Subject: Re: bug#33034: `unwind-protect' cleanup form is not executed if body dies in stack overflow

From: Paul Pogonyshev <[email-masked]>
Date: Sat, 13 Oct 2018 16:02:09 +0200

(defvar global-test nil)
(unwind-protect
    (let ((global-test t))
      (message "inside, global-test = %s" global-test)
      (error "test"))
  (message "in cleanup, global-test = %s" global-test))

This gives the following output (outside the error):
    inside, global-test = t
    in cleanup, global-test = nil

So, global variables are unwound, but stack is not? This doesn't make
much sense to me.

Besides, what is the purpose of current implementation? Current state
has at least one disadvantage, highlighted by this bug: cleanup forms
after a stack overflow error always fail to work, because stack is
still full. Are there any advantages? I feel like it is more of
coincidence than deliberate decision. Would fixing it break backwards
compatibility?
On Sat, 13 Oct 2018 at 14:35, Eli Zaretskii <[email-masked]> wrote:
>
> > From: Paul Pogonyshev <[email-masked]>
> > Date: Sat, 13 Oct 2018 13:38:11 +0200
> > Cc: [email-masked]
> >
> > OK, but why does it hit the limit? Logically, by the time cleanup form
> > is called, all the (overflow) stack frames should be removed and the
> > cleanup form should see practically empty stack. It shouldn't be much
> > different from calling cleanup without overflowing the stack to begin
> > with.
>
> I don't think your expectation, that the stack should be unwound
> before the cleanup runs, is correct.  The implementation calls the
> cleanup forms before it jumps to top-level, and I see nothing in the
> documentation to promise anything different.