From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8782 invoked from network); 7 Jul 2004 14:53:43 -0000 Received: from odin.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.85) by ns1.primenet.com.au with SMTP; 7 Jul 2004 14:53:43 -0000 Received: (qmail 24298 invoked from network); 7 Jul 2004 14:53:29 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 7 Jul 2004 14:53:29 -0000 Received: (qmail 3688 invoked by alias); 7 Jul 2004 14:53:22 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 20141 Received: (qmail 3679 invoked from network); 7 Jul 2004 14:53:22 -0000 Received: from odin.dotsrc.org (HELO a.mx.sunsite.dk) (qmailr@130.225.247.85) by sunsite.dk with SMTP; 7 Jul 2004 14:53:22 -0000 Received: (qmail 24063 invoked from network); 7 Jul 2004 14:53:24 -0000 Received: from lhuumrelay3.lnd.ops.eu.uu.net (62.189.58.19) by a.mx.sunsite.dk with SMTP; 7 Jul 2004 14:53:10 -0000 Received: from MAILSWEEPER01.csr.com (mailhost1.csr.com [62.189.183.235]) by lhuumrelay3.lnd.ops.eu.uu.net (8.11.0/8.11.0) with ESMTP id i67Eqfv00617 for ; Wed, 7 Jul 2004 14:52:41 GMT Received: from EXCHANGE02.csr.com (unverified [192.168.137.45]) by MAILSWEEPER01.csr.com (Content Technologies SMTPRS 4.3.12) with ESMTP id for ; Wed, 7 Jul 2004 15:52:00 +0100 Received: from news01.csr.com ([192.168.143.38]) by EXCHANGE02.csr.com with Microsoft SMTPSVC(5.0.2195.6713); Wed, 7 Jul 2004 15:53:39 +0100 Received: from news01.csr.com (localhost.localdomain [127.0.0.1]) by news01.csr.com (8.12.11/8.12.11) with ESMTP id i67Eqe3m004328 for ; Wed, 7 Jul 2004 15:52:40 +0100 Received: from csr.com (pws@localhost) by news01.csr.com (8.12.11/8.12.11/Submit) with ESMTP id i67EqdAI004325 for ; Wed, 7 Jul 2004 15:52:40 +0100 Message-Id: <200407071452.i67EqdAI004325@news01.csr.com> X-Authentication-Warning: news01.csr.com: pws owned process doing -bs To: Zsh-Workers Subject: PATCH: crashing bug here with LANG=C printf "%1.1f\n" 23.2 In-reply-to: "Matthias Kopfermann"'s message of "Wed, 07 Jul 2004 02:46:45 +0200." <20040707004644.GA9512@finlandia.infodrom.north.de> Date: Wed, 07 Jul 2004 15:52:39 +0100 From: Peter Stephenson X-OriginalArrivalTime: 07 Jul 2004 14:53:39.0219 (UTC) FILETIME=[30268630:01C46432] X-Spam-Checker-Version: SpamAssassin 2.63 on a.mx.sunsite.dk X-Spam-Level: X-Spam-Status: No, hits=0.0 required=6.0 tests=BAYES_50 autolearn=no version=2.63 X-Spam-Hits: 0.0 Matthias Kopfermann wrote: > for ((i=1;i<100;i+=.01)) ; { LANG=C printf "%1.1f\n" $i ; } > gives me a segfault instantly here. > the same can happen when just doing LANG='C' printf "%1.1f\n" 23.2 > > with message: BUG: attempt to free more than allocated. While fixing this, I improved the interface to the environment add/removal functions. However, exactly one of the lines changed below makes any difference to the bug whatsoever. As I don't see why anyone else should be less frustrated than I've been for the last couple of hours, I'm not telling you which (unless you give up and ask). Have fun :-). (Assuming this does fix it, of course. valgrind seems to think it does.) Index: Src/builtin.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v retrieving revision 1.121 diff -u -r1.121 builtin.c --- Src/builtin.c 2 Jun 2004 22:14:25 -0000 1.121 +++ Src/builtin.c 7 Jul 2004 14:47:22 -0000 @@ -750,15 +750,11 @@ setsparam("OLDPWD", ztrdup(oldpwd)); pm = (Param) paramtab->getnode(paramtab, "PWD"); - if (!(pm->flags & PM_EXPORTED)) { - pm->flags |= PM_EXPORTED; - pm->env = addenv("PWD", pwd, pm->flags); - } + if (!(pm->flags & PM_EXPORTED)) + addenv(pm, pwd); pm = (Param) paramtab->getnode(paramtab, "OLDPWD"); - if (!(pm->flags & PM_EXPORTED)) { - pm->flags |= PM_EXPORTED; - pm->env = addenv("OLDPWD", oldpwd, pm->flags); - } + if (!(pm->flags & PM_EXPORTED)) + addenv(pm, oldpwd); } /* set if we are resolving links to their true paths */ @@ -1883,11 +1879,9 @@ if (!(pm->flags & (PM_ARRAY|PM_HASHED))) { if (pm->flags & PM_EXPORTED) { if (!(pm->flags & PM_UNSET) && !pm->env && !value) - pm->env = addenv(pname, getsparam(pname), pm->flags); - } else if (pm->env && !(pm->flags & PM_HASHELEM)) { - delenv(pm->env); - pm->env = NULL; - } + addenv(pm, getsparam(pname)); + } else if (pm->env && !(pm->flags & PM_HASHELEM)) + delenv(pm); if (value && !(pm = setsparam(pname, ztrdup(value)))) return NULL; } else if (value) { @@ -1938,7 +1932,7 @@ * Maybe it would be easier to create a new struct but copy * the get/set methods. */ - tpm = (Param) zalloc(sizeof *tpm); + tpm = (Param) zshcalloc(sizeof *tpm); tpm->nam = pm->nam; if (pm->ename && @@ -1962,10 +1956,9 @@ tpm->old = pm->old; tpm->level = pm->level; tpm->ct = pm->ct; - if (pm->env) { - delenv(pm->env); - } - tpm->env = pm->env = NULL; + if (pm->env) + delenv(pm); + tpm->env = NULL; pm->old = tpm; /* Index: Src/exec.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/exec.c,v retrieving revision 1.66 diff -u -r1.66 exec.c --- Src/exec.c 28 Jun 2004 15:38:13 -0000 1.66 +++ Src/exec.c 7 Jul 2004 14:47:24 -0000 @@ -483,7 +483,7 @@ * that as argv[0] for this external command */ if (unset(RESTRICTED) && (z = zgetenv("ARGV0"))) { setdata(firstnode(args), (void *) ztrdup(z)); - delenv(z - 6); + delenvvalue(z - 6); } else if (dash) { /* Else if the pre-command `-' was given, we add `-' * * to the front of argv[0] for this command. */ @@ -2520,15 +2520,13 @@ while (wc_code(ac = *pc) == WC_ASSIGN) { s = ecrawstr(state->prog, pc + 1, NULL); if ((pm = (Param) paramtab->getnode(paramtab, s))) { - if (pm->env) { - delenv(pm->env); - pm->env = NULL; - } + if (pm->env) + delenv(pm); if (!(pm->flags & PM_SPECIAL)) { paramtab->removenode(paramtab, s); } else if (!(pm->flags & PM_READONLY) && (unset(RESTRICTED) || !(pm->flags & PM_RESTRICTED))) { - Param tpm = (Param) zhalloc(sizeof *tpm); + Param tpm = (Param) hcalloc(sizeof *tpm); tpm->nam = pm->nam; copyparam(tpm, pm, 1); pm = tpm; @@ -2589,10 +2587,11 @@ tpm->sets.hfn(tpm, pm->u.hash); break; } + pm = tpm; } else paramtab->addnode(paramtab, pm->nam, pm); if ((pm->flags & PM_EXPORTED) && ((s = getsparam(pm->nam)))) - pm->env = addenv(pm->nam, s, pm->flags); + addenv(pm, s); } } } Index: Src/params.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/params.c,v retrieving revision 1.86 diff -u -r1.86 params.c --- Src/params.c 22 Jun 2004 13:10:02 -0000 1.86 +++ Src/params.c 7 Jul 2004 14:47:25 -0000 @@ -587,20 +587,15 @@ opts[ALLEXPORT] = oae; pm = (Param) paramtab->getnode(paramtab, "HOME"); - if (!(pm->flags & PM_EXPORTED)) { - pm->flags |= PM_EXPORTED; - pm->env = addenv("HOME", home, pm->flags); - } + if (!(pm->flags & PM_EXPORTED)) + addenv(pm, home); pm = (Param) paramtab->getnode(paramtab, "LOGNAME"); - if (!(pm->flags & PM_EXPORTED)) { - pm->flags |= PM_EXPORTED; - pm->env = addenv("LOGNAME", pm->u.str, pm->flags); - } - pm = (Param) paramtab->getnode(paramtab, "SHLVL"); if (!(pm->flags & PM_EXPORTED)) - pm->flags |= PM_EXPORTED; + addenv(pm, pm->u.str); + pm = (Param) paramtab->getnode(paramtab, "SHLVL"); sprintf(buf, "%d", (int)++shlvl); - pm->env = addenv("SHLVL", buf, pm->flags); + if (!(pm->flags & PM_EXPORTED)) + addenv(pm, buf); /* Add the standard non-special parameters */ set_pwd_env(); @@ -712,10 +707,8 @@ * needed to avoid freeing oldpm, but we do take it * out of the environment when it's hidden. */ - if (oldpm->env) { - delenv(oldpm->env); - oldpm->env = NULL; - } + if (oldpm->env) + delenv(oldpm); paramtab->removenode(paramtab, name); } paramtab->addnode(paramtab, ztrdup(name), pm); @@ -1585,8 +1578,7 @@ else val = pm->gets.cfn(pm); - pm->flags |= PM_EXPORTED; - pm->env = addenv(pm->nam, val, pm->flags); + addenv(pm, val); } /**/ @@ -2240,10 +2232,8 @@ return 1; } pm->unsetfn(pm, exp); - if ((pm->flags & PM_EXPORTED) && pm->env) { - delenv(pm->env); - pm->env = NULL; - } + if (pm->env) + delenv(pm); /* remove it under its alternate name if necessary */ if (pm->ename && !altflag) { @@ -3296,7 +3286,7 @@ else joinchar = ':'; - pm->env = addenv(s, t ? zjoin(t, joinchar, 1) : "", pm->flags); + addenv(pm, t ? zjoin(t, joinchar, 1) : ""); } @@ -3385,8 +3375,8 @@ } /**/ -char * -addenv(char *name, char *value, int flags) +void +addenv(Param pm, char *value) { char *oldenv = 0, *newenv = 0, *env = 0; int pos; @@ -3394,13 +3384,14 @@ /* First check if there is already an environment * * variable matching string `name'. If not, and * * we are not requested to add new, return */ - if (findenv(name, &pos)) + if (findenv(pm->nam, &pos)) oldenv = environ[pos]; - newenv = mkenvstr(name, value, flags); + newenv = mkenvstr(pm->nam, value, pm->flags); if (zputenv(newenv)) { zsfree(newenv); - return NULL; + pm->env = NULL; + return; } /* * Under Cygwin we must use putenv() to maintain consistency. @@ -3408,16 +3399,19 @@ * silently reuse existing environment string. This tries to * check for both cases */ - if (findenv(name, &pos)) { + if (findenv(pm->nam, &pos)) { env = environ[pos]; if (env != oldenv) zsfree(oldenv); if (env != newenv) zsfree(newenv); - return env; + pm->flags |= PM_EXPORTED; + pm->env = env; + return; } - return NULL; /* Cannot happen */ + DPUTS(1, "addenv should never reach the end"); + pm->env = NULL; } @@ -3448,12 +3442,9 @@ * string. */ -/* Delete a pointer from the list of pointers to environment * - * variables by shifting all the other pointers up one slot. */ - /**/ void -delenv(char *x) +delenvvalue(char *x) { char **ep; @@ -3467,6 +3458,22 @@ zsfree(x); } +/* Delete a pointer from the list of pointers to environment * + * variables by shifting all the other pointers up one slot. */ + +/**/ +void +delenv(Param pm) +{ + delenvvalue(pm->env); + pm->env = NULL; + /* + * Note we don't remove PM_EXPORT from the flags. This + * may be asking for trouble but we need to know later + * if we restore this parameter to its old value. + */ +} + /**/ mod_export void convbase(char *s, zlong v, int base) @@ -3625,10 +3632,8 @@ pm->flags = (tpm->flags & ~PM_NORESTORE); pm->level = tpm->level; pm->ct = tpm->ct; - if (pm->env) { - delenv(pm->env); - } - pm->env = NULL; + if (pm->env) + delenv(pm); if (!(tpm->flags & PM_NORESTORE)) switch (PM_TYPE(pm->flags)) { -- Peter Stephenson Software Engineer CSR Ltd., Science Park, Milton Road, Cambridge, CB4 0WH, UK Tel: +44 (0)1223 692070 ********************************************************************** This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error please notify the system manager. This footnote also confirms that this email message has been swept by MIMEsweeper for the presence of computer viruses. www.mimesweeper.com **********************************************************************