4 posts

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
1120 posts

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
2265 posts / 2 projects

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.

4 posts

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.

4 posts

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
2265 posts / 2 projects
Edited by Mārtiņš Možeiko on

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

4 posts
Edited by RobinLeathart on

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;

{
} break;

{
} break;

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


Mārtiņš Možeiko
2265 posts / 2 projects