From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6776 invoked by alias); 20 Mar 2016 17:18:49 -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: 38191 Received: (qmail 6220 invoked from network); 20 Mar 2016 17:18:46 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=brasslantern-com.20150623.gappssmtp.com; s=20150623; h=from:message-id:date:in-reply-to:comments:references:to:subject :mime-version; bh=sIVDigVARV0WGLet5xPXceMlK2NCrDaA7SnJ+0l3I7Q=; b=1nuQRLpmyaXAX29vnRjwDHZWlR9E4ZYpEjevBHGFvlX2EEHquH5Fg4vrJOZwxHgV8e JeI7VHeZ2Cs4HQJBwcgMh7Kxn/4JavarErlFJPYLKVykWURbWZM6XCBQIAldQ54X8gSx 44tWJwW0a3DT5qJioJCV9TGUYkNquefqyu8Pk22Api/wejKUnCoJBB9tzowKlM42gEWt ngWOs5z0/ZKtkcb3GMaTw131KbXGzky/zsHHe1cl+fuuz0J4RJ1+LBdyzEbUTA1dNiI/ u8aH0OjDWqgUz+VVNBy8n7LuMiOeFesiMq9To9A2RPZXs3PNudKjggwG2DRzlIMtoXrB U3WQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:message-id:date:in-reply-to:comments :references:to:subject:mime-version; bh=sIVDigVARV0WGLet5xPXceMlK2NCrDaA7SnJ+0l3I7Q=; b=H7eDckUVc12HshhqKoPKlPfvOCGsR4DiVUAE6k1q0Y7fS5KKmykktQBhNdJdR0CfBK H+s2G8w0a4Ni2z+1Ws5bT+h2eZvEvJc/CM34Tn4mmjW59voibCDeqZ6Myvqqz3Zdk7nO B2r/0THgA3RaWg+SsAuJlrXOki8BGGEvjSMdab9fQ8cBeoEY64qekb/ihfIMQ9qj9faB jgHc/xggpmAMxyrPhmAJ2URmBBibnqe4fFzTHOW7QOZlKtUz0Z2lkTrNfX95nWnChN8n oZ7xTwr1cK4eVTcICO6pEdbaiPDl8yutRyp6sIC7YqqJMbG0VYN86H0oQpMUbR1yrtI/ ieUQ== X-Gm-Message-State: AD7BkJJG+JRWwOPQ8ydFn+QEvvdpgLosQJMA5LgPC5r+/8/5TveEawOIDSfv/+b1+1lhRQ== X-Received: by 10.98.8.74 with SMTP id c71mr39621511pfd.155.1458494322315; Sun, 20 Mar 2016 10:18:42 -0700 (PDT) From: Bart Schaefer Message-Id: <160320101910.ZM8306@torch.brasslantern.com> Date: Sun, 20 Mar 2016 10:19:10 -0700 In-Reply-To: Comments: In reply to comic fans "access already freed memory when resize window" (Mar 20, 9:57pm) References: X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-workers@zsh.org Subject: Re: access already freed memory when resize window MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii This appears to be happening because the PROMPTSUBST option is set and one of the prompt variables contains a $(...) command substitution. When the $(...) is executed during prompt expansion, zsh waits for the command to exit, which allows a second SIGWINCH to be handled, which in turn redisplays the prompt again before it has finished expanding. I can trivially reproduce from zsh -f with: torch% setopt promptsubst torch% PS1='$(<<<$SECONDS) '"$PS1" and then resize the window. The reexpandprompt() routine has a guard against re-entering this way, but that doesn't help because the global pointer has been freed and even if reexpandprompt() is skipped other parts of the ZLE redraw may access it. It doesn't even help to queue signals, because waiting for the command substitution to finish must temporarily unqueue them. This is especially nasty because lpromptbuf has to be correctly set in order for rpromptbuf to be correctly computed, so if the user is wildly dragging the window border around there is no instant at which we are guaranteed to be able to leave the two of them in proper sync with both the window size and each other -- unless we do something unpleasant like attempting to sleep with SIGWINCH blocked until the user has finished goofing around. The following appears to be the next best thing, but I think it could still leave us one SIGWINCH short of a full paint job. diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 6e2bfde..104e5d6 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -1856,6 +1856,7 @@ void reexpandprompt(void) { static int reexpanding; + static int looping; if (!reexpanding++) { /* @@ -1866,15 +1867,33 @@ reexpandprompt(void) int local_lastval = lastval; lastval = pre_zle_status; - free(lpromptbuf); - lpromptbuf = promptexpand(raw_lp ? *raw_lp : NULL, 1, NULL, NULL, - &pmpt_attr); - rpmpt_attr = pmpt_attr; - free(rpromptbuf); - rpromptbuf = promptexpand(raw_rp ? *raw_rp : NULL, 1, NULL, NULL, - &rpmpt_attr); + do { + /* A new SIGWINCH may arrive while in promptexpand(), causing + * looping to increment. This only happens when a command + * substitution is used in a PROMPT_SUBST prompt, but + * nevertheless keep trying until we see no more changes. + */ + char *new_lprompt, *new_rprompt; + looping = reexpanding; + + new_lprompt = promptexpand(raw_lp ? *raw_lp : NULL, 1, NULL, NULL, + &pmpt_attr); + free(lpromptbuf); + lpromptbuf = new_lprompt; + + if (looping != reexpanding) + continue; + + rpmpt_attr = pmpt_attr; + new_rprompt = promptexpand(raw_rp ? *raw_rp : NULL, 1, NULL, NULL, + &rpmpt_attr); + free(rpromptbuf); + rpromptbuf = new_rprompt; + } while (looping != reexpanding); + lastval = local_lastval; - } + } else + looping = reexpanding; reexpanding--; }