LoadLibrary 失败:第一次机会异常 0xC0000139(未找到 DLL)- 如何调试?
我有一个 dll“mytest.dll”,当通过 LoadLibrary() 加载时,返回 NULL(以及 127 作为 GetLastError()
)。 如果我在“mytest.dll”上使用 DependencyWalker,它会报告它应该正确加载并且所有 DLL 都已正确找到。 在主机 exe 上运行 DependencyWalker 的探查器选项会在日志中提供此相关部分:
00:00:55.099: Loaded "mytest.DLL" at address 0x07860000 by thread 0xBBC. Successfully hooked module. 00:00:55.115: First chance exception 0xC0000139 (DLL Not Found) occurred in "NTDLL.DLL" at address 0x76E24285 by thread 0xBBC. 00:00:55.115: Unloaded "mytest.DLL" at address 0x07860000 by thread 0xBBC. 00:00:55.115: LoadLibraryW("mytest.dll") returned NULL by thread 0xBBC. Error: The specified procedure could not be found (127).
是否有方法对此进行调试以找出 NTDLL.DLL 报告的 DLL Not Found 消息试图查找的内容? 或者我应该去其他地方寻找问题的根源?
请注意,从另一个应用程序加载相同的“mytest.DLL”似乎可以正常工作。
I have a dll "mytest.dll" that when loaded via LoadLibrary()
, returns NULL (and 127 as the GetLastError()
). If I use DependencyWalker on "mytest.dll", it reports that it should load correctly and that all DLLs are found correctly. Running the profiler option of DependencyWalker on the host exe gives me this relevant section in the log:
00:00:55.099: Loaded "mytest.DLL" at address 0x07860000 by thread 0xBBC. Successfully hooked module. 00:00:55.115: First chance exception 0xC0000139 (DLL Not Found) occurred in "NTDLL.DLL" at address 0x76E24285 by thread 0xBBC. 00:00:55.115: Unloaded "mytest.DLL" at address 0x07860000 by thread 0xBBC. 00:00:55.115: LoadLibraryW("mytest.dll") returned NULL by thread 0xBBC. Error: The specified procedure could not be found (127).
Is there a way to debug this to find out what the DLL Not Found message that NTDLL.DLL reports is trying to look for? Or should I be looking elsewhere for the source of the problem?
Note that loading this same "mytest.DLL" from another application seems to work correctly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的应用程序是否会在初始加载(可能)后尝试通过 GetProcAddress 调用未找到的特定 DLL 函数? 它是 32 位还是 64 位应用程序?
如果它按照您的建议在另一个应用程序中正确加载,那么它可能有一个正确的入口点。
快速 google 搜索表明您返回的错误代码可能来自 DLL 中缺少的函数名称(或特定函数的序数值)。 我建议以 Exescope 之类的方式打开 DLL 并检查出口清单。
它还可以解释为什么 DLL 与另一个应用程序一起工作(也许另一个应用程序在 DLL 中使用不同的导出函数)?
Could your application be trying to call a specific DLL function via GetProcAddress after the initial load (perhaps) which is not found? Is it a 32 or 64 bit application?
If it is loading correctly in another application as you suggest, then it probably has a correct entry point.
A quick google search suggests that the error code you are getting back is likely from a missing function name (or specific function's ordinal value) in the DLL. I'd suggest opening the DLL in something like Exescope and inspect the exports list.
It might also explain why the DLL works with another application (perhaps the other application uses different exported functions in the DLL)?
使用进程监视器或FileMon 可能会告诉您 myTest.dll 是否根本不在要查找的位置。
Using Process Monitor or FileMon from SysInternals might give you a clue as to whether myTest.dll is simply not where it's being looked for.
DependencyWalker 显示隐式依赖关系(由 Windows 加载程序自动处理的依赖关系)。 使用 LoadLibrary 加载的 DLL 是显式依赖项,DependencyWalker 无法找到它们(例如,库名称可能从 ini 文件中读取,而 DependencyWalker 无法推断出这一点)。
DLL 在一个应用程序中工作而在另一个应用程序中不起作用的情况一点也不罕见。 在最常见的情况下,一个应用程序已加载所需的 dll,而另一个应用程序尚未加载。 如果 dll 不在路径上,则您的 dll 将在第一种情况下工作,而不是在第二种情况下工作。
不管怎样,遵循 Michael Burr 的建议并使用 FileMon。 尽管 SysInternals 网站说 FileMon 已经过时,但它仍然比 ProcMon 更容易使用。
DependencyWalker shows implicit dependencies (dependencies that are automatically handled by the Windows loader). DLLs you load with LoadLibrary are explicit dependencies and DependencyWalker has no way to find them (for example, the library names might be read from an ini file, and there's no way that DependencyWalker could infer this).
It's not at all unusual for a DLL to work in one app and not in another. In the most common scenario, one application already has a required dll loaded and the other does not. If the dll is not on the path, your dll will work in the first case and not in the second.
Anyway, go with Michael Burr's suggestion and use FileMon. Even though the SysInternals web site says that FileMon is outdated, it's still a lot easier to use than ProcMon.