LoadLibrary 失败:第一次机会异常 0xC0000139(找不到 DLL)- 如何调试?

5
我有一个名为“mytest.dll”的dll文件,当通过LoadLibrary()加载时,返回NULL(并且作为GetLastError()的值为127)。如果我在“mytest.dll”上使用DependencyWalker,则报告应该正确加载它,并且所有DLL都被正确找到。在主机exe上运行DependencyWalker的分析器选项会在日志中给出以下相关部分:

00:00:55.099: 由线程0xBBC加载“mytest.DLL”,地址为0x07860000。成功挂钩模块。
00:00:55.115: 线程0xBBC在地址0x76E24285处发生了首次机会异常0xC0000139(未找到DLL)。
00:00:55.115: 由线程0xBBC卸载“mytest.DLL”,地址为0x07860000。
00:00:55.115: 线程0xBBC的LoadLibraryW(“mytest.dll”)返回NULL。错误:找不到指定的程序(127)。

有没有一种方法可以调试此问题以查找NTDLL.DLL报告的未找到DLL消息正在寻找什么?还是我应该在其他地方寻找问题的源头?

请注意,从另一个应用程序加载相同的“mytest.DLL”似乎正常工作。


我们的任何答案有帮助解决这个问题吗? - RichieHindle
3个回答

3
使用SysInternals的Process MonitorFileMon可能会让你知道myTest.dll是否就在它被查找的位置。

3

你的应用程序是否在初始加载后(可能)通过GetProcAddress调用特定的DLL函数,但找不到该函数?它是32位还是64位应用程序?

如果像你所说的那样,在另一个应用程序中正确加载,那么它可能有一个正确的入口点。

快速的谷歌搜索表明,你收到的错误代码很可能是由于DLL中缺少函数名称(或特定函数的序数值)。我建议使用Exescope之类的工具打开DLL并检查导出列表。

这也可能解释为什么DLL可以在另一个应用程序中正常工作(也许另一个应用程序使用DLL中不同的导出函数)?


Exescope在解决这个问题上非常有帮助。原来另一个应用程序(及其DLL)是使用不同的编译器编译的,因此命名约定也不同。 "DLL未找到"消息显然是虚假的。 - PeteVasi

2
DependencyWalker可以显示隐式依赖项(由Windows加载器自动处理的依赖项)。使用LoadLibrary加载的DLL是显式依赖项,DependencyWalker无法找到它们(例如,库名称可能从ini文件中读取,而DependencyWalker无法推断出这一点)。
一个DLL在一个应用程序中工作而在另一个应用程序中不工作并不罕见。在最常见的情况下,一个应用程序已经加载了所需的DLL,而另一个应用程序没有。如果DLL不在路径上,则您的DLL将在第一个案例中工作,在第二个案例中则不会工作。
总之,请遵循Michael Burr的建议并使用FileMon。尽管SysInternals网站表示FileMon已过时,但它仍然比ProcMon更容易使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接