-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Use Itanium Unwind ABI in place of HP's #4190
Comments
/cc @janvorli The current EH design built upon the existing (Windows) code as much as possible, to avoid introducing unnecessary complexity. Check the design discussions in #3942 and #3946. Implementing the EH differently is certainly possible, but it is unlikely to be an improvement. Alternative measurably better implementations are welcomed to prove me wrong. |
@jsonn - what do you mean by the HP interface? The low level libunwind? We need that one for stack walking over native frames and its use in the exception handling itself is to unwind to the first managed frame. We use it for stack walking for GC purposes too. |
"Low" and "high" level is a bit misleading as the interfaces (libunwind.h vs unwind.h) are pretty much orthogonal. libunwind.h is the HP interface, unwind.h is standard Itanium ABI. If all you want to do is stack walking, _Unwind_Backtrace is a wide supported extension of the plain Itanium ABI to just do a forced unwind. The same trick with adjusting the context with known registers can be used here. What I don't understand is how the current code is supposed to interact with foreign exception handlers, i.e. if the call stack contains C++ code. |
We use libunwind to walk the stack for GC (and other purposes). We do not use to run the actual handlers. Does the Itanium ABI have equivalent of unw_get_save_loc? |
@jkotas No, it doesn't have that.
We are not using the API for exception unwinding itself. In the exception handling, we just use it to scan the stack to find the first managed frame. The exception unwinding of native frames on the call stack is performed just by throwing C++ exception and catching it at the last native frame before a managed frame or possibly in the native code itself. |
But you don't run exception handlers if there is any non-CLR frame between the top of the stack and the first managed frame, right? Or is that case impossible? unw_get_save_loc is currently not supported by LLVM (and Apple's) unwind implementation. I'm not sure how it can work reliable. I believe it is valid for one frame explicitly restore the register if it guarantees that all exceptions are handled. But this is a topic that should be brought up on the LLVM lists for input from other involved parties. It would seem to me that the ability to intercept the return to a frame would provide a more reliable mechanism. It would still require extending the interface for that, but it seems to be a better primitive. We explicitly don't support the libunwind.h interface in NetBSD as it exposes interfaces in a bad way. The size of the unwind context needs to be statically sized large enough to hold all possible target state, which is a bad idea for long term maintenance. There are other flaws in the interface making it problematic. That said, I am strongly interested in finding and fixing issues with the Itanium ABI. |
No, we don't. The native frames that are there are always frames stemming from a catch handler of managed exception thrown as PAL_SEHException by coreclr (which includes IL_Throw / IL_Rethrow helpers that are called when managed code throws / rethrows an exception). So we know we can just skip such frames without performing full exception unwinding. Regarding the |
How do you ensure that the spilling is really annotated? I mean I can write an assembler function with a catch all block and spill/restore the registers manually without adding .cfi annotation. That would still be correct for normal EH operation. |
Thinking a bit more about |
@jsonn Regarding your former question, for the GC purposes, we care only for native code in the coreclr. We have all the assembler functions properly annotated. And we spill all callee saved registers to stack in an asm helper when we call external native code. |
Can we close it? |
I think so. |
Exception Handling on ELF platforms (except ARM) and on Mac OSX is based on the Itanium ABI. From a cursory look, it should be possible to implement the EH dispatch directly on top without having to use the non-standard HP interface. Am I missing something fundamental?
The text was updated successfully, but these errors were encountered: