Handmade Hero»Forums»Code
6 posts
Crazy LoadLibrary() bug?

I've been programming hot code reloading into a project of mine in a simlar way that Casey does in Handmade Hero and I've come across some crazy behaviour that I can't explain...

Essentially I have run into a case where the call to LoadLibrary fails with

ERROR_DLL_INIT_FAILED
    1114 (0x45A)
    A dynamic link library (DLL) initialization routine failed.

This happens if I simply comment out a specific function call in the DLL codebase. Additionally, adding a dummy variable declaration fixes the problem!?

I am very confused...

Video demo

Simon Anciaux
1337 posts
Crazy LoadLibrary() bug?

Did you try loading the dll in an empty application with just the LoadLibrary call to see if it works ?

Could you share a minimal reproduction case or the full code ?

Mārtiņš Možeiko
2559 posts / 2 projects
Crazy LoadLibrary() bug?

Do you have lockfile implemented like in HH? If not, then most likely what is happening is that linker starts creating new dll file and your hot reload code notices that new file is there and tries to reload it, but linking process is still in progress - it has not finished to fully produce dll file. So loading it will fail, because partially written dll file has incorrect format. You can easily test this by adding something like Sleep(2000) before LoadLibrary call. If that success, then this is the case.

6 posts
Crazy LoadLibrary() bug?
Replying to mrmixer (#25591)

Yeah even trying to load the dll in an empty application doesn't work. Here's some test code that just tries to get a handle to the dll with LoadLibrary and that's it. It fails for me but if I uncomment line 326 in modaw.cpp and then recompile it will load successfully. Curiously also just deleting any random code you like in modaw.cpp seems to have the same effect.

LoadLibraryBug.zip

6 posts
Crazy LoadLibrary() bug?
Replying to mmozeiko (#25598)

I don't think this is the case because I'm not even trying to recompile the dll while the program is running. It just wont even load the dll on startup.

Mārtiņš Možeiko
2559 posts / 2 projects
Crazy LoadLibrary() bug?
Edited by Mārtiņš Možeiko on
Replying to RobinLeathart (#25600)

This happens because you did not implement DllMainCRTStartup function properly. It must return TRUE for dll loading to succeed. You are not returning anything, so random garbage is returned (whatever value is in rax register) - most likely 0. And 0 is FALSE which signals OS that dll initialization failed and it must unload it.

For more information what this function must do (and what is its proper signature) is here: https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain

image.png

6 posts
Crazy LoadLibrary() bug?
Edited by RobinLeathart on
Replying to mmozeiko (#25602)

Ah amazing, thank you! Is the prototype for DllMainCRTStartup identical to DllMain? i.e. I should have something like this?

extern "C" int
_DllMainCRTStartup(HINSTANCE Instance, DWORD Reason, LPVOID Reserved)
{
  switch(Reason) 
  { 
    case DLL_PROCESS_ATTACH:
    {
    } break;

    case DLL_THREAD_ATTACH:
    {
    } break;

    case DLL_THREAD_DETACH:
    {
    } break;

    case DLL_PROCESS_DETACH:
    {
    } break;
  }
  return TRUE;
}


Mārtiņš Možeiko
2559 posts / 2 projects
Crazy LoadLibrary() bug?
Replying to RobinLeathart (#25606)

Yes, that's correct. Add WINAPI in case you want to have code compatible win 32-bit code. No need for those switch statements if you don't need to do different things based on process/thread start/end.