[LLVMdev] Getting exceptions to work?

Talin viridia at gmail.com
Mon May 18 21:56:49 PDT 2009


Nicolas Geoffray wrote:
> Hi Talin,
>
> You're not using the llvm intrinsics for exception handling, so your 
> code won't work. Using _Unwind_RaiseException should be OK, but your 
> main function must at least use llvm.eh.exception, 
> llvm.eh.selector.i32/64 and probably __cxa_begin_catch and __cxa_end_catch.
>   
Let me ask a follow-up question then - if the llvm.eh.* intrinsics are 
required to define the landing pad, then what is the role of the 
"unwind" target in the invoke instruction? According to the docs, the 
unwind target defines where execution will jump to when the called 
function returns with an exception, but clearly that isn't true - the 
flow of control passes directly to the personality function, bypassing 
the unwind target completely (as far as I can tell).

By using the llvm.eh* intrinsics, I have managed to get the code to call 
my custom personality function without crashing. However, what I don't 
yet understand is how to get the result from the personality function 
back to the landing pad. For example, I could use the function 
_Unwind_SetIP to tell it where to jump to, except that I can't take the 
address of a label in LLVM. I could call _Unwind_SetGR to set an index 
and then have a switch in the landing pad that uses that index - except 
that I would have no way to determine which register is safe to set in a 
platform-independent way. I could even just have the personality 
function do nothing at all, and have the landing pad do all the work - 
except that if my personality function doesn't do anything, then the 
landing pad is skipped entirely, and control resumes at the non-unwind 
target of the original invoke instruction, as if no exception had been 
thrown at all.
> Nicolas
>
>
> Talin wrote:
>   
>> I've been struggling for several days, trying to get native exceptions 
>> to work in my code. I managed to boil down the IR to the simplest 
>> possible example that I can think of.
>>
>> If anyone on this list can tell me what changes I need to make to the 
>> following code to get it to work (i.e. return 0 instead of a bus 
>> error), it would make my life immensely better.
>>
>>    ; ModuleID = 'ExceptionTest'
>>        %Object = type {}
>>        %UnwindInfo = type { i64, void (i32, %UnwindInfo *)*, i16, i16 }
>>        %Throwable = type { %Object, %UnwindInfo }
>>
>>    define i32 @main(i32, i8**) nounwind {
>>    entry:
>>        invoke fastcc void @throwSomething() to label %nounwind unwind
>>    label %catch
>>
>>    catch:
>>        ret i32 0
>>
>>    nounwind:
>>        ret i32 -1
>>    }
>>
>>    define internal fastcc void @throwSomething() noreturn {
>>    entry:
>>        %throwable = malloc %Throwable
>>        call fastcc void @Throwable.construct(%Throwable* %throwable)
>>        %unwindInfo = getelementptr %Throwable* %throwable, i32 0, i32 1
>>        %throw = call i32 @_Unwind_RaiseException(%UnwindInfo* 
>> %unwindInfo)
>>        unreachable
>>    }
>>
>>    define internal fastcc void @Throwable.construct(%Throwable* %self)
>>    nounwind {
>>    entry:
>>        %exceptionClass = getelementptr %Throwable* %self, i32 0, i32 1,
>>    i32 0
>>        store i64 0, i64* %exceptionClass
>>        %exceptionCleanup = getelementptr %Throwable* %self, i32 0, i32
>>    1, i32 1
>>        store void (i32, %UnwindInfo *)* @exceptionCleanupFn, void (i32,
>>    %UnwindInfo *)** %exceptionCleanup
>>        %private1 = getelementptr %Throwable* %self, i32 0, i32 1, i32 2
>>        store i16 0, i16* %private1
>>        %private2 = getelementptr %Throwable* %self, i32 0, i32 1, i32 3
>>        store i16 0, i16* %private2
>>        ret void
>>    }
>>
>>    define internal void @exceptionCleanupFn(i32 %reason, %UnwindInfo *
>>    %exc) {
>>      ret void
>>    }
>>
>>    declare i32 @_Unwind_RaiseException(%UnwindInfo*) noreturn
>>
>> -- Talin
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>     
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>   




More information about the llvm-dev mailing list