Subject: bug#47067: 28.0.50; [feature/native-comp] Crash while scrolling through dispnew.c

From: Pip Cet <[email-masked]>
Date: Sat, 13 Mar 2021 17:10:08 +0000

On Sat, Mar 13, 2021 at 4:53 PM Eli Zaretskii <[email-masked]> wrote:
> > From: Pip Cet <[email-masked]>
> > Date: Sat, 13 Mar 2021 16:32:50 +0000
> > Cc: Andrea Corallo <[email-masked]>, [email-masked]
> >
> > > > > > So EDI is bunk at this point. Can you go back a bit further to where
> > > > > > it's initialized?
> > > > >
> > > > > Sorry, I don't understand: I gave you the disassembly of 512 bytes
> > > > > before, isn't that enough to see where EDI is assigned the value?  Or
> > > > > what do you mean by "go back"?
> > > >
> > > > It's not enough, no. we're looking for an insn of the form mov XXX,
> > > > %edi or lea XXX, %edi, or anything like that.
> > >
> > > I went back 4KB, and the only two instructions that write into EDI are
> >
> > It's a long function, that might not have been enough.
>
> But since I found those two, everything before that is irrelevant,
> right?

Assuming all code paths hit these insns, yes.

> > I just checked the only "mingw"-like sources I could find, and they
> > don't appear to use the frame pointer argument properly...
>
> Why is this suddenly relevant when native compilation is involved?

Native-compiled code assumes, on Windows, that you can call setjmp
through a function pointer. If the implementation of setjmp is such
that you can't, we shouldn't do that. Portable code will never call
setjmp through a function pointer.

Since mingw (at least the version I could find) declares setjmp with
the "returns_twice" attribute, I'm assuming their implementation is
not such that you can call it through a function pointer.

> > > > Is it possible that you're on Windows, but unlike other Windows
> > > > setjmps, it's unsafe to call your setjmp through a function pointer?
> > >
> > > How do I tell?
> >
> > Well, you could just apply this untested patch, fix any obvious
> > compile errors I might not have spotted, and try to reproduce it. I'm
> > not currently on a Windows (or x86) machine, so it's a bit hard for me
> > to test...
>
> I'd like this investigation to be less of a blind search, sorry.  can
> you tell what to check or look at to see if this is relevant?
>
> And how is setjmp related to the code which causes segfault?  I see no
> call to setjmp in the disassembly.

That might be because it's called through a function pointer?

If you look at the Lisp code, the thing it does just before the code
dies is to exit from a long-ish (catch ...) form. Which involves
setjmp, unless the byte compiler is smart enough to optimize it away.

> > > Note how arguments to Funcall's are the same, whereas arguments to
> > > funcall_lambda's aren't.  Even the garbage in the 2 arguments to
> > > wrong_type_argument are identical.
> >
> > Which non-stack addresses are invariant in that backtrace?
>
> Not sure how stack-based vs non-stack based is important here.

If non-stack addresses vary between runs and stack addresses don't, I
don't see any evidence we're looking at corruption here.