From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8956 invoked by alias); 7 Dec 2015 13:55:42 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 37337 Received: (qmail 23910 invoked from network); 7 Dec 2015 13:55:39 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.0 X-AuditID: cbfec7f4-f79026d00000418a-10-56658fd79898 Date: Mon, 07 Dec 2015 13:55:32 +0000 From: Peter Stephenson To: zsh-workers@zsh.org Subject: Re: Segfault with zsh 5.2 Message-id: <20151207135532.1a285c15@pwslap01u.europe.root.pri> In-reply-to: <87h9jujttm.fsf@gmail.com> References: <87h9jujttm.fsf@gmail.com> Organization: Samsung Cambridge Solution Centre X-Mailer: Claws Mail 3.7.9 (GTK+ 2.22.0; i386-redhat-linux-gnu) MIME-version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrALMWRmVeSWpSXmKPExsVy+t/xy7rX+1PDDH416lscbH7I5MDoserg B6YAxigum5TUnMyy1CJ9uwSujEUb/rEXfJWq+HbgBXsD4zqRLkZODgkBE4neCU/YIGwxiQv3 1gPZXBxCAksZJT5d7WAGSQgJzGCS2LtPCyJxmlFiweHH7BDOGUaJ3tmfWECqWARUJU7cOcAE YrMJGEpM3TSbEcQWERCXOLv2PFiNsICSxMdZk9hBbF4Be4kZO/+D1XAKqEtcPnGSFWKbmsSq q1vB5vAL6Etc/fuJCeI8e4mZV84wQvQKSvyYfA9sJrOAlsTmbU2sELa8xOY1b6GuVpe4cXc3 +wRG4VlIWmYhaZmFpGUBI/MqRtHU0uSC4qT0XEO94sTc4tK8dL3k/NxNjJBw/rKDcfExq0OM AhyMSjy8FukpYUKsiWXFlbmHGCU4mJVEeGUzU8OEeFMSK6tSi/Lji0pzUosPMUpzsCiJ887d 9T5ESCA9sSQ1OzW1ILUIJsvEwSnVwOief3/SUuHYQ6K/PthcSNeR4n3Cd0+Vy9Egyuzb4QrR k9z6Ldpbcw8Enmvnf/jugerUfu/t+60rSy+tkeNsXVJ1zWLxFXun+EaD9fNc49VedS5Umh2d OS9lztW2eRGMOw7J3pB0LP4Z8KTgdxVH9/XCePablya6nRdn5O2Vc7voEsLe0nefRYmlOCPR UIu5qDgRANxX7z1jAgAA On Mon, 7 Dec 2015 14:01:57 +0100 Christian Neukirchen wrote: > zle-line-init() { > BUFFER="$ICMD" > zle accept-line > zle -D zle-line-init > } I couldn't get your crash to happen easily, and the crash actually happened in a normal alloc high up in the execution tree so doesn't give us much direct help apart from pointing at memory management. (The call was protected by signal queueing, by the way.) However, there's definitely something very dodgy in memory management for the code above. It's always been this way, so I think the fact it's just shown up is an accident. I couldn't get valgrind to show it up, for some reason, but the evidence from gdb is incontrovertible. Does the following help? Unless I've screwed up it needs committing anyway. (I hope the widget flags aren't so heavily overloaded now as to make this unsafe.) pws diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h index 2d672de..e9b1428 100644 --- a/Src/Zle/zle.h +++ b/Src/Zle/zle.h @@ -213,6 +213,8 @@ struct widget { #define ZLE_KEEPSUFFIX (1<<9) /* DON'T remove added suffix */ #define ZLE_NOTCOMMAND (1<<10) /* widget should not alter lastcmd */ #define ZLE_ISCOMP (1<<11) /* usable for new style completion */ +#define WIDGET_INUSE (1<<12) /* widget is in use */ +#define WIDGET_FREE (1<<13) /* request to free when no longer in use */ /* thingies */ diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 38427e8..1f0c07d 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -1344,6 +1344,8 @@ execzlefunc(Thingy func, char **args, int set_bindk) eofsent = 1; ret = 1; } else { + int inuse = wflags & WIDGET_INUSE; + w->flags |= WIDGET_INUSE; if(!(wflags & ZLE_KEEPSUFFIX)) removesuffix(); if(!(wflags & ZLE_MENUCMP)) { @@ -1367,6 +1369,12 @@ execzlefunc(Thingy func, char **args, int set_bindk) ret = w->u.fn(args); unqueue_signals(); } + if (!inuse) { + if (w->flags & WIDGET_FREE) + freewidget(w); + else + w->flags &= ~WIDGET_INUSE; + } if (!(wflags & ZLE_NOTCOMMAND)) lastcmd = wflags; } @@ -1387,6 +1395,8 @@ execzlefunc(Thingy func, char **args, int set_bindk) int osc = sfcontext, osi = movefd(0); int oxt = isset(XTRACE); LinkList largs = NULL; + int inuse = w->flags & WIDGET_INUSE; + w->flags |= WIDGET_INUSE; if (*args) { largs = newlinklist(); @@ -1402,8 +1412,15 @@ execzlefunc(Thingy func, char **args, int set_bindk) opts[XTRACE] = oxt; sfcontext = osc; endparamscope(); - lastcmd = w->flags; - w->flags = 0; + lastcmd = w->flags & ~(WIDGET_INUSE|WIDGET_FREE); + if (inuse) { + w->flags &= WIDGET_INUSE|WIDGET_FREE; + } else { + if (w->flags & WIDGET_FREE) + freewidget(w); + else + w->flags = 0; + } r = 1; redup(osi, 0); } diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c index 271fd8e..21495b6 100644 --- a/Src/Zle/zle_thingy.c +++ b/Src/Zle/zle_thingy.c @@ -253,9 +253,14 @@ unbindwidget(Thingy t, int override) /* Free a widget. */ /**/ -static void +void freewidget(Widget w) { + if (w->flags & WIDGET_INUSE) { + w->flags |= WIDGET_FREE; + return; + } + if (w->flags & WIDGET_NCOMP) { zsfree(w->u.comp.wid); zsfree(w->u.comp.func);