[LLVMdev] Exception Handling Tables Question

Nick Kledzik kledzik at apple.com
Thu Sep 17 21:18:38 PDT 2009

On Sep 17, 2009, at 6:03 PM, Duncan Sands wrote:

> Hi Bill,
>>>> Yeah. The logic will need tweaking for sure. I'm also concerned  
>>>> about the
>>>> _Unwind_resume() call. GCC emits a call site region for it in the  
>>>> exception
>>>> table. We...kind of do that. It looks like it's being included in  
>>>> one of the
>>>> "this is a region which isn't in a try-catch block, but it has a  
>>>> call in it,
>>>> so lets add it to the exception table" areas.
>>> isn't that exactly how it should be?  This is a call that will  
>>> unwind
>>> out of the function, so C++ requires it to have a call site region  
>>> just
>>> like any other call that we want to let unwind out of the  
>>> function.  I
>>> don't see why it needs any special logic.  If I understood right the
>>> change you want to make is that if a call is known not to unwind  
>>> then
>>> you want to omit adding a call-site entry if that saves some space  
>>> in
>>> the call site table, which seems irrelevant to this, or am I missing
>>> something?  By the way, LLVM "nounwind" calls are different to GCC  
>>> no
>>> throw regions IIRC.  If an exception is thrown in a GCC no throw  
>>> region
>>> then it must (C++) result in a call to "terminate".  These are not
>>> mapped to "nounwind", instead we create explicit "catch-all" filter
>>> expressions for this (IIRC).  In LLVM it is undefined what happens  
>>> if
>>> a call is marked "nounwind" but nonetheless an exception unwinds out
>>> of it.  Thus you can add call-site entries for nounwind calls,
>>> or not add them, as you like - whatever is most convenient (eg:  
>>> saves
>>> the most space).  An interesting optimization which we don't do is  
>>> to
>>> identify which calls correspond to a "catch-all" filter and not  
>>> generate
>>> an entry for them in the call-site table (no need to add the filter
>>> either) - this saves space and the C++ runtime knows to handle this
>>> just like if we added the filter explicitly.
>> There's a miscommunication here. :-) The _Unwind_resume call isn't
>> marked with "nounwind", however it's not called through an "invoke"
>> instruction, only a regular "call" instruction. From what I can see,
>> the only reason it falls within a call site in the exception table is
>> because we're generating call sites for areas of code without
>> "invokes".
> yes, and that's absolutely the right thing to do!  Due to a strange
> design choice, if a call does *not* have an entry in the call-site
> table, and the call unwinds, then the runtime calls std::terminate.
> All calls that may throw (like _Unwind_Resume!) must have an entry
> in the call-site table.

But _Unwind_Resume() is special.  It never returns. It does not throw.

The purpose of  _Unwind_Resume() is for when you have a function with  
a destructor that implicitly needs running during exception processing  
as the exception unwinds through the stack.  The unwinder jumps into  
that function's landing pad where the compiler has laid down a call to  
the destructor followed by a call to _Unwind_Resume() which then  
continues where the unwinding left off in processing the exception.

Therefore, I don't see the point of having a call-site entry for the  
_Unwind_Resume() "call".


More information about the llvm-dev mailing list