jmmartinez / easy-just-in-time

LLVM Optimization to extract a function, embedded in its intermediate representation in the binary, and execute it using the LLVM Just-In-Time compiler.
BSD 3-Clause "New" or "Revised" License
511 stars 31 forks source link

Example fails with `Inserted && "Pass registered multiple times!"' error #45

Open spyked opened 5 years ago

spyked commented 5 years ago

Compiling with a custom build of LLVM 6.0 works:

$ pwd
/home/mogosanu/llvm-jit/easyjit-obj
$ cmake -DLLVM_DIR=/opt/llvm-6.0/lib/cmake/llvm/ ../easy-just-in-time/
$ cmake --build .
# generates /home/mogosanu/llvm-jit/easyjit-obj/bin/{EasyJitPass.so,libEasyJitRuntime.so}

And so does compiling a very simple example:

/opt/llvm-6.0/bin/clang++ -O2 --std=c++14 -o hello hello.cpp \
  -Xclang -load -Xclang /home/mogosanu/llvm-jit/easyjit-obj/bin/EasyJitPass.so \
  -I/home/mogosanu/llvm-jit/easy-just-in-time/include -L/home/mogosanu/llvm-jit/easyjit-obj/bin \
  -lEasyJitRuntime

But running it gives the following error:

$ LD_LIBRARY_PATH=/home/mogosanu/llvm-jit/easyjit-obj/bin ./hello 
hello: /home/mogosanu/llvm-jit/llvm/lib/IR/PassRegistry.cpp:62: void llvm::PassRegistry::registerPass(const llvm::PassInfo&, bool): Assertion `Inserted && "Pass registered multiple times!"' failed.
Aborted

hello.cpp:

#include <cstdio>

int main(void)
{
    printf("Hello, world!\n");
    return 0;
}

Can I get some help regarding this? Thank you!

jmmartinez commented 5 years ago

Hello! I'll try to reproduce it and I'll come back to you. Thanks for the issue !

spyked commented 5 years ago

Thank you for looking at this!

I forgot to add: the LLVM build I used is the official LLVM 6.0 release compiled with X86 as a target and with RTTI support.

spyked commented 5 years ago

I've been digging a bit more into this and the reason for the assertion failure seems to be related to the fact that registerPass is called multiple times from the initialization routines in the run-time, e.g. LLVMInitializeX86Target called from InitNativeTarget. This can be observed by running the example under gdb and breaking on registerPass.

The bug doesn't manifest in the LLVM packaged in e.g. Debian because that is a release build, or in any case, assertions are disabled for package builds. Passing -DCMAKE_BUILD_TYPE="Release" to the LLVM cmake call works around the bug.

jmmartinez commented 5 years ago

Today I've been trying to fix this. I did not find a solution for the moment. There seem to be other problems also with static linking for example. Thanks a lot for the help!