[LLVMdev] trouble understanding value in dwarf exception mechanism
baldrick at free.fr
Sat May 4 00:37:53 PDT 2013
On 25/04/13 07:38, edA-qa mort-ora-y wrote:
> I'm having trouble understanding the value in the way exceptions are
> handled on Linux, the dwarf/system V ABI exception spec. The mechanism
> allows for both cleanup routines and catch handlers, where by cleanup
> handlers don't stop the search for a normal handler. The personality
> function (I guess no longer part of the standard, but a C++ thing) can
> also compare types of the landingpads.
> I'm having trouble understanding a few points. I would like to
> understand since I have exceptions in my language as well and want to
> make effective use of the model.
> 1. The way basic blocks come together often means you can have embedded
> try/catch handlers without an intervening function call. You can't have
> multiple landingpads without an intervening invoke thus one block needs
> to branch/include the other handler. This appears to result in the need
> to check the types of exceptions in the landingpad.
the kind of test involved is completely different. The personality function
has to do language specific tests with a type, eg class comparisons, which
might be complicated. The landing pad is essentially just executing a switch
instruction (in GCC they experimented with having codegen output a real switch,
but found that a series of "if" comparisons was usually faster). Also,
inlining naturally creates nested catch blocks, so I don't see how you can
escape something like this (need to test multiple catch possibilities in one
landing pad) in general.
This seems wasteful
> to check the types in both the personality and the landingpad.
> 2. Cleanup landingpads, in the general case, will need to call
> functions. Not knowing what is in these functions one must assume they
> could in turn have their own exception flow: they have a try/catch but
> don't allow exceptions to escape. The ABI mechanism though seems like
> only one exception at a time can be in progress. This would mean that
> cleanup code would have to register as catch handlers and rethrow the
> exception -- they cannot be "cleanup" routines according to the standard.
It is perfectly fine to have a cleanup throw an exception (and maybe catch
it or maybe let it propagate, or whatever), the unwind library doesn't care.
Ada does this and doesn't have to jump through any hoops to get it to work.
The reason that C++ has trouble with this is not coming from the unwind
library, it's coming from C++ semantics (the fact that exception objects
themselves may need complicated destructing IIRC). It's a C++ problem.
> In all I don't see why the current approach is better than simply
> treating all landingpads equally in the personality. Each landingpad
> would do its own type checking and rethrow or continue as appropriate.
> That is, no cleanup routines, and no type matching in the personality.
Wouldn't that mean that for every stack frame, you would have to restore
all registers, jump to your code for the stack frame (which would then do
the type testing, i.e. in essence be an inlined version of the personality
function), then maybe continue unwinding. That seems expensive, and like
a good way to get very fat landing pad code. Anyway you can always have
your personality function be very simple: it can not bother with any type
comparisons, just always say "yes, there is a match", causing control to
always branch to your landing pad, giving the effect that you want.
More information about the llvm-dev