This is the mail archive of the
archer@sourceware.org
mailing list for the Archer project.
Inferior function calls and out-of-frame exception handlers
- From: Phil Muldoon <pmuldoon at redhat dot com>
- To: Project Archer <archer at sourceware dot org>
- Date: Fri, 15 Aug 2008 07:40:24 -0400 (EDT)
- Subject: Inferior function calls and out-of-frame exception handlers
When one calls a function via inferior function call, and that function raises an exception (throw), but that function has no local exception handler (catch), the inferior exits with sigabrt. This is filed, with a test-case in gnats 2495. This occurs on platforms with GCC that follow the C++ ABI, and not sjlj exceptions (1).
Today I spent a little time looking at this.
Briefly in this case:
void foo_no_local_exception_handler ()
{
throw;
}
In GDB if one calls this via inferior function call, perhaps as follows:
p foo_no_local_exception_handler ()
a dummy frame is created for the function call. When the exception is raised, it is packaged and _Unwind_RaiseException is called. The _Unwind_RaiseException proceeds to perform the _UA_SEARCH_PHASE and searches for a matching handler. I stepped through this today, and because of the mechanics of the inferior function call and the single dummy frame, it will not find a matching exception handler. The _UA_SEARCH_PHASE terminates and _Unwind_RaiseException returns with a _URC_END_OF_STACK. To quote the C++ ABI here (http://www.codesourcery.com/public/cxx-abi/abi-eh.html#cxx-catch):
"_URC_END_OF_STACK: The unwinder encountered the end of the stack during phase 1, without finding a handler. The unwind runtime will not have modified the stack. The C++ runtime will normally call uncaught_exception() in this case."
And that is exactly what happens in this case. _Unwind_RaiseException returns and this code executes:
74 // Some sort of unwinding error. Note that terminate is a handler.
75 __cxa_begin_catch (&header->unwindHeader);
76 std::terminate ();
And the inferior terminates. This won't happen with a local exception handler as the unwinder can find the handler in frame.
That being said, I'm a little at a loss on how this can fixed. The unwinder and exception raising mechanisms are working as designed and the inferior function frame is being correctly assembled for the command. I was pondering catching the exception with a GDB supplied implementation-specific handler for the purposes of the inferior function call. But not sure if this is even possible. Suggestions?
Regards
Phil