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.