If I create a dll that throws and catches exceptions internally, then load it into an application and unload it, the application will crash as soon as a thread exits.
The crash is because __cxa_get_globals() allocates a tls-key that is not freed when the dll is unloaded, so the callback that was set (with FlsAlloc() via __libcpp_tls_create()) now points into non-existing code.
This will happen if the dll is statically linked against libc++ or if the main application does not use libc++. If both the main app and the dll are dynamically linked I guess it will not happen.
As a workaround I made a function __libcpp_tls_destroy() that is registered with atexit() when the tls-key is created in libcxxabi/src/cxa_exception_storage.cpp.
I was going to propose a patch, but I don’t know if it is ok to use atexit() like this, and there are probably ABI-concerns.
I think there may be a similar problem with the tls-key in __thread_specific_ptr, but since this destructor is inlined I guess there could be an ABI break to add a dependency on a cleanup function there?