-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
I discovered this bug in the context of writing a JIT compiler for an interpreted language.
The JIT interfaces a C++ library which can throw exceptions, and the JIT should be able to catch them. To achieve that, I set the personality function of the catching functions to __gxx_personality_v0
, which is defined in the standard library, and uses landingpads.
Imagine we duplicate the definition of a function in the interpreted code. The function has a landingpad catching C++ exceptions. Then when the second definition happens, we delete the previously compiled code using llvm::orc::ResourceTracker::remove
then compile the new one. When executing the second version, the execution get lost in the throwing C++ code around __Unwind_RaiseException
and eventually segfault.
I wrote the most minimal code I could to replicate the error, but it is still a lot of code so I made it available on this gist : https://gist.github.com/epitavy/f2f5ded61b2d722ea22da1126b680f34
The code in the gist is self contained and provides different tests cases. One test cases is the crashing test, the others show cases where the crash does not happen.
Said in another way, compiling and executing a function with the following IR, deleting it using an orc::ResourceTracker
then compiling and executing it again segfaults on ARM architectures. I have tried on x86 and no crash happens.
define void @cppCatchFunct() personality ptr @__gxx_personality_v0 {
entry:
invoke void @throwCppException()
to label %normal unwind label %exception
normal:
br label %end
exception:
%landingPad = landingpad { ptr, i32 }
catch ptr null
%0 = extractvalue { ptr, i32 } %landingPad, 0
%1 = call ptr @__cxa_begin_catch(ptr %0)
call void @__cxa_end_catch()
br label %end
end:
ret void
}
I don't know if the error is related to ORC, to the way I am using LLVM or specific to ARM.