Whenever a thread_local object is accessed from different threads one instance of this object will be created for each threads. As soon as thread exits the object must be destructed. UNFORTUNATELY THIS CALL TO THE DESTRUCTOR FOR COMMON STL CONTAINERS IS CRASHING THE PROGRAM!
I have tried different versions of mingw-w64 ( ver : (i686-posix-dwarf-rev1, Built by MinGW-W64 project) 4.9.2) as well as TDM GCC 4.9.2 but still its crashing.
Below is the program to reproduce the problem.
' #include <thread></thread>
using namespace std;
thread_local string s("Hello");
int main()
{
thread([]
{
s;
}).join();
return 0;
}
'
which works fine in ideone,
http://ideone.com/H8aGwJ
This is effecting me as well, in fact it is impossible to declare a variable with a destructor as thread_local without a getting a segfault. Tested with x86_64-6.3.0-win32-seh-rt_v5-rev2 and x86_64-5.4.0-win32-seh-rt_v5-rev0. A simplified test case is:
Which will segfault on program exit. There is a workaround, which is to link to the static runtime libraries, so this looks like an order-of-destruction issue.
I ran into this while tracking down an issue in the Boost.Multiprecision library, and this is a bit of a showstopper for us, as it prevents me from making our library thread safe under mingw.
For mingw-w64 x86_64-6.3.0-posix-seh-rt_v5-rev2 both of test cases above were built and run successfully (i.e.
%ERRORLEVEL%== 0).For mingw-w64 x86_64-6.3.0-win32-seh-rt_v5-rev2 first test case throw error during build, second finished with segfault.
Last edit: sav 2017-09-04
I'm having the same issue with mingw gcc 7.2 win32 both posix and win threads. In fact any thread_local class with destructor throws segmentation fault on destructor call. value of "this" pointer seems to be corrupt.
Both code compile and run successfully with GCC 7.1.0 and 7.2.0 x86_64-posix-seh from https://sourceforge.net/projects/mingw-w64/files/
C++ std::thread and related features currently not supported in win32 thread model.
true, it does compile and run successfully wih x86_64-posix-seh, but i686-posix sjlj or dwarf produces segmentation fault. I have attached my test file
To be more presize, not supported in mingw-w64 win32 thread model implementation. Since both tests above could be successfully built using MSVC 2017 and "ICC 2018 on Windows", and run without errors.
The original problem is caused by GCC. If emutls is in effect (this is true for mingw-w64), or the
thread_localobject block scope in question has block scope instead of namespace scope, GCC emits a call to the__cxa_thread_atexit()function after successful construction of it. This function, as its name suggests, is similar toatexit()and takes a pointer to a function using the __cdecl calling convention, where the first argument is pushed onto stack. Unfortunately on x86 destructors use the __thiscall convention, where the implicitthisparameter is to be passed via the ECX register. The inconsistency of calling conventions inside the dtor merely results in ECX having whatever garbage values that happen to reside in it. x86_64 is not suffering from this problem because there is only one calling convention - the __fastcall calling convention,Last edit: LIU Hao 2017-12-22
The issue discovered by @johnmaddock is another one.
Compiling and running the attached program yields the following result:
Notice the last four lines about how destruction of
staticandthread_localobjects are sequenced. The behavior here violates the standard, as the standard mandates the behavior as follows:Last edit: LIU Hao 2017-12-22
I filed a PR to GCC about the original program: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562