0

How can I start a thread in DLLMain means std :: thread - fundamentally. No means WinApi, and STL means. When I run the function in the flow, then I crash the application is called from this DLL. Thank you in advance.

This code gets the hash sum on the file (exe) and writes it to a file. (* .txt). But the application crash

void initialize()
{
    string buffer;
    thread t(calclulateHash, ref(buffer));
    t.detach();
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            initialize();
            break;
        }
    }
    return true;
}
continue98
  • 29
  • 4

2 Answers2

3

There are limitations on DllMain().

You shouldn't do any blocking calls in DllMain, because it is called from OS loader. Locking loader may prevent some thread to start and in general leads to bad things. Locking of any kind. If you are trying to acquire a lock that is currently held by a thread that needs OS loader lock (which you are being holding while executed from it), you’ll deadlock in best case scenario. Starting threads isn't allowed, because when you start thread.. you call this DllMain again through OS loader, but with DLL_THREAD_ATTACH parameter now. It leads to the same deadlock or illegal concurrent access to uninitialized memory of this module.

Calls to LoadLibrary/LoadLibraryEx are explicitly prohibited, because that requires OS loader lock. Other calls into kernel32 are fine, you can’t call into User32. And don’t use CRT memory management (unless you are linked statically), anything that calls to dynamic C runtime at all – use HeapAlloc and similar API instead. You'll cause call to SxS runtime library otherwise. You can't read the registry either. Any cross-binary calls are UB, the binary you've called into may not have been initialized or have already been unutilized.

Have a nice day.

Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42
  • So is it possible to use a std::thread in DLLMain how the "magic" way? Or is the only option with CreateThread (windows api) – continue98 Dec 28 '16 at 02:56
  • @user230568 you can't create thread there.. CreateThread is kernel32 , but you can't cause recursion of OS loader. make an exported function which would do that extra initialization, call it from your app, quite a number of API DLLs do that. If required, make so that other functionality of DLL will not work until that call. Or , even better, try emulate singleton that would be created on first call to DLL – Swift - Friday Pie Dec 28 '16 at 02:58
  • std::thread is not magical. Underneath, it uses OS thread support, and so it's also forbidden. – Euro Micelli Dec 28 '16 at 03:23
  • @Euro Micelli I guess, for whoever use that without understanding how it work, it is magical. You know, successfully advanced technology... – Swift - Friday Pie Dec 28 '16 at 07:10
  • 2
    @Swift See [Does creating a thread from DllMain deadlock or doesn’t it?](https://blogs.msdn.microsoft.com/oldnewthing/20070904-00/?p=25283). Calling `CreateThread()` by itself in `DllMain()` is safe (just not recommended), but waiting on a thread is not safe. As long as `DllMain()` exits after calling `CreateThread()`, no deadlock will occur. – Remy Lebeau Dec 28 '16 at 16:42
  • @Remy Lebeau CreateThread() serializes creation of thread but not creates it directly, and yes that doesn't happen until DllMain doesn't exits. same with most of user32 call, file system or registry interaction. in general, one should never do blocking calls(wait for anything) inside DllMain. Crash he experiences, I suppose, happens within thread though, it's mist likely either thread class that failed to wait for creation or FILE* interaction functions or _dup() which throw exceptions in case of failure. the problem is , he cannot use CreateThread, because of CRT. – Swift - Friday Pie Dec 29 '16 at 05:44
  • No, sorry, that's completely misunderstood and misrepresented. Launching a thread by calling `CreateThread` is perfectly safe from `DllMain`. And it doesn't matter, what that thread does either. It won't run until `DllMain` runs to completion. – IInspectable Jan 01 '17 at 20:53
  • According to Microsoft's documentation, you can call CreateThread provided there's no synchronization with the current thread: https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices – Benj Feb 23 '21 at 14:49
0

1 DllMain -> 2 New thread -> 3 call DllMain again with DLL_THREAD_ATTACH -> 4 without check, so New thread again -> 5 call DllMain again with DLL_THREAD_ATTACH; just like step 3;