[PATCH] dlfcn: Fix dlclose crash during C++ thread_local destructor (BZ 33598)
Arjun Shankar
arjun@redhat.com
Wed Dec 10 11:30:57 GMT 2025
Hi Adhemerval,
It looks like this won't work if the library getting unmapped doesn't
directly call dlclose, and instead there's a level of indirection,
like so:
cat <<EOF > main.c
#include <dlfcn.h>
#include <assert.h>
int main()
{
void *h = dlopen("lib1.so", RTLD_NOW); assert(h);
dlclose(h);
return 0;
}
EOF
cat <<EOF > lib1.cc
#include <dlfcn.h>
#include <assert.h>
#include <memory>
thread_local std::unique_ptr<int> tlp;
static struct c1 {
void *h;
void (*init)(void);
void (*cleanup)(void);
c1() {
h = dlopen("lib2.so", RTLD_NOW); assert(h);
init = (void (*)(void)) dlsym(h, "init"); assert(init);
cleanup = (void (*)(void)) dlsym(h, "cleanup"); assert(cleanup);
init();
tlp = std::make_unique<int>();
}
~c1() { cleanup(); dlclose(h); }
} c1;
EOF
cat <<EOF > lib2.c
#include <dlfcn.h>
#include <assert.h>
static void *h;
void init(void) { h = dlopen("libm.so.6", RTLD_NOW); assert(h); }
void cleanup(void) { dlclose(h); }
EOF
gcc -Wall -g -fPIC -shared -o lib2.so lib2.c -ldl
g++ -Wall -g -fPIC -shared -o lib1.so lib1.cc -ldl
gcc -Wall -g -fPIC -o main main.c -ldl
LD_LIBRARY_PATH=. ./main
Can this be tackled more generally by deferring or not unmapping
during program exit?
More information about the Libc-alpha
mailing list