Opened 10 years ago

Closed 10 years ago

#819 closed defect (fixed)

windows exception 0x80000004 in SPffcall

Reported by: rme Owned by: rme
Priority: normal Milestone:
Component: Runtime (threads, GC) Version: trunk
Keywords: windows Cc:


See the attached test case.

It appears that the TF bit in the flags register is getting set sometimes when restoring the saved flags from tcr.unboxed0 in SPffcall.

I don't understand how that bit is getting set. I added code to see if the bit was set when doing the initial pushfl, and never saw it. Yet, somehow, tcr.unboxed0 will occasionally end up with the TF bit set, and then we get the 0x80000004 (single-step) exception from Windows after we restore the flags with popfl.

Attachments (1)

event-crash-test.lisp (1.2 KB) - added by rme 10 years ago.
test case from Michael Minerva

Download all attachments as: .zip

Change History (6)

Changed 10 years ago by rme

test case from Michael Minerva

comment:1 Changed 10 years ago by rme

I should have mentioned that the way to provoke the bug using the test case is to load the attached file, select the window that appears, and press keyboard keys. It may take up to a minute, but it should eventually crash in SPffcall with "unhandled exception -1 (windows code 0x80000004)".

comment:2 Changed 10 years ago by rme

(In [14652]) In SPffcall, don't use popfl to restore the state of DF. Instead, test the DF bit in the saved flags directly, and set DF with the std instruction if needed.

This appears to resolve the issue described in ticket:819. On the other hand, I don't see how the TF bit is gettting set in the saved flags, so this may simply be masking the symptoms of some underlying bug.

See ticket:819.

comment:3 Changed 10 years ago by gb

Note that we use tcr.unboxed0 in other cases (e.g., _SPkeyword_bind, possibly elsewhere.) In some cases - if we do a callback due to an exception, for instance - we take care to preserve tcr.unboxed0 and a few other things. In other cases - if the callback is just defined as the implementation of an ObjC method, for instance - the callback can freely bash tcr.unboxed0. It's not too hard to imagine a sequence of "ffcall, callback, something that binds keywords and stores a random value in tcr.unboxed0, return from callback, return from ffcall" finding that the tcr slot has "mysteriously" changed.

If we can avoid saving and restoring the flags in the TCR on ffcall and therefore avoid this issue, great; it just isn't surprising that the slot can get clobbered during the ffall (because of code run from callbacks.)

comment:4 Changed 10 years ago by rme

We used to use tcr.saved_eflags to save the flags in SPffcall, but I changed it to use tcr.unboxed0 when I merged in the changes to shrink the TCR on 32-bit Windows. Clearly a bad move.

comment:5 Changed 10 years ago by rme

  • Resolution set to fixed
  • Status changed from new to closed

As of r14657, we don't save/restore DF in SPffcall at all.

We have always assumed that the node/imm register split is the default.

Note: See TracTickets for help on using tickets.