Subject: Re: bug#18438: 24.4.50; assertion failed in bidi.c

From: Eli Zaretskii <[email-masked]>
Date: Sun, 19 Oct 2014 17:39:51 +0300

> Date: Thu, 16 Oct 2014 09:11:18 -0400
> From: Ken Brown <[email-masked]>
> CC: [email-masked]
> 
> On 10/16/2014 3:27 AM, Eli Zaretskii wrote:
> > Let's try to get a couple more full backtraces like this one, in case
> > some pattern emerges that could give us some ideas.
> 
> I saw some things in Thread 7 (the Windows message queue thread), especially 
> frame #14, which got me to look at the code for w32_wnd_proc in w32fns.c.  The 
> code is about 1300 lines long, and includes several comments about why it is 
> thread-safe.  Here are a few examples:
> 
>       Walking the frame list in this thread is safe (as long as
>       writes of Lisp_Object slots are atomic, which they are on Windows).
> 
>       It is also safe to use functions that make GDI calls, such as
>       w32_clear_rect, because these functions must obtain a DC handle
>       from the frame struct using get_frame_dc which is thread-aware.
> 
>       The code below does something that one shouldn't do: it
>       accesses the window object from a separate thread, while the
>       main (a.k.a. "Lisp") thread runs and can legitimately delete
>       and even GC it.  That is why we are extra careful...
> 
> I wonder if something in these 1300 lines is not thread-safe on Cygwin.  For 
> example, I don't know if it's true on Cygwin that "writes of Lisp_Object slots 
> are atomic".

I couldn't find even one "write to Lisp_Object slot" in that function,
so I don't see how this would matter.

Besides, the code that crashes has no relation to any Lisp objects: we
are walking the buffer text there.  So even if w32_wnd_proc does do
something that's "verboten" with Lisp objects, I still don't see how
that could change the result of a comparison-and-jump pair of
instructions in mid-flight.

The rest of what the comments in w32_wnd_proc say is correct, but
again unrelated, for the same reasons.  In fact, I cannot explain to
myself at all how _any_ code that is not thread-safe could cause such
a phenomenon.  I can think of no other explanations for what we see
except some code that somehow modifies the CPU flags between the
compare instruction and the following jump instruction.  Otherwise,
how can it be that the value is valid, but Emacs still aborts?  Any
other ideas?