-
-
Notifications
You must be signed in to change notification settings - Fork 606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OSv freezes when exception is thrown out of main #64
Comments
On Mon, Oct 21, 2013 at 3:10 PM, Tomasz Grabiec [email protected]:
Interesting, a regression? Can you please check tests/tst-except.so? It used to not work correctly, but then I a bug in dl_iterate_phdr and it
Nadav Har'El |
tst-except passes, probably because exception does not go out of main 2013/10/21 nyh [email protected]
|
On Mon, Oct 21, 2013 at 3:28 PM, Tomasz Grabiec [email protected]:
I see... Good (it's obviously much more serious to have a general bug with Probably the simplest solution is just to add a "try" in loader.cc's If you are not planning on doing this (or otherwise solving this bug), I Nadav Har'El |
2013/10/21 nyh [email protected]
I wasn't going to work on this now, so please go ahead.
|
As noticed by Tomek in issue #64, unhandled C++ exceptions cause OSv to silently hang, in an endless loop inside the unwinding code. So this patch fixes the wrong CFI (DWARF Call Frame Information) which caused the unwinder to loop. We just had a single line of assembly missing: The topmost frame - the thread's main function - needs to undefine the saved %rip to prevent going further back. If we don't do that, gdb will end every "bt" output with a warning "Frame did not save its PC" (but hey, nobody complained... ;-)), and the unwinding library, will, unfortunately, go into an endless loop as seen in issue #64. With this one-line patch, unhandled exceptions now work as expected - they abort with a message like: terminate called after throwing an instance of 'int' Aborted And attaching a debugger you can see exactly where the offending throw came from (i.e., the stack does *not* unnecessarily unwind when there's nobody waiting to catch the exception). This works for uncaught exceptions anywhere - including inside main() and from constructors when loading the object (before running main()). "bt" in gdb also no longer ends each stack trace with an error message. The last frame it shows is "thread_main()". Signed-off-by: Nadav Har'El <[email protected]>
Commit 7fc023e fixed issue #64, and made unhandled exceptions work correctly. This patch adds a test to tst-except.cc to test this - that an unhandled exception really does call the custom termination handler that the C++ standard allows to set (before the above commit, this test would hang). Unfortunately, gcc's libsupc++ tries very hard to ensure that the terminination handler really does abort - if the handler returns, or throws an exception, the library nevertheless aborts. So we need to trick it with an ugly longjmp to make this test be able to complete without aborting the system. Signed-off-by: Nadav Har'El <[email protected]>
d8-d15 are callee-saved registers [1], and since q8-q15 are listed in the clobber list in the inline asm, the compiler added instructions to save and restore d8-d15 from the stack. To be exact, fpu_state_load() was surrounded by callee-register-saving snippets like this, for example: stp d8, d9, [sp, #48] stp d10, d11, [sp, #64] stp d12, d13, [sp, #80] stp d14, d15, [sp, #96] ... our inline asm here ... ldp d8, d9, [sp, #48] ldp d10, d11, [sp, #64] ldp d12, d13, [sp, #80] ldp d14, d15, [sp, #96] This was effectively zeroing out the upper 64 bits of q8-q15 during interrupts and pre-emptive context switches. Two possible ways to work around this issue would be to remove q8-q15 from the clobber list, or to move the implementation to a real assembly file. I chose to move fpu_state_save/load to assembly (entry.S) to guarantee that the compiler won't potentially add any unwanted instructions. This also takes out any guesswork of how the syntax of inline assembly works. [1] https://developer.arm.com/documentation/ihi0055/latest/ See section "SIMD and Floating-Point Registers" [2] d8-d15 is the 64-bit name for v8-v15 q8-q15 is the 128-bit name for v8-v15 Signed-off-by: Stewart Hildebrand <[email protected]> Message-Id: <[email protected]>
OSv freezes when running the following program:
Result on Linux:
terminate called after throwing an instance of 'int'
Aborted (core dumped)
The text was updated successfully, but these errors were encountered: