The pthread_key_create() and __nptl_deallocate_tsd() do not track the references to destructor's DSO like the __cxa_thread_atexit_impl(). Therefore the DSO, which holds a destructor's code, could be unloaded before destructor execution or before deleting a corresponding key. So in a complex environment there is no way to know whether it is safe to unload a particular DSO or some tls-destructors are still left. Suggest this should be fixed or documented, e.g. that the pthread_create_key() with a destructor should not be used from lib.so.
Related to bugs 18136, 21031.
Created attachment 13236 [details] Minimal reproduction I've attached a minimal reproduction of the issue (GitHub repository: https://github.com/Aaron1011/pthread_dlopen) It does the following: 1. Spawn a new thread from `main()`, and block on it using `pthread_join` 2. From the new thread, load a simple shared library, and call a function in it. 3. In the shared library, call `pthread_key_create` with a destrutor function, and call `pthread_setspecific` with a non-NULL value to force the destrutor to actually run on thread exit. 4. Back in the main program (on the thread), call `dlclose` on the shared library. 5. Return from the thread function This causes the following segfault: ``` [Current thread is 1 (Thread 0x7facc3ff4640 (LWP 701108))] gef➤ bt #0 0x00007facc4229129 in ?? () #1 0x00007facc41cd411 in __nptl_deallocate_tsd.part.0 () from /usr/lib/libpthread.so.0 #2 0x00007facc41ce2ba in start_thread () from /usr/lib/libpthread.so.0 #3 0x00007facc40f7053 in clone () from /usr/lib/libc.so.6 gef➤ q ```
Not a bug for glibc, but the feature )