Within winpthreads, a native posix thread is a thread that has been created via pthread_create.
Previously, pthread key destructors were executed immediately when the thread exits, for native posix threads. For non-posix native threads (i.e. threads created via some other API than pthreads), the pthread key destructors were executed later, via the __dyn_tls_pthread callback. When a thread has got TLS objects, where the TLS implementation is provided via emutls (compiled with the GCC posix thread model, which uses winpthreads), the memory for those TLS objects is allocated via emutls and gets deallocated via a pthread key destructor. When the destructors of the TLS objects are executed via mingw-w64-crt's __cxa_thread_atexit, those destructors are executed via a TLS callback, after the point when emutls has deallocated their storage memory. To fix this, don't run the pthread key destructors immediately, but later via the __dyn_tls_pthread callback, just like for non-posix native threads. This makes sure the memory for the TLS objects isn't freed at the time when the destructors are executed. See also: https://bugreports.qt.io/browse/QTBUG-131476 --- To repro and analyze the situation, apply https://github.com/mstorsjo/mingw-w64/commit/tls-winpthreads-log on mingw-w64, and https://github.com/mstorsjo/gcc/commit/log-emutls-thread-atexit on gcc, and compile https://martin.st/temp/tls-dtor.cpp. Unfortunately, this isn't enough to fix all cases of this issue. This patch fixes the case when winpthreads is statically linked into the same executable as the user code destructors. If they reside in a separate DLL, the winpthreads TLS callback executes before the main executable TLS callbacks, so the emutls memory still is freed before running the destructors. Also for the case of having them statically linked, I guess there's no guarantee about the order of the TLS callbacks between mingw-w64-crt tls_atexit.c and winpthreads. --- mingw-w64-libraries/winpthreads/src/thread.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mingw-w64-libraries/winpthreads/src/thread.c b/mingw-w64-libraries/winpthreads/src/thread.c index 68858cfa6..3535797e3 100644 --- a/mingw-w64-libraries/winpthreads/src/thread.c +++ b/mingw-w64-libraries/winpthreads/src/thread.c @@ -456,9 +456,10 @@ __dyn_tls_pthread (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { if (_pthread_tls != 0xffffffff) t = (_pthread_v *)TlsGetValue(_pthread_tls); + if (t) + _pthread_cleanup_dest (t->x); if (t && t->thread_noposix != 0) { - _pthread_cleanup_dest (t->x); if (t->h != NULL) { CloseHandle (t->h); @@ -1566,8 +1567,6 @@ pthread_create_wrapper (void *args) #endif pthread_mutex_lock (&mtx_pthr_locked); tv->ret_arg = (void*) trslt; - /* Clean up destructors */ - _pthread_cleanup_dest(tv->x); } else pthread_mutex_lock (&mtx_pthr_locked); -- 2.43.0 _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public