C++11 thread_local
Hi, I integrated this great library into our application and we got an error when this application creates a C++11 thread. The callstack starts from last line of MmpUserThreadStart() and ends a thread_local variable reference. The variable is a simple pointer to a structure what is newed before the first usage of the pointer. The program did not use the MMPP api at this early stage just want to create some background threads. Without linking MMPP, no issue w the thread creation. Does the lib MMPP support C++11 thread_local?
Sorry I can't reproduce this problem. The thread_local variable works correctly on my simple test program. Can you provide a code snippet that causes this problem?
I integrated MMPP into a larger build, cannot provide a small repro now. There is a.EXE it uses import lib to a b.DLL what links MMPP as a static lib. MMPP lib built crt Debug DLL, /EHa x64. b.DLL (crt debug dll, /EHa, x64) has a thread_local struct WorkData. In the init section inside b.DLL there is a new std::stread(threadWork,...) At the very beginning of the threadWork(), the thread wants to access WorkData but crashes with access violation at 0x0000000000000330 There are 2 treads created before MMPP registers itself, that threads can access WorkData without crashing. After the registration, the first new std::thread has this issue. VS2019
Please answer these questions to help me build the test program:
- Is MMPP linked to a.EXE or b.DLL?
- When is WorkData initialized?
- Is WorkData a structure or a pointer to a structure?
- Is threadWork created by a.EXE or b.DLL?
- MMPP linked to the b.DLL. 2.-3. WorkData is a thread_local struct: thread_local RMTLSDATA g_WorkData; It is automatically initialized in every thread at the 1st reference to it by the CRT (I guess)
b.dll!RMTLSDATA::RMTLSDATA() Line 84 C++ b.dll!`dynamic initializer for 'g_WorkData''() Line 188 C++ [External Code]
- threadWork created by b.DLL
If MMPP is statically linked, how did you create the threadWork thread before initializing MMPP and make it run?
in the b.DLL:
initbDll() { pThreadData = new THREAD_DATA; . . hthreadWork = new std::thread(threadWork, pThreadData); . }
static unsigned __stdcall threadWork(void *lpParam) { // read access violation 0x0000000000000215 <-- always a small number int a = g_WorkData.a; }
// if I do not link MMPP.lib to the b.DLL everything works. // the program calls MMPP api first time later
When MMPP is not initialized, in the 1st worker thread:
00007FF91708A510 push rdi
00007FF91708A512 sub rsp,40h
if (g_pWorkData == NULL)
00007FF91708A516 mov eax,110h
00007FF91708A51B mov eax,eax
00007FF91708A51D mov ecx,dword ptr [_tls_index (07FF9173357C0h)] <--- tls index looks good
00007FF91708A523 mov rdx,qword ptr gs:[58h] <---- rdx looks real address
00007FF91708A52C mov rcx,qword ptr [rdx+rcx*8]
00007FF91708A530 cmp qword ptr [rax+rcx],0
00007FF91708A535 jne GetRmTLSData+85h (07FF91708A595h)
later, MMPP initialized next new thread(worker 2nd thread) --> and at same code, rdx 0
Hi! Could you reproduce the issue?