[LLVMdev] Throwing an exception from JITed code, and catching in C++

Vapor Nide vaporanide at live.com
Wed Dec 26 17:03:52 PST 2012


If anyone else needs the answer to this question it is to add these two lines:
#include "llvm/Target/TargetOptions.h"
llvm::JITExceptionHandling = true;

----------------------------------------
> From: vaporanide at live.com
> To: llvmdev at cs.uiuc.edu
> Subject: Throwing an exception from JITed code, and catching in C++
> Date: Wed, 26 Dec 2012 19:25:06 -0500
>
>
>
> Hi everyone,
>
> I am writing an application that uses LLVM JIT and I would like to throw an exception from the JIT and catch it in the C++ code that invokes the JIT.
> This does not seem to work.
> I've written what is hopefully a super simple demonstration to reproduce this.
> I would appreciate any help with this.
>
> Thank you
>
> The demonstration is composed of:
> 1) thrower.cpp - a source file that contains a single function, throwInt(), that throws an int. This is compiled to thrower.s with clang and then to thrower.s.bc with llvm-as.
> 2) catcher.cpp - a source file that contains a main() that JITs thrower.s.bc and then calls throwInt(). This is compiled using g++.
>
> When I run catcher it just prints this:
> terminate called after throwing an instance of 'int'
>
> I am using LLVM and CLANG 3.0, and gcc 4.7.2.
>
> Here are all of the files needed to reproduce this:
> 1) thrower.cpp
> 2) catcher.cpp
> 3) Makefile
>
> This is how I run the test:
> make LLVM_BIN=path/to/llvm-3.0.src/Release/bin/
>
> $ cat thrower.cpp ################
> void throwInt()
> {
> throw 1;
> }
>
> $ cat thrower.s ################
> ; ModuleID = 'thrower.cpp'
> target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
>
> @_ZTIi = external constant i8*
>
> define void @_Z8throwIntv() uwtable {
> %1 = call i8* @__cxa_allocate_exception(i64 4) nounwind
> %2 = bitcast i8* %1 to i32*
> store i32 1, i32* %2
> call void @__cxa_throw(i8* %1, i8* bitcast (i8** @_ZTIi to i8*), i8* null) noreturn
> unreachable
> ; No predecessors!
> ret void
> }
>
> declare i8* @__cxa_allocate_exception(i64)
>
> declare void @__cxa_throw(i8*, i8*, i8*)
>
> $ cat catcher.cpp ################
> #include "llvm/LLVMContext.h"
> #include "llvm/Module.h"
> #include "llvm/ExecutionEngine/JIT.h"
> #include "llvm/Support/IRReader.h"
> #include "llvm/Support/TargetSelect.h"
> #include
>
> using namespace llvm;
>
> int main(int, char**)
> {
> LLVMContext& context = getGlobalContext();
> InitializeNativeTarget();
> SMDiagnostic error;
> Module* m = ParseIRFile("./thrower.s.bc", error, context);
> if (!m)
> {
> printf("could not load module\n");
> return 1;
> }
>
> ExecutionEngine* ee = ExecutionEngine::create(m);
> if (!ee)
> {
> printf("could not create execution engine\n");
> return 1;
> }
>
> Function* throwsIntFunction = ee->FindFunctionNamed("_Z8throwIntv");
> if (!throwsIntFunction)
> {
> printf("could not find function\n");
> return 1;
> }
>
> typedef void (*throwsIntType)();
> throwsIntType throwsInt = reinterpret_cast(ee->getPointerToFunction(throwsIntFunction));
> if (!throwsInt)
> {
> printf("could not get pointer to function\n");
> return 1;
> }
>
> try
> {
> throwsInt();
> }
> catch (int ex)
> {
> printf("caught an int\n");
> }
> }
>
> $ cat Makefile ################
> LLVM_CXX_FLAGS=$(shell $(LLVM_BIN)/llvm-config --cxxflags)
> LLVM_LIBS=$(shell $(LLVM_BIN)/llvm-config --libs)
> LLVM_LD_FLAGS=$(shell $(LLVM_BIN)/llvm-config --ldflags)
>
> all : tested
>
> .PHONY: clean
> clean:
> rm thrower.s thrower.s.bc catcher tested
>
> thrower.s : thrower.cpp Makefile
> $(LLVM_BIN)/clang -S -emit-llvm thrower.cpp
>
> thrower.s.bc : thrower.s Makefile
> $(LLVM_BIN)/llvm-as thrower.s
>
> catcher : catcher.cpp Makefile
> g++ -g catcher.cpp -o catcher $(LLVM_CXX_FLAGS) $(LLVM_LIBS) $(LLVM_LD_FLAGS) -Wno-cast-qual -fexceptions -O0
>
> tested : thrower.s.bc catcher Makefile
> ./catcher
> touch tested
>
>
 		 	   		  



More information about the llvm-dev mailing list