[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