Subject: Re: access already freed memory when resize window
From: Bart Schaefer <[email-masked]>
To: [email-masked]
Date: Mon, 21 Mar 2016 08:10:31 -0700
List-Id: Zsh Workers List <zsh-workers.zsh.org>

On Mar 21, 10:43am, Peter Stephenson wrote:
} Subject: Re: access already freed memory when resize window
}
} On Sun, 20 Mar 2016 10:19:10 -0700
} Bart Schaefer <[email-masked]> wrote:
} > It doesn't even help to queue signals, because waiting for the command
} > substitution to finish must temporarily unqueue them.
} 
} Right, but shouldn't there at least be some attempt to tame the points
} at which recursion can happen?  Or is that already happening, and all
} the effects we're seeing are out at the top level after the signal
} handler has returned?

Generically, the problem is that reexpandprompt() was doing

	free(GlobalPointer);
	GlobalPointer = maybe_reference_GlobalPointer();

The fact that the reference is from a signal handler is an instantiation
of "maybe".  So at the very least we have to change the order of the
function call and the free.

An added complication is that we have two interdependent global pointers
that were both being treated that way.

To "tame the recursion" we could do something like this:

 #ifdef SIGWINCH
     case SIGWINCH:
+	winch_block();
         adjustwinsize(1);  /* check window size and adjust */
 	(void) handletrap(SIGWINCH);
+	winch_unblock();
         break;
 #endif
 
But then we might stop adjusting our idea of the window size before the
user stops resizing the window.  (Also due to the way we manage signal
queuing we don't know the current state of winch_block() at that point,
so it might not be correct to block/unblock.  The whole winch-handling
scheme would have to be revised to be more like queue_signals().)