[LLVMdev] Darwin vs exceptions

Dale Johannesen dalej at apple.com
Sun Dec 9 10:48:49 PST 2007

On Dec 9, 2007, at 2:34 AM, Duncan Sands wrote:

> Hi Dale,
>>> this is the bit I don't understand.  Why does it go
>>> into a loop?  How can the unwinder possibly know that
>>> the original code did not have a catch-all, since we
>>> tell it which catches there are and we say: there is
>>> a catch-all!
>> The unwinder works by doing a stack crawl to find a handler.  Since
>> we're telling it every eh-selector is a catch-all handler, it finds
>> one immediately (that is not there)
> I'm not sure what you mean: there is a handler: it just rethrows
> the exception.  This is not very interesting of course, but it's
> still a handler.  Or do you mean something different when you talk
> of a handler?

I'm following the notation in comments in the unwinding code
(gcc/unwind*, especially unwind.inc, and libstdc++/libsupc++/eh*,
especially eh_personality.cc).  "handler" is used consistently to mean
something that actually handles the thrown exception, a catch-block
for that thrown type.  Code that just calls destructors and resumes is
a "cleanup", and is handled differently in the tables and code.

Linux's unwinder uses the same code, doesn't it?  I bet if you make  
the same
change in uw_identify_context that we have you would have the same  

>> and caches where it thinks it
>> is.  That code (cleanup or whatever) is executed and ends by reaching
>> Unwind_Resume, which tries to resume at where it thinks the handler
>> is.
> I also don't understand this: why is Unwind_Resume looking at where
> the exception's handler is?

I don't know the 'why' of any of this; I didn't write it, nor did  
anybody at Apple.

> The handler used for the caught exception
> should be irrelevant to it.  It sounds like the unwinder thinks that
> the Unwind_Resume is in the same eh region as the original throwing
> call.

Yes, exactly, and when you're using CFAs rather than IPs to identify  
it, it is.
The code in question is in Unwind_RaiseException_Phase2, reached from
       /* Identify when we've reached the designated handler  
context.  */
       match_handler = (uw_identify_context (context) == exc->private_2
                        ? _UA_HANDLER_FRAME : 0);

>> Which is back at the same code from which we reached
>> Unwind_Resume.  This worked OK when we were caching the IP because
>> the IP of the throw and Unwind_Resume call were different, but when
>> caching the CFA they are the same, which confuses Unwind_Resume.
> How is catch-all then rethrow supposed to work then?

It isn't.  Catch-all (corresponding to "catch(...)" ) ends the  

> Are you sure
> that this isn't simply a bug in where labels are placed etc, the
> frame info or the exception table setup etc?

Yes, comparing gcc and llvm output has made me quite sure of that.

>> (This is darwin's unwinder but I think the patch I quoted is the only
>> relevant change to generic gcc code.
>> Could be wrong.)
>>>>> -  lang_eh_catch_all = return_null_tree;
>>>>> +/*  lang_eh_catch_all = return_null_tree;*/
>>>> Ok, cool :)  Duncan, Anton, what do you guys think about this?
>>> This is wrong - it breaks the semantics of invoke and causes
>>> eh to not work properly in some cases (see my email to Dale).
>> Well, it works a lot better on Darwin than what's there now.  I
>> believe telling the unwinder there is a cleanup is sufficient to get
>> control always transferred to the secondary label on the invoke.
> Are you saying that the Darwin unwinder doesn't have the special
> cleanup logic?  If so you could indeed push a cleanup rather than
> a catch-all on Darwin.

What "special cleanup logic"?

>> Could you point me to an example that should fail?
> Sure - run the testsuite on linux with -enable-correct-eh-support
> changed to -enable-eh in Makefile.programs.  Then apply your patch,
> run again and analyse the failures.  I will do this and send you
> a reduced example (I used to have some but I don't remember what
> I did with them).
> Ciao,
> Duncan.

More information about the llvm-dev mailing list