LLVM Exception Handling

Hi,

I am trying to implement a scenario similar to running ExceptionDemo.cpp with parameter -1 (where the JITed code calls the C++ function which throws an exception)

Different from the given example I am using IRParser instead of IRBuilder. I can successfully catch the exception in Linux but the program crashes in Mac and Windows.

The code is similar to as follows:

The test.cpp : (clang++ -O0 -S -emit-llvm test.cpp –c)

extern void test() ;

extern “C” void exec(void*) {

test();

}

main.cpp

// necessary includes here…

static void test() {

throw 1;

}

int main(int, const char **) {

llvm::InitializeNativeTarget();

llvm::InitializeNativeTargetAsmPrinter();

llvm::InitializeNativeTargetAsmParser();

llvm::LLVMContext &Context = llvm::getGlobalContext();

llvm::SMDiagnostic Err;

std::unique_ptrllvm::Module Mod = llvm::parseIRFile(“test.ll”, Err, Context);

std::string triple = llvm::sys::getProcessTriple();

Mod->setTargetTriple(triple);

llvm::Function* f = Mod->getFunction(“exec”);

llvm::TargetOptions Opts;

Opts.NoFramePointerElim = true;

// Build engine with JIT

std::unique_ptrllvm::RTDyldMemoryManager MemMgr(new llvm::SectionMemoryManager());

std::string err;

llvm::EngineBuilder factory(std::move(Mod));

factory.setErrorStr(&err);

factory.setEngineKind(llvm::EngineKind::JIT);

factory.setTargetOptions(Opts);

factory.setMCJITMemoryManager(std::move(MemMgr));

llvm::ExecutionEngine* EE = factory.create();

llvm::sys::DynamicLibrary::AddSymbol("_Z4testv", reinterpret_cast<void*>(test));

EE->finalizeObject();

void* poi = EE->getPointerToFunction(f);

void (exec)(void) = reinterpret_cast<void ()(void)>(poi);

try {

exec(NULL);

} catch (int e) {

std::cout << "catched " << e << std::endl;

}

return 0;

}

I haven’t dug into your example, but I would say exceptions don’t work on Windows yet.

I don’t know why it doesn’t work on Mac.

I haven't dug into your example, but I would say exceptions don't work
on Windows yet.

I don't know why it doesn't work on Mac.

The symptoms look like what happens when you have two copies of the rtti each in different SOs. If that's the problem, then throwing from one SO and trying to catch in the other will terminate this way when the first's typeinfos don't match against any in the second.

I don't know the JIT well at all, but I'd suggest printing out the address of the type info for int, _ZTIi, and check that they're the same in both the JIT-ee and the JIT-er.

Jon

In r234975 I fixed an issue where we were failing to emit the eh_frame for JIT’d code on MacOS. It may have fixed this problem.

  • Lang.