From patchwork Fri Dec 14 05:44:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herbert Xu X-Patchwork-Id: 10730561 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CA48C13B5 for ; Fri, 14 Dec 2018 05:44:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BA6732CEF6 for ; Fri, 14 Dec 2018 05:44:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AF20B2D1B3; Fri, 14 Dec 2018 05:44:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 18C192CEF6 for ; Fri, 14 Dec 2018 05:44:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726437AbeLNFoT (ORCPT ); Fri, 14 Dec 2018 00:44:19 -0500 Received: from orcrist.hmeau.com ([104.223.48.154]:52316 "EHLO deadmen.hmeau.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727127AbeLNFoS (ORCPT ); Fri, 14 Dec 2018 00:44:18 -0500 Received: from gondobar.mordor.me.apana.org.au ([192.168.128.4] helo=gondobar) by deadmen.hmeau.com with esmtps (Exim 4.89 #2 (Debian)) id 1gXgGn-00085s-6F; Fri, 14 Dec 2018 13:44:17 +0800 Received: from herbert by gondobar with local (Exim 4.89) (envelope-from ) id 1gXgGk-0000pk-Ui; Fri, 14 Dec 2018 13:44:14 +0800 Date: Fri, 14 Dec 2018 13:44:14 +0800 From: Herbert Xu To: Ron Yorston Cc: dash@vger.kernel.org Subject: [v2 PATCH] eval: avoid leaking memory associated with redirections Message-ID: <20181214054414.4aglxca57ethwtee@gondor.apana.org.au> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <5bf6aabc.5IrNAw91xx5SQEm6%rmy@frippery.org> X-Newsgroups: apana.lists.os.linux.dash Organization: Core User-Agent: NeoMutt/20170113 (1.7.2) Sender: dash-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dash@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Ron Yorston wrote: > The following constructs result in ever-increasing memory usage: > > while true; do { true; } while true; do ( true; ) > For comparison, bash displays static memory usage in both cases. > > This issue was reported for BusyBox ash which is derived from dash: > > https://bugs.busybox.net/show_bug.cgi?id=7748 > > Signed-off-by: Ron Yorston Thanks for the patch. I thinkg we should just move the stack mark into evaltree for everybody, like this: ---8<--- The following constructs result in ever-increasing memory usage: while true; do { true; } I have simplified evaltree so that it simply sets the stack mark unconditionally. This allows us to remove the stack marks in the functions called by evaltree. Signed-off-by: Herbert Xu diff --git a/src/eval.c b/src/eval.c index 546ee1b..715aa8b 100644 --- a/src/eval.c +++ b/src/eval.c @@ -200,8 +200,12 @@ evaltree(union node *n, int flags) { int checkexit = 0; int (*evalfn)(union node *, int); + struct stackmark smark; unsigned isor; int status = 0; + + setstackmark(&smark); + if (n == NULL) { TRACE(("evaltree(NULL) called\n")); goto out; @@ -317,6 +321,8 @@ exexit: exraise(EXEXIT); } + popstackmark(&smark); + return exitstatus; } @@ -396,14 +402,12 @@ evalfor(union node *n, int flags) struct arglist arglist; union node *argp; struct strlist *sp; - struct stackmark smark; int status; errlinno = lineno = n->nfor.linno; if (funcline) lineno -= funcline - 1; - setstackmark(&smark); arglist.lastp = &arglist.list; for (argp = n->nfor.args ; argp ; argp = argp->narg.next) { expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); @@ -420,7 +424,6 @@ evalfor(union node *n, int flags) break; } loopnest--; - popstackmark(&smark); return status; } @@ -433,14 +436,12 @@ evalcase(union node *n, int flags) union node *cp; union node *patp; struct arglist arglist; - struct stackmark smark; int status = 0; errlinno = lineno = n->ncase.linno; if (funcline) lineno -= funcline - 1; - setstackmark(&smark); arglist.lastp = &arglist.list; expandarg(n->ncase.expr, &arglist, EXP_TILDE); for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) { @@ -459,8 +460,6 @@ evalcase(union node *n, int flags) } } out: - popstackmark(&smark); - return status; } @@ -717,7 +716,6 @@ evalcommand(union node *cmd, int flags) struct localvar_list *localvar_stop; struct parsefile *file_stop; struct redirtab *redir_stop; - struct stackmark smark; union node *argp; struct arglist arglist; struct arglist varlist; @@ -746,7 +744,6 @@ evalcommand(union node *cmd, int flags) /* First expand the arguments. */ TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); - setstackmark(&smark); file_stop = parsefile; back_exitstatus = 0; @@ -925,7 +922,6 @@ out: * However I implemented that within libedit itself. */ setvar("_", lastarg, 0); - popstackmark(&smark); return status; }