Hasty Briefsbeta

Why did dlclose not unload the library? (2023)

15 days ago
  • #dlclose
  • #dynamic-linking
  • #debugging
  • dlclose may not unload a library due to several conditions, including reference count > 1, NODELETE flag, or pending thread local storage (TLS) destructors.
  • In the debugging scenario, libA (Rust) was unloaded, but libB (C++) was not, due to pending TLS destructors registered by libB.
  • The NODELETE flag can be set in the ELF binary or via dlopen flags, and symbols marked as STB_GNU_UNIQUE (common in libstdc++.so) also trigger this flag.
  • Enabling logging (env_logger) in libA caused it to register TLS destructors, preventing its unloading and thus keeping libB's state consistent.
  • Use LD_DEBUG to debug dynamic loader behavior, though it doesn't show pending TLS destructors—breakpoints in _dlclose are needed for that.