From owner-freebsd-bugs Wed Jul 19 17:34:27 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from midten.fast.no (midten.fast.no [213.188.8.11]) by hub.freebsd.org (Postfix) with ESMTP id 14A0E37B631; Wed, 19 Jul 2000 17:34:08 -0700 (PDT) (envelope-from tegge@fast.no) Received: from fast.no (IDENT:tegge@midten.fast.no [213.188.8.11]) by midten.fast.no (8.9.3/8.9.3) with ESMTP id CAA37265; Thu, 20 Jul 2000 02:34:06 +0200 (CEST) Message-Id: <200007200034.CAA37265@midten.fast.no> To: sheldonh@FreeBSD.ORG Cc: pfeifer@dbai.tuwien.ac.at, freebsd-bugs@FreeBSD.ORG, cracauer@FreeBSD.ORG Subject: Re: bin/19983: sh dumps core reproducibly From: Tor.Egge@fast.no In-Reply-To: Your message of "Tue, 18 Jul 2000 09:40:48 -0700 (PDT)" References: <200007181640.JAA81033@freefall.freebsd.org> X-Mailer: Mew version 1.70 on Emacs 19.34.1 Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Date: Thu, 20 Jul 2000 02:34:05 +0200 Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org growstackblock() sometimes relocates a stack_block considered empty without properly relocating stack marks referencing that block. The first call to popstackmark() with the unrelocated stack mark as argument then causes sh to abort. Relocating the relevant stack marks seems to solve this problem. The patch changes the semantics of popstackmark() somewhat. It can only be called once after a call to setstackmark(), thus cmdloop() in main.c needs an extra call to setstackmark(). - Tor Egge Index: bin/sh/main.c =================================================================== RCS file: /home/ncvs/src/bin/sh/main.c,v retrieving revision 1.19 diff -u -r1.19 main.c --- bin/sh/main.c 2000/04/14 06:03:39 1.19 +++ bin/sh/main.c 2000/07/20 00:26:56 @@ -253,12 +253,13 @@ evaltree(n, 0); } popstackmark(&smark); + setstackmark(&smark); if (evalskip == SKIPFILE) { evalskip = 0; break; } } - popstackmark(&smark); /* unnecessary */ + popstackmark(&smark); } Index: bin/sh/memalloc.c =================================================================== RCS file: /home/ncvs/src/bin/sh/memalloc.c,v retrieving revision 1.15 diff -u -r1.15 memalloc.c --- bin/sh/memalloc.c 1999/08/27 23:15:16 1.15 +++ bin/sh/memalloc.c 2000/07/20 00:09:03 @@ -118,6 +118,7 @@ struct stack_block stackbase; struct stack_block *stackp = &stackbase; +struct stackmark *markp; char *stacknxt = stackbase.space; int stacknleft = MINSIZE; int sstrnleft; @@ -176,6 +177,8 @@ mark->stackp = stackp; mark->stacknxt = stacknxt; mark->stacknleft = stacknleft; + mark->marknext = markp; + markp = mark; } @@ -186,6 +189,7 @@ struct stack_block *sp; INTOFF; + markp = mark->marknext; while (stackp != mark->stackp) { sp = stackp; stackp = sp->prev; @@ -215,6 +219,7 @@ char *oldspace; int oldlen; struct stack_block *sp; + struct stack_block *oldstackp; newlen = ALIGN(stacknleft * 2 + 100); oldspace = stacknxt; @@ -222,6 +227,7 @@ if (stacknxt == stackp->space && stackp != &stackbase) { INTOFF; + oldstackp = stackp; sp = stackp; stackp = sp->prev; sp = ckrealloc((pointer)sp, sizeof(struct stack_block) - @@ -230,6 +236,19 @@ stackp = sp; stacknxt = sp->space; stacknleft = newlen; + { + /* Stack marks pointing to the start of the old block + * must be relocated to point to the new block + */ + struct stackmark *xmark; + xmark = markp; + while (xmark != NULL && xmark->stackp == oldstackp) { + xmark->stackp = stackp; + xmark->stacknxt = stacknxt; + xmark->stacknleft = stacknleft; + xmark = xmark->marknext; + } + } INTON; } else { p = stalloc(newlen); Index: bin/sh/memalloc.h =================================================================== RCS file: /home/ncvs/src/bin/sh/memalloc.h,v retrieving revision 1.6 diff -u -r1.6 memalloc.h --- bin/sh/memalloc.h 1999/08/27 23:15:17 1.6 +++ bin/sh/memalloc.h 2000/07/20 00:08:33 @@ -41,6 +41,7 @@ struct stack_block *stackp; char *stacknxt; int stacknleft; + struct stackmark *marknext; }; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message