Skip to content

Error 126 while loading DLL compiled by Rust (as a cdylib) on Windows #69207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
silverweed opened this issue Feb 16, 2020 · 6 comments
Closed

Comments

@silverweed
Copy link

silverweed commented Feb 16, 2020

Note: looks very similar to #33842, but I'm opening a new issue since that is closed and old.

Basically I'm having the same issue here. This is my project which has 3 crates: one static lib, one dynamic lib (cdylib) and an executable.
The dynamic lib (ecs_game) depends on the static lib (ecs_engine) and gets compiled into a single DLL. The executable (ecs_runner) then loads the DLL dynamically (I'm using the libloading crate for that).
Here is what happens:

  • on Linux/Mac, the lib gets loaded just fine
  • on an old (pre-anniversary update) Windows, it gets loaded just fine
  • on newer Windows installations, it fails with error 126.

I also tried to create a small C program that uses LoadLibraryA directly to load the library and it gives the same exact error.
Am I doing something wrong here?

(this is the C loader:)

#include <windows.h>
#include <stdio.h>

int main() {
	HMODULE lib = LoadLibraryA("ecsde/target/release/ecs_game.dll");
	if (lib) {
		printf("Hurray!\n");
	} else {
		DWORD last_err = GetLastError();
		printf("Failed to load. Last err = %d\n", last_err);
	}
}

Note that if I link the DLL at link-time, it works fine. It's just dynamic loading that gives problems.

@silverweed silverweed changed the title Error 126 while loading DLL on Windows Error 126 while loading DLL compiled by Rust (as a cdylib) on Windows Feb 16, 2020
@retep998
Copy link
Member

Error 126 for reference is ERROR_MOD_NOT_FOUND.

Are you certain that you build and run the program in the same exact way between older and newer Windows? The slightest difference can easily cause this.

@silverweed
Copy link
Author

silverweed commented Feb 16, 2020

@retep998 I just found out that on my older Windows it only succeeds if I run the program with cargo run: launching the executable directly (e.g. from powershell or git bash) yields the same error 126.

EDIT: apparently there is a difference between a freshly-compiled cdylib and my ecs_game.dll compiled as-is in debug mode:

$ ldd freshly_compiled.dll
        ntdll.dll => /c/Windows/SYSTEM32/ntdll.dll (0x7ffa639f0000)
        KERNEL32.DLL => /c/Windows/system32/KERNEL32.DLL (0x7ffa62100000)
        KERNELBASE.dll => /c/Windows/system32/KERNELBASE.dll (0x7ffa60160000)
        ucrtbase.dll => /c/Windows/SYSTEM32/ucrtbase.dll (0x7ffa5f1b0000)
        VCRUNTIME140.dll => /c/Windows/SYSTEM32/VCRUNTIME140.dll (0x7ffa568e0000)
        ??? => ??? (0xcd0000)

vs

$ ldd target/debug/ecs_game.dll
        ntdll.dll => /c/Windows/SYSTEM32/ntdll.dll (0x7ffa639f0000)
        KERNEL32.DLL => /c/Windows/system32/KERNEL32.DLL (0x7ffa62100000)
        KERNELBASE.dll => /c/Windows/system32/KERNELBASE.dll (0x7ffa60160000)
        ??? => ??? (0x7ffa27ff0000)
        ??? => ??? (0x7ffa61270000)
        ??? => ??? (0x7ffa61320000)
        ??? => ??? (0x7ffa60df0000)
        ??? => ??? (0x7ffa60e50000)
        ??? => ??? (0x7ffa568e0000)

most notably, VCRUNTIME140.dll is not there in ecs_game.dll.

@retep998
Copy link
Member

Why are there so many ??? in that output? Is ldd just really bad?

If you have VC++ I recommend doing dumpbin /dependents foo.dll to get DLL dependencies.

My current guess is that you're depending on some C library being provided by one of the crates you depend on, and it succeeds when you run it in a way such that it can be found and it fails otherwise. cargo run succeeding whereas running the executable directly failing is the biggest tip off.

@silverweed
Copy link
Author

silverweed commented Feb 17, 2020

Thanks for the help you're giving. I'm a windows newbie, so I am quite disoriented when it comes to troubleshooting this kind of stuff there :S
I ran the command and this is the output (on the older install):

Microsoft (R) COFF/PE Dumper Version 14.16.27025.1
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file ecs_game.dll

File Type: DLL

  Image has the following dependencies:

    csfml-graphics-2.dll
    csfml-audio-2.dll
    csfml-window-2.dll
    KERNEL32.dll
    ADVAPI32.dll
    VCRUNTIME140.dll
    api-ms-win-crt-math-l1-1-0.dll
    api-ms-win-crt-string-l1-1-0.dll
    api-ms-win-crt-runtime-l1-1-0.dll
    api-ms-win-crt-heap-l1-1-0.dll

  Summary

        1000 .data
       30000 .pdata
       6B000 .rdata
        1000 .reloc
      211000 .text

I guess the most likely culprit here are the csfml libs, which are the only non-system ones.

EDIT: running dumpbin on the newer install yields the exact same result.
EDIT2: well, I just found out that if I copy the csfml DLLs in my project root directory, suddenly it loads just fine. So I guess the problem was windows failing to find the dependent libraries when calling LoadLibrary. So...thanks windows for giving good error messages?

@fzyzcjy
Copy link

fzyzcjy commented Mar 5, 2022

@silverweed Hi, I am having the same problem. How did you solve it? Thanks!

@silverweed
Copy link
Author

silverweed commented Mar 6, 2022

@fzyzcjy Hello, I just copied the DLLs that my dynamically loaded lib depended on in the executable directory so it could find them when calling LoadLibrary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants