[LLVMdev] How to code catch-all in the new exception handling scheme?
gvenn.cfe.dev at gmail.com
Wed Sep 28 05:28:07 PDT 2011
Bill, and Duncan forced me to go back though my code, and the Itanium exception
ABI doc: http://sourcery.mentor.com/public/cxx-abi/abi-eh.html. For the clarity of
others, and for recorded posterity, I am tagging a couple of Duncan's statements
with references back to the doc which is now at rev 1.22.
On Sep 28, 2011, at 4:20, Duncan Sands wrote:
> If only cleanups are found in phase 1 then the unwinder hits the top
> of the stack without finding a handler and returns _URC_END_OF_STACK without
> installing any handlers; note that a cleanup is not considered to be a handler.
> If the C++ unwinder sees the call to _Unwind_RaiseException return like this
> then it terminates the program. Cleanups will therefore not have been run.
> The Ada unwinder behaves differently. If it the call to _Unwind_RaiseException
> returns then it calls _Unwind_ForcedUnwind which runs all the cleanups. The
> program is then terminated. In the more common situation of the unwinder seeing
> a handler somewhere up the stack it doesn't return and moves on to phase 2 as
> you described; but your description doesn't apply to the case in which there are
> only cleanups.
Under section 1.3 the _Unwind_RaiseException function can return:
_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.
Duncan is calling _Unwind_ForcedUnwind at this point on such a return. I have
yet to look for what the behavioral specification of uncaught_exception() is but
according to Duncan it seems it is supposed to terminate.
> First off, the C++ personality function does have special support for
> foreign exceptions. A C++ catch-all will happily catch Ada exceptions for
> example. If there is a C++ cleanup and an Ada exception is unwinding then
> (assuming the Ada exception isn't matched by a C++ catch-all) the C++
> personality function acts exactly the same as if a C++ exception was unwinding:
> it returns _URC_CONTINUE_UNWIND and the unwinder continues to unwind. Let's
> suppose that there are only cleanups all the way up the stack. Then phase 1
> ends with _Unwind_RaiseException returning _URC_END_OF_STACK. If it was C++'s
> "throw" that was doing the unwinding, it will terminate the program at this
> point. If it was Ada's "raise" that was doing the unwinding, it will call
> _Unwind_ForcedUnwind which will run all cleanups including the C++ ones. Then
> it will terminate the program.
Ibid and section 1.6.4:
An exception which has an unknown class must not be altered by the personality routine. The semantics of foreign exception processing depend on the language of the stack frame being unwound. This covers in particular how exceptions from a foreign language are mapped to the native language in that frame.
Example: Foreign Exceptions in C++. In C++, foreign exceptions can be caught by a catch(...) statement. They can also be caught as if they were of a __foreign_exception class, defined in <exception>. The__foreign_exception may have subclasses, such as __java_exception and __ada_exception, if the runtime is capable of identifying some of the foreign languages.
The example depicts the behavior of clang's C++ exception "unwinder" with regard to
foreign exceptions handled by a catch(...). Not sure about the rest.
> Ciao, Duncan.
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
Hope this helps, and thanks to Bill and Duncan for clarifying this behavior by
having their discussion on the list.
More information about the llvm-dev