www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 15976] New: explicite TLS initializes badly in DLLs if other

https://issues.dlang.org/show_bug.cgi?id=15976

          Issue ID: 15976
           Summary: explicite TLS initializes badly in DLLs if other
                    threads exist
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Windows
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: druntime
          Assignee: nobody puremagic.com
          Reporter: r.sagitario gmx.de

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).

--
May 01 2016