Bug 15976 – explicite TLS initializes badly in DLLs if other threads exist

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
druntime
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2016-05-01T09:32:00Z
Last change time
2016-10-01T11:44:46Z
Assigned to
nobody
Creator
r.sagitario

Comments

Comment #0 by r.sagitario — 2016-05-01T09:32:51Z
This happened for intermediate versions of druntime that used explicite TLS to save the thread pointer: This is the DLL code: ///////////////////////////////////////////// module exptls; import core.sys.windows.windows; import core.sys.windows.dll; import core.stdc.stdio; mixin SimpleDllMain; __gshared DWORD tlsSlot; int tlsVar; shared static this() { tlsSlot = TlsAlloc(); printf("TlsAlloc() = %d\n", tlsSlot); } static this() { printf("TlsSetValue(%d, &var = %p\n", tlsSlot, &tlsVar); TlsSetValue(tlsSlot, &tlsVar); } And the executable: //////////////////////////////////////////////////// module main; import core.sys.windows.windows; import core.thread; import core.time; alias fnType = void function(); __gshared fnType pFn; void test() { Thread.sleep(2.seconds); assert(pFn); pFn(); } void main() { Thread t1 = new Thread(&test); t1.start(); Thread.sleep(1.seconds); HANDLE h = LoadLibrary("exptls.dll"); pFn = cast(fnType) GetProcAddress(h, "verifyTls"); assert(pFn); pFn(); t1.join(); } extern(C) export void verifyTls() { printf("TlsGetValue() = %x, &var = %x\n", TlsGetValue(tlsSlot), &tlsVar); assert(TlsGetValue(tlsSlot) == &tlsVar); } Compile with: dmd -ofexptls.dll exptls.d -m64 -L/DLL dmd main.d -m64 Running produces output similar to: TlsAlloc() = 26 TlsSetValue(26, &var = 0000005FF88E3B50 TlsSetValue(26, &var = 0000005FF88F36B0 TlsGetValue() = f88f36b0, &var = f88e3b50 and the process crashes (due to the assert exception from DLL not being handled).
Comment #1 by r.sagitario — 2016-05-01T09:34:06Z
This happens because the "impersonation" of existing threads during DLL startup does not swap explicit TLS values, only implicit.
Comment #2 by github-bugzilla — 2016-05-05T22:00:17Z
Commits pushed to master at https://github.com/dlang/druntime https://github.com/dlang/druntime/commit/998c0fc455c959bfb55c1a26ef8b9599622bc457 fix issue 15976: swap out explicit TLS values during impersonating thread https://github.com/dlang/druntime/commit/c7ddfef05d0d6ed564aecd2e6a51b6e6a93f689a Merge pull request #1556 from rainers/explicit_tls fix issue 15976: swap out explicit TLS values during impersonating thread
Comment #3 by github-bugzilla — 2016-10-01T11:44:46Z
Commits pushed to stable at https://github.com/dlang/druntime https://github.com/dlang/druntime/commit/998c0fc455c959bfb55c1a26ef8b9599622bc457 fix issue 15976: swap out explicit TLS values during impersonating thread https://github.com/dlang/druntime/commit/c7ddfef05d0d6ed564aecd2e6a51b6e6a93f689a Merge pull request #1556 from rainers/explicit_tls