LoadLibrary 126 returns the error code error cause of the fault

In developing applications under Windows process, often manually loaded some of the DLL, use is LoadLibrarythis function, and this function once failed with error code returned error code 126, 126 basically means specified module can not be found , this does not, I encountered this problem, and very strange, is that the problem is not Debug mode, Release mode shall an error code.

First introduced the issue of environment, an application needs to load a DLL module IoT, this DLL in turn depends on a number of DLL. Experienced old driver or DLL load on this very familiar people should soon know where the problem lies. No hurry, slowly introduced.

-- core.exe
  |--module
    |--iot.dll
    |--mqtt.dll

Directory is a view shown above, core.exewill be LoadLibrarya directory moduleunder iot.dll, and iot.dllin turn is dependent mqtt.dll.

At that time I did not realize IoT this DLL is also dependent on the other DLL This is a key point,

So my first step to troubleshoot the problem, since it can not find the specified module, then take a look at the corresponding position in the end there iot.dll, unfortunately, there is!

The second step, since the performance of the Debug and Release is not the same, you would not want yes iot.dllsome of compiling and linking options is not the same in both modes DLL cause a problem? So you use Debug to Release mode manually modified to compile, or not, still returns an error code 126.

The third step, since their existing knowledge in order to get it working, then it can only help Google, the search for a wave of " LoadLibrary 126 Release error ", others did not see this problem appeared in Release, but rather check out, error code 126 appears generally depends DLL DLL is not found, this problem occurs. This time realized iot.dllalso relied mqtt.dll, then went to a confirmed case mqtt.dll, there is found the corresponding position DLL. This is a completely senseless.

The fourth step in stackoverflow have a big God on https://stackoverflow.com/questions/14361992/dll-load-library-error-code-126 gives a method of analysis, probably means my translation:

Windows dll error code 126 for many reasons, the most useful debugging programs are as follows:

The fifth step, first with the first tool Dependency Walker are looked at under Debug and Release iot.dll, useless to find the DLL is optimized out in the Release, still did not see the problem. But all dependent DLL exists in the corresponding position, which still does not solve the problem.

The sixth step, no way, can only use Process Monitor, and I have not used this before, simply looked familiar at it, find it and under the Linux stracesystem call command like, are running and follow-up procedures behavior, and finally I saw the following things:

Here Insert Picture Description

It can be seen iot.dllalready LoadImage, but it's dependent DLL mqtt.dllcould not find, and can be seen in the Windows LoadLibrarysearch path when, as follows:

  • Program directory, the directory is exe
  • System Directory
  • Windows directory
  • Process current directory
  • PATH environment variable directory

By comparison, my position DLL is located, not inside any of these above, therefore, reported a 126 error code is very reasonable.

The solution is very simple, in accordance with the copy of the first order dependence of the DLL is loaded mqtt.dllinto the program directory on the line.

-- core.exe
  |--module
    |--iot.dll
    |--mqtt.dll
  |--mqtt.dll

Of course, you can SetCurrentDirectoryto achieve the purpose of changing the current process successfully load the DLL directory, but do not forget to pass GetCurrentDirectorythe current directory to restore back; a function SetDllDirectoryis designed to specify the DLL search path, and this better if used this function, then the DLL load order will be a little different, as follows:

  • Process current directory
  • SetDllDirectorySpecified directory
  • System Directory
  • Windows directory
  • Process current directory
  • PATH environment variable directory

After setting this, you will not find in the program directory of the DLL search, but will process the current directory as the first order. So, if your application below DLL with the same name, this DLL is not what you want, you must use SetDllDirectorythis function up.

其实微软已经给我们提供了更好的方式,LoadLibrary有一个扩展函数LoadLibraryEx [https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw],里面有个参数LOAD_WITH_ALTERED_SEARCH_PATH,可以让DLL的搜索路径从DLL所在目录开始,这个同样可以使用Process Monitor去观察其行为。那么这个扩展函数和不扩展的有啥区别呢?下面是我摘抄的一段:

The LoadLibraryEx function is very similar to the LoadLibrary function. The differences consist of a set of optional behaviors that LoadLibraryEx provides:

  • LoadLibraryEx can load a DLL module without calling the DllMain function of the DLL.
  • LoadLibraryEx can load a module in a way that is optimized for the case where the module will never be executed, loading the module as if it were a data file.
  • LoadLibraryEx can find modules and their associated modules by using either of two search strategies or it can search a process-specific set of directories.

Set up SetDllDirectory, LoadLibraryand LoadLibraryExthe search algorithm used is the same, that I've seen through the Process Monitor.


To sum up, this is actually a very common sense questions, pay attention to the position-dependent DLL when the DLL is loaded with a dependent, but prior knowledge of this part of their own blind spots, resulting in open thinking. If I had known DLL search path, the problem would not be so long investigation, however, in the course of the investigation in question, we learned a lot, including the use of new tools, but also a profound understanding of some of the things a lot, but also found a blind spot of knowledge, know they do not know.

Published 299 original articles · won praise 353 · Views 450,000 +

Guess you like

Origin blog.csdn.net/FlushHip/article/details/96167157