Closed Bug 497669 Opened 15 years ago Closed 15 years ago

Standard MSVC longjump cannot be used with Tamarin if Tamarin is compiled with C++ exception support

Categories

(Tamarin Graveyard :: Virtual Machine, defect, P1)

x86
Windows XP

Tracking

(Not tracked)

VERIFIED FIXED
flash10.1

People

(Reporter: lhansen, Assigned: lhansen)

References

Details

(Whiteboard: Has patch)

Attachments

(1 file, 1 obsolete file)

The problem is that MSVC longjmp unwinds the stack in the same way as exception handling would, if exception handling is turned on. This is probably legal but really breaks our locking code: MMGC_LOCK turns into a local variable declaration that acquires a spinlock on entry and releases it when the object is destroyed. Code that longjmps past such a lock (only the out-of-memory abort at this time) is careful to perform an explicit unlock of the GCHeap lock before jumping - but because the destructor of the locking object is called by longjmp, we get a double release, and we have asserts to catch that. If we have other acquire/release patterns then they too could be affected. The fix is to use a setjmp/longjmp implementation that does not do this. We need to provide such an implementation and we need to implement (well documented) checks for this problem occuring. It's not clear to me right now what those checks might look like.
One correspondent writes: "You might look into turning off structured exception handling. That might cause setjmp/longjmp to not call the c++ destructors when unwinding. Try /EHsc. Link to /EH docs: http://msdn.microsoft.com/en-us/library/1deeycx5.aspx"
Priority: -- → P3
Target Milestone: --- → flash10.1
Priority: P3 → P2
This appears to be a problem even if Tamarin is compiled with C++ exceptions disabled, at least on 64-bit Vista. The situation in the code is pretty messy: we call naked setjmp/longjmp here and there, never VMPI_ versions; the jit appears to call our own _setjmp3 under some circumstances. None of this seems reliable.
Severity: normal → major
Priority: P2 → P1
Blocks: 515935
(Taking this because it's blocking another P1 bug I have.)
Assignee: nobody → lhansen
Status: NEW → ASSIGNED
Attached patch Preliminary patch, MSVC only (obsolete) — Splinter Review
Introduces VMPI_setjmpNoUnwind and VMPI_longjmpNoUnwind and maps them to the correct non-unwinding versions on 64-bit MSVC builds; maps them to setjmp and longjmp on 32-bit MSVC builds because that works correctly. Implementations for other platforms to follow.
Tested on Windows and Mac; testing continues. Please review carefully for impacts to JIT.
Attachment #408448 - Flags: review?(edwsmith)
Attachment #408442 - Attachment is obsolete: true
Attachment #408448 - Flags: review?(edwsmith) → review+
Comment on attachment 408448 [details] [diff] [review] Patch for all platforms jit never calls longjmp directly. confirmed that we're properly taking &::setjmp on mac-32 and mac-64. if win32 and winmo pass regression testing then i think we're in the clear.
Whiteboard: Has patch
redux changeset: 2881:b80e5c6070d6
Status: ASSIGNED → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: