Reputation: 87250
Consider the following loop
while (true) {
void* lib = dlopen("bin/liblibrary.so", RTLD_NOW | RTLD_LOCAL);
assert(lib);
typedef void (*f_t)(void);
f_t f = (f_t)dlsym(lib, "foo");
assert(f);
f();
int res = dlclose(lib);
assert(!res);
}
And a library that contains a simple function
extern "C" void foo() {
printf("hello from foo\n");
}
This reloads the dynamic library on every iteration, or at least it should.
Compiling this on Linux (Arch) with clang 17.0.6 works as expected, and changing and recompiling the library makes the main binary run the new code.
But compiling with the same flags with GCC 14.1.1 does not work, and even when the library is reloaded it keeps calling the old code.
Compiling main with just clang++ main.cpp -o main
and library with clang++ -shared -fPIC -o liblibrary.so library.cpp
, and with GCC the same flags, except g++
instead of clang++
.
edit: further testing, when I add an an __attribute__((destructor))
it does not get called with gCC, but it does get called with Clang, e.g.
__attribute__((constructor)) void init_library() {
printf("Library loaded\n");
}
__attribute__((destructor)) void cleanup_library() {
printf("Library unloaded\n");
}
Upvotes: 0
Views: 142
Reputation: 87250
It seems the problem in this case was not actually in the example code, which was initially incorrect (using assert(!dlclose(lib))
), but that was unfortunately only a problem in the example code and not in my actual code.
This did lead me down to another thread which hinted at --no-gnu-unique
, which seems to be the flag that makes GCC actually unload the library.
Upvotes: 2