问题
I'm using dlopen to load dynamically generated code. The program calls the compiler on the code and generates a .so file which is then loaded by the program to extend itself.
The problem is that if I use the same name for the generated code, the dlopen returns a handle to the old object, not the new one.
The code looks like:
…generate code into test.cpp
system("gcc <args> test.cpp -o test.so");
void *handle = dlopen("test.so");
void *sym = dlsym(handle, "run");
(*sym)();
dlclose(handle);
…Do other work
…generate different code to test.cpp
system("gcc <args> test.cpp -o test.so");
void *handle = dlopen("test.so");
void *sym = dlsym(handle, "run");
(*sym)();
<crash here because the code isn't what was expected>
Is this a basic flaw in dlopen
's cache code or something well known and not well documented in dlopen
?
回答1:
Most probly dlclose
failed to unload the library. This usually happens when it contains GNU_UNIQUE symbols (which tend to sneak in if you link with static libstdc++). This can be verified via
$ readelf -sW --dyn-syms path/to/libxyz.so | grep '\bUNIQUE\b'
...
3808: 0000000000302e78 8 OBJECT UNIQUE DEFAULT 27 _ZNSt8messagesIcE2idE@@GLIBCXX_3.4
To fix this, you can try one of the following:
- build library with
-fvisibility=hidden
and__attribute__((visibility("default")))
to hide unique symbols - build with
-Wl,--version-script
to achieve the same - build shlib with toolchain that was configured with
--disable-gnu-unique-object
(see discussion in GCC list)
来源:https://stackoverflow.com/questions/50437892/dlopen-on-new-binary-with-same-name-returns-old-handle