You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since many projects depend on LLVM, we recommend that distributions and downstream user use symbol versioning to avoid conflicts between multiple LLVM versions being loaded into the same process.
On Linux mesa implementations (OpenGL/OpenCL) use LLVM extensively and they are generally built against the system LLVM. On the other hand front-ends like Julia might want to use a version of LLVM that diverges from the system LLVM.
What we have observed happening for several years is that users will get errors like:
CommandLine Error: Option 'help-list' registered more than once!
LLVM ERROR: inconsistency in registered CommandLine options
What this boils down to is that despite symbol versioning wires get crossed and the state of the two loaded LLVM version aliases each other.
After I building mesa, my system LLVM and Julia's LLVM with debuginformation I get the following interesting backtrace:
julia: /home/vchuravy/src/julia/deps/srccache/llvm-11.0.0/include/llvm/Support/CommandLine.h:851: void llvm::cl::parser<DataType>::addLiteralOption(llvm::StringRef, const DT&, llvm::StringRef) [with DT = llvm::FunctionPass* (*)(); DataType = llvm::FunctionPass* (*)()]: Assertion `findOption(Name) == Values.size() && "Option already exists!"' failed.
Thread 1 "julia" received signal SIGABRT, Aborted.
0x00007ffff7dda615 in raise () from /usr/lib/libc.so.6
(gdb) bt
#​0 0x00007ffff7dda615 in raise () from /usr/lib/libc.so.6
#​1 0x00007ffff7dc3862 in abort () from /usr/lib/libc.so.6
#​2 0x00007ffff7dc3747 in __assert_fail_base.cold () from /usr/lib/libc.so.6
#​3 0x00007ffff7dd2bf6 in __assert_fail () from /usr/lib/libc.so.6
#​4 0x00007ffff0a8014e in llvm::cl::parser<llvm::FunctionPass* (*)()>::addLiteralOption<llvm::FunctionPass* (*)()> (this=0x7ffff72fce68 <RegAlloc+168>,
Name=...,
V=@0x7fffffff9bc0: 0x7fffa6d8ff40 <llvm::createBasicRegisterAllocator()>,
HelpStr=...)
at /home/vchuravy/src/julia/deps/srccache/llvm-11.0.0/include/llvm/Support/CommandLine.h:851
#​5 0x00007ffff0a83884 in llvm::RegisterPassParser<llvm::RegisterRegAlloc>::NotifyAdd (this=0x7ffff72fce60 <RegAlloc+160>, N=...,
C=0x7fffa6d8ff40 <llvm::createBasicRegisterAllocator()>, D=...)
at /home/vchuravy/src/julia/deps/srccache/llvm-11.0.0/include/llvm/CodeGen/MachinePassRegistry.h:162
#​6 0x00007fffa67b9bb9 in llvm::MachinePassRegistry<llvm::FunctionPass* (*)()>::Add (Node=0x7fffab14a900 <basicRegAlloc>,
this=0x7fffab14a8e0 <llvm::RegisterRegAllocBase<llvm::RegisterRegAlloc>::Registry>) at ../include/llvm/CodeGen/MachinePassRegistry.h:110
#​7 llvm::RegisterRegAllocBase<llvm::RegisterRegAlloc>::RegisterRegAllocBase (
C=0x7fffa6d8ff40 <llvm::createBasicRegisterAllocator()>,
D=0x7fffa91c73b8 "basic register allocator", N=0x7fffa91c73b2 "basic",
--Type <RET> for more, q to quit, c to continue without paging--
this=0x7fffab14a900 <basicRegAlloc>)
at ../include/llvm/CodeGen/RegAllocRegistry.h:37
#​8 llvm::RegisterRegAlloc::RegisterRegAlloc (
C=0x7fffa6d8ff40 <llvm::createBasicRegisterAllocator()>,
D=0x7fffa91c73b8 "basic register allocator", N=0x7fffa91c73b2 "basic",
this=0x7fffab14a900 <basicRegAlloc>)
at ../include/llvm/CodeGen/RegAllocRegistry.h:63
#​9 __static_initialization_and_destruction_0 (__initialize_p=1,
__priority=65535) at ../lib/CodeGen/RegAllocBasic.cpp:44
#​10 _GLOBAL__sub_I_RegAllocBasic.cpp(void) ()
at ../lib/CodeGen/RegAllocBasic.cpp:333
#​11 0x00007ffff7fe12de in call_init.part () from /lib64/ld-linux-x86-64.so.2
#​12 0x00007ffff7fe13c8 in _dl_init () from /lib64/ld-linux-x86-64.so.2
#​13 0x00007ffff7ed80e5 in _dl_catch_exception () from /usr/lib/libc.so.6
#​14 0x00007ffff7fe5705 in dl_open_worker () from /lib64/ld-linux-x86-64.so.2
#​15 0x00007ffff7ed8088 in _dl_catch_exception () from /usr/lib/libc.so.6
#​16 0x00007ffff7fe4f3e in _dl_open () from /lib64/ld-linux-x86-64.so.2
#​17 0x00007ffff7f8934c in ?? () from /usr/lib/libdl.so.2
#​18 0x00007ffff7ed8088 in _dl_catch_exception () from /usr/lib/libc.so.6
#​19 0x00007ffff7ed8153 in _dl_catch_error () from /usr/lib/libc.so.6
#​20 0x00007ffff7f89b89 in ?? () from /usr/lib/libdl.so.2
#​21 0x00007ffff7f893d8 in dlopen () from /usr/lib/libdl.so.2
#​22 0x00007fffac9a6b90 in loader_open_driver.constprop ()
--Type <RET> for more, q to quit, c to continue without paging--
from /usr/lib/libGLX_mesa.so.0
#​23 0x00007fffac99cbe0 in dri3_create_screen.lto_priv ()
from /usr/lib/libGLX_mesa.so.0
#​24 0x00007fffac9856e9 in __glXInitialize () from /usr/lib/libGLX_mesa.so.0
In particular I find note-worthy how from the initializer:
#​10 _GLOBAL__sub_I_RegAllocBasic.cpp(void) ()
at ../lib/CodeGen/RegAllocBasic.cpp:333
we meander to:
#​5 0x00007ffff0a83884 in llvm::RegisterPassParser<llvm::RegisterRegAlloc>::NotifyAdd (this=0x7ffff72fce60 <RegAlloc+160>, N=...,
C=0x7fffa6d8ff40 <llvm::createBasicRegisterAllocator()>, D=...)
at /home/vchuravy/src/julia/deps/srccache/llvm-11.0.0/include/llvm/CodeGen/MachinePassRegistry.h:162
Now I am unclear on how the wires get crossed here by the dynamic linker. My assumption is this has to do with static variables, and perhaps those get merged across the libraries?
Working with that hypothesis I added a prefix to the static variables used by ManagedStatic and that got me further, but while writing this up I am unsure if that is a sufficient fix. I am baffled byt the behaviour since these static variables are not exported ...
Thinking about this more an looking at the particular global variable: llvm::RegisterRegAllocBase<llvm::RegisterRegAlloc>::Registry
nm -D /usr/lib/libLLVM-11.0.0.so | ~/builds/julia/usr/tools/llvm-cxxfilt | grep "llvm::RegisterRegAlloc"
00000000052188e0 u llvm::RegisterRegAllocBase<llvm::RegisterRegAlloc>::Registry@@LLVM_11
0000000005142ec0 V typeinfo for llvm::RegisterPassParser<llvm::RegisterRegAlloc>@@LLVM_11
0000000005142f60 V typeinfo for llvm::cl::opt<llvm::FunctionPass* (*)(), false, llvm::RegisterPassParser<llvm::RegisterRegAlloc> >::Callback::'lambda'(llvm::FunctionPass* (* const&)())@@LLVM_11
0000000005142ef8 V typeinfo for llvm::cl::opt<llvm::FunctionPass* (*)(), false, llvm::RegisterPassParser<llvm::RegisterRegAlloc> >@@LLVM_11
000000000329e4c0 V typeinfo name for llvm::RegisterPassParser<llvm::RegisterRegAlloc>@@LLVM_11
000000000329e680 V typeinfo name for llvm::cl::opt<llvm::FunctionPass* (*)(), false, llvm::RegisterPassParser<llvm::RegisterRegAlloc> >::Callback::'lambda'(llvm::FunctionPass* (* const&)())@@LLVM_11
000000000329e500 V typeinfo name for llvm::cl::opt<llvm::FunctionPass* (*)(), false, llvm::RegisterPassParser<llvm::RegisterRegAlloc> >@@LLVM_11
00000000051434b8 V vtable for llvm::RegisterPassParser<llvm::RegisterRegAlloc>@@LLVM_11
0000000005143540 V vtable for llvm::cl::opt<llvm::FunctionPass* (*)(), false, llvm::RegisterPassParser<llvm::RegisterRegAlloc> >@@LLVM_11
To quote the nm man page:
"u" The symbol is a unique global symbol. This is a GNU extension
to the standard set of ELF symbol bindings. For such a symbol
the dynamic linker will make sure that in the entire process
there is just one symbol with this name and type in use.
So I would assume that issue might be that the dynamic linker ignores the symbol version.
The text was updated successfully, but these errors were encountered:
Hi @vchuravy ,
I met the same issue.
I have two libraries both linked with the static llvm libraries. And they both have the same symbol name for the static global singleton registry. 000000000b89c490 u llvm::RegisterRegAllocBase<llvm::RegisterRegAlloc>::Registry
And I got the same error as you.
Can you explain more detail about the suggested solution?
Extended Description
Since many projects depend on LLVM, we recommend that distributions and downstream user use symbol versioning to avoid conflicts between multiple LLVM versions being loaded into the same process.
On Linux mesa implementations (OpenGL/OpenCL) use LLVM extensively and they are generally built against the system LLVM. On the other hand front-ends like Julia might want to use a version of LLVM that diverges from the system LLVM.
What we have observed happening for several years is that users will get errors like:
Or segmentation faults:
What this boils down to is that despite symbol versioning wires get crossed and the state of the two loaded LLVM version aliases each other.
After I building mesa, my system LLVM and Julia's LLVM with debuginformation I get the following interesting backtrace:
In particular I find note-worthy how from the initializer:
we meander to:
Now I am unclear on how the wires get crossed here by the dynamic linker. My assumption is this has to do with static variables, and perhaps those get merged across the libraries?
Working with that hypothesis I added a prefix to the static variables used by ManagedStatic and that got me further, but while writing this up I am unsure if that is a sufficient fix. I am baffled byt the behaviour since these static variables are not exported ...
Thinking about this more an looking at the particular global variable:
llvm::RegisterRegAllocBase<llvm::RegisterRegAlloc>::Registry
To quote the
nm
man page:So I would assume that issue might be that the dynamic linker ignores the symbol version.
The text was updated successfully, but these errors were encountered: