c++ - 使用托管 C++ 库时出现 WS2_32.dll_unloaded 异常

标签 c++ dll windows-server-2008-r2

有没有人知道以下崩溃的含义或如何调试它?

故障应用程序名称:MyServer.exe,版本:0.0.0.0,时间戳:0x53d885f1

错误模块名称:WS2_32.dll_unloaded,版本:0.0.0.0,时间戳:0x4ce7ca25

异常代码:0xc0000005

故障偏移量:0x000007fefe67a0af

错误进程 id:0xcbc

错误的应用程序启动时间:0x01cfabbc216f52c2

错误的应用程序路径:[Path]/MyServer.exe

错误模块路径:WS2_32.dll

报告编号:61efadce-17af-11e4-8301-001517d9c80a

当我将我的 exe(非托管 C++)与托管 C++ dll(通过 dllexport 公开)链接时,会发生这种情况。从 windbg 来看,似乎崩溃是在加载所有模块之后发生的,甚至在它到达 main 之前:

(51d4.5e50):访问冲突 - 代码 c0000005(第一次机会) 在任何异常处理之前报告第一次机会异常。 可以预期并处理此异常。 +0x1a0af: 000007fe fe67a0af ?? ??? 0:000> kP Child-SP RetAddr Call Site 00000000 0020dc80 00000000 002a2700 <Unloaded_WS2_32.dll>+0x1a0af 00000000 0020dc88 00000000 002a2701 0x2a2700 00000000 0020dc90 00000000`00000000 0x2a2701

托管的 C++ dll 是一个 DNS 库,它最终调用下面的 WS2_32.dll。

奇怪的是,另一个使用相同托管 C++ dll 的 exe 工作正常,我没有看到源/头文件之间有任何明显的差异会导致这种不同的行为。如果我注释掉 (1) 引用此托管 dll 的代码,或 (2) 我的 exe 中除了引用托管 dll 的代码之外的所有其他内容,那么崩溃也不会发生。 (2) 有效的事实告诉我至少所有的 dll 依赖项都应该在工作目录中。

这仅发生在 Windows Server 2008 R2 上。我正在使用.Net 4.5。

谁有什么指点吗?

最佳答案

我有一个类似的问题涉及一个使用许多 DLL 的 native 应用程序,其中一个是托管的。应用程序无法进入 main 的事实表明 DLL 的 DllMain 正在返回 FALSE。但是,我不知道是哪一个,尽管事件查看器中的日志显示了与 OP 提供的错误消息类似的错误消息。对我来说幸运的是,该应用程序仅在新构建的 PC 上失败。为尝试和调试问题而执行的操作:

  • 使用加载程序快照来跟踪 DLL 加载过程。与 WinDbg 一起,这给出了哪个 DLL 失败的指示,这是因为一堆未初始化的 DLL 包括除已运行其初始化程序之外的所有 DLL。虽然它没有显示每个 DLL 的 DllMain 的实际返回值。
  • 使用 Dependency Walker 的分析选项来跟踪 DllMains 的返回值。然而,这并没有取得什么成果。
  • 在两台机器上使用 ProcMon 捕获启动并比较跟踪。在检查注册表项 HKLM\Software\Microsoft\SQMClient\Windows\CEIPEnable 后,这更有成效,并显示出两者之间的不同行为。在工作案例中,CEIPEnable 为 0。在失败案例中,CEIPEnable 为 1。这就是 nop 提到的 Windows 客户体验改善计划。禁用它允许应用程序在故障机器上启动。
  • 使用 AppVerifier 捕获那些在 DllMain 中调用 WSAStartup 的 DLL(在调试器下运行时)。这确实标记了可疑的 DLL(以及其他)。此行为与 Richard 指出的 MSDN 建议相反。

进一步观察:

  • 如果我在好的机器上启用 CEIP,应用程序仍然可以成功启动。因此,必须有其他因素导致失败。
  • Microsoft Japan 有一个 article关于禁用 CEIP 被列为解决方法的问题。链接的文章是日文的,但谷歌可以翻译。
  • 托管 DLL 似乎不是问题所在。

我希望有人觉得这个答案有用。如果这里没有 nop 的答案,我就无法解决我的问题。

关于c++ - 使用托管 C++ 库时出现 WS2_32.dll_unloaded 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25047316/

相关文章:

c++ - 使用stringstream将0x20视为0x00

c++ - EnumDisplayMonitors 回调

c# - 带有 Mono 4.2.3 的 Web Api 2

c++ - dll 中的 vector.h 在我的应用程序中不可用

c++ - tr1::reference_wrapper 有什么用?

c++ - OpenMP 第一个内核比第二个内核慢得多

c# - 如何以编程方式检查解决方案中是否正确配置了引用

MySQL服务器性能

windows - 在任务计划程序中运行 PowerShell

c# - 控制台应用程序的 Process.Start() 在 Server 2008 R2 中无法从 Windows 服务运行