-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
Hello,
I posted this issue on the gcc bug tracker, but I am not entirely sure if this is supposed to be a GCC bug or a mingw bug.
I see it has also been reported here, however at the moment I can not create a sourceforge account to comment on that. I apologize if this is not the proper place.
The issue here, to my best understanding, is the following.
-
At the very first access of a thread-local object in a new program,
emutls_init
is called via__emutls_get_address
. This function allocates some memory for the storage usingmalloc
(seeemutls_alloc
), and registersemutls_destroy
to be executed at thread exit, using__gthread_key_create
. -
Immediately after, the
TLS init function
(generated by GCC) is called. This calls the C++ constructor on the storage provided at the previous point. It also uses__gthread_key_create
to register the C++ destructor for execution at thread exit. -
When a thread terminates,
_pthread_cleanup_dest
in winpthread is called. This function is responsible for calling all the destructors registered withpthread_key_create
. Unfortunately, the execution order of such destructors is unspecified. In this case, it happens thatemutls_destroy
is called before the C++ destructor, which then executes on deallocated memory.
A quick workaround would be to reverse the loop in winpthread/src/thread.c:842. This will cause the destructors to be called in reverse order, and it will probably work correctly in most of the cases.
The only other solution would be to merge emutls+TLS init on GCC side, in such a way to have a single destructor callback to both invoke the C++ destructor and cleanup the memory.