C++\CLI应用程序在加载时崩溃

3
我有一个C++应用程序,加载了大量的C++ DLL和少量选择的C++\CLI。在其中一台机器上(Windows Server 2003 SP2)启动时,我收到了错误消息:

应用程序无法正确初始化(0xC0000005)。单击“确定”终止应用程序。

当使用WinDbg打开应用程序时,而不是获得正确的DbgBbreak断点,我得到了以下内容:

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: d:\appdir\MyTrueApp.exe
Symbol search path is: .sympath SRV*c:\localsymbols*http://msdl.microsoft.com/download/symbols
Executable search path is: 
ModLoad: 00400000 0044b000   MyTrueApp.exe
ModLoad: 7c800000 7c8c3000   ntdll.dll
ModLoad: 77e40000 77f42000   C:\WINDOWS\system32\kernel32.dll
ModLoad: 60200000 60264000   d:\AppDir\CustomCppDLL_ONE.dll
ModLoad: 76aa0000 76acd000   C:\WINDOWS\system32\WINMM.dll
ModLoad: 77380000 77411000   C:\WINDOWS\system32\USER32.dll
ModLoad: 77c00000 77c49000   C:\WINDOWS\system32\GDI32.dll
ModLoad: 7d1e0000 7d27c000   C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77c50000 77cf0000   C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 76f50000 76f63000   C:\WINDOWS\system32\Secur32.dll
ModLoad: 10000000 10023000   d:\AppDir\CustomCppDLL_TWO.dll
ModLoad: 7c420000 7c4a7000   C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.5592_x-ww_179798C8\MSVCP80.dll
ModLoad: 78130000 781cb000   C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.5592_x-ww_179798C8\MSVCR80.dll
ModLoad: 77ba0000 77bfa000   C:\WINDOWS\system32\msvcrt.dll
ModLoad: 60300000 60332000   d:\AppDir\CustomCppDLL_3RD.DLL
ModLoad: 781d0000 782df000   C:\WINDOWS\WinSxS\x86_Microsoft.VC80.MFC_1fc8b3b9a1e18e3b_8.0.50727.5592_x-ww_E87E0BCD\MFC80.DLL
ModLoad: 7d180000 7d1d2000   C:\WINDOWS\system32\SHLWAPI.dll
ModLoad: 77670000 777a9000   C:\WINDOWS\system32\ole32.dll
ModLoad: 77d00000 77d8b000   C:\WINDOWS\system32\OLEAUT32.dll
ModLoad: 00360000 00375000   d:\AppDir\CustomCppDLL_4th.DLL
ModLoad: 60800000 6081a000   d:\AppDir\CustomCppDLL_5th.DLL
ModLoad: 60600000 6074b000   d:\AppDir\CustomCppDLL_6th.DLL
ModLoad: 003b0000 003c5000   d:\AppDir\CustomCppDLL_7th.DLL
ModLoad: 77b90000 77b98000   C:\WINDOWS\system32\VERSION.dll
ModLoad: 00450000 004d6000   d:\AppDir\CustomCppDLL_7th.DLL
ModLoad: 7c8d0000 7d0cf000   C:\WINDOWS\system32\SHELL32.dll
ModLoad: 61880000 618bb000   C:\WINDOWS\system32\OLEACC.dll
ModLoad: 73070000 73097000   C:\WINDOWS\system32\WINSPOOL.DRV
ModLoad: 762b0000 762f9000   C:\WINDOWS\system32\comdlg32.dll
ModLoad: 77530000 775c7000   C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.3790.4770_x-ww_A689AB02\COMCTL32.dll
ModLoad: 004e0000 00506000   d:\AppDir\CustomCppDLL_9th.DLL
ModLoad: 00510000 00547000   d:\AppDir\CustomCppDLL_10th.DLL
ModLoad: 71c00000 71c17000   C:\WINDOWS\system32\WS2_32.dll
ModLoad: 71bf0000 71bf8000   C:\WINDOWS\system32\WS2HELP.dll
ModLoad: 76cf0000 76d0a000   C:\WINDOWS\system32\iphlpapi.dll
ModLoad: 76b70000 76b7b000   C:\WINDOWS\system32\PSAPI.DLL
ModLoad: 6d580000 6d628000   C:\WINDOWS\system32\dbghelp.dll
ModLoad: 00560000 0056a000   d:\AppDir\CustomCpp_CLI.DLL
ModLoad: 79000000 7904a000   C:\WINDOWS\system32\mscoree.dll
ModLoad: 71bc0000 71bc8000   C:\WINDOWS\system32\rdpsnd.dll
ModLoad: 771f0000 77201000   C:\WINDOWS\system32\WINSTA.dll
ModLoad: 71c40000 71c97000   C:\WINDOWS\system32\NETAPI32.dll
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntdll.dll - 
(1510.1304): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.

kc命令的结果为:

ntdll!LdrOpenImageFileOptionsKey
ntdll!LdrQueryImageFileExecutionOptionsEx
ntdll!LdrQueryImageFileExecutionOptions
ntdll!RtlIpv4StringToAddressExW
ntdll!RtlLogStackBackTrace
ntdll!LdrGetProcedureAddress
ntdll!EtwTraceMessage
ntdll!RtlIsThreadWithinLoaderCallout
ntdll!RtlGetActiveActivationContext
ntdll!RtlGetActiveActivationContext
ntdll!RtlGetActiveActivationContext
ntdll!RtlGetActiveActivationContext
ntdll!RtlGetActiveActivationContext
ntdll!RtlGetActiveActivationContext
ntdll!CsrClientConnectToServer
ntdll!KiUserApcDispatcher

谷歌搜索 ntdll!LdrOpenImageFileOptionsKey 可以发现它是系统加载器的一部分。除此之外,没有更多的帮助,只是似乎有一个可怜的家伙遇到了类似的问题,但没有解决方案。曾经有一个在加载混合程序集时的 bug,但那是针对 Visual Studio 2003 的,而我使用的是 2005 和 .NET Framework 2.0。

在绝望中,我尝试了.Net Framework修复程序,但当然没有成功。我回到Google并找到了这个帖子,其中有一个小线索。它说:

Since you received the error message "An unhandled non-continuable exception was thrown during process load", it seems the problem is caused by a difficult issue related to DLL files. There are several discussions on this topic, maybe some of them can help:

  http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=325627&SiteID=1
  http://groups.google.com/group/microsoft.public.vc.mfc/browse_thread/thread/560a31bb72b2bca8/44fb800374c2f3b0%2344fb800374c2f3b0
  http://groups.google.com/group/microsoft.public.dotnet.languages.vc/browse_thread/thread/1243abff27e677ae/901c0a23deec7e47%23901c0a23deec7e47

前两个链接没有用,但是last提到使用类似问题的/DELAYLOAD链接器选项可以解决问题。通过将CustomCpp_CLI.DLL设置为延迟加载,我找到了解决方案。现在我的应用程序运行良好

我仍然不知道这有何帮助的确切原因。另一方面,我的C++ DLL在DllMain中做了一些奇怪的事情,正如Larry OstermanRaymond Chen所写的那样,这是可怕的。也许我的DLL与加载程序搞乱了?我不知道。

我把这篇文章写成了行动后报告 (AAR)的形式,这样它在谷歌搜索结果中会更加突出,未来的某一天,可能会有一个可怜的灵魂需要这篇文章,所以互联网变得更好
顺便说一句,如果有人知道为什么/DELAYLOAD会有帮助,请 enlighten 我。

你的 C++ DLL 的 DllMain 函数在做什么奇怪的事情? - Marc Sherman
4个回答

4

3
我遇到了完全相同的问题,并尝试了几种不同的策略,但最终由于代码库存在问题而不得不放弃。/delayload 策略对我来说不是一个选项。
然而,在 Microsoft Connect 上我偶然发现了这个 posting ,提供了一个对我来说相当好的解决方法。
基本上,非托管 C++ 可执行文件需要在链接任何非托管 C++ dll 的 lib 文件之前链接到混合模式 C++ dll 的 lib 文件。
我通过以下方式指定了这个选项:
  1. 进入可执行项目的属性对话框。
  2. 选择 Linker-> 输入选项卡。
  3. 将混合模式 lib 文件添加到附加依赖项字段的开头。
对于我的情况,这是最好的解决方案。它让我能够利用我的混合模式 dll ,而无需做大量工作或导致巨大的 QA 负担。
另一个可能有效但对我所使用的代码库没有用处的解决方案是将非托管 C++ 可执行文件变成混合模式可执行文件。
为了避免将整个exe变成CLR exe...
  1. 向项目中添加一个新的cpp文件。
  2. 右键单击该cpp文件。
  3. 选择“属性”。
  4. 选择“常规”选项卡
  5. 将公共语言运行时支持标志设置为/clr。
cpp文件可以为空,不需要定义类。它只需要存在,以使可执行文件成为混合模式,从而正确链接所有内容。
希望这些解决方案中的一个能够帮助未来的某个人节省大量时间来解决此问题。

哦,该死的,谢谢!我已经追寻这个问题一段时间了。 - Justin
我不知道为什么,但改变链接顺序解决了我的问题!谢谢。 - Stefano

2
我遇到了一个类似的问题,我的C++/CLI应用程序在启动时崩溃了,也很难找到原因。我经过一番调试和搜索才发现罪魁祸首是WinMM DLL(Windows多媒体库),它在入口点函数中做了一些“不安全”的事情(即多次调用“FreeLibrary” - 我认为文档中明确标记为不安全的内容)。我在Microsoft网站上找到了一些KB文章或帖子,并且解决方案与您的情况相同 - 动态加载DLL(具有与/DELAYLOAD开关相同的效果)而不是静态链接。

在您的情况下,我看到您还加载了WinMM库。 它是由您的应用程序直接加载还是通过CustomCpp_CLI模块间接加载的?如果您遇到了相同的问题,那么这就很有趣了。但无论如何,似乎总的规则是,在C++/CLI项目中静态链接到某些“行为不当”的DLL是不安全的。


有趣。我记得在我的研究中看到了一些WinMM的参考资料,但我忽略了它们。http://www.google.com/search?q=winmm+c%2B%2B%2Fcli+hangs 给出了一些有趣的链接。WinMM由一个CPP DLL加载。我从未想过我会遭受真正的Windows错误... - Michal Sznajder

0

我看到你正在加载winsta.dll - MSDN论坛上的一个问题(也是我正在开发的服务器应用程序中常见的问题)显示,XP/2003上的终端服务会导致TS会话中的C++/CLI混合模式DLL(至少对于CLR2而言)出现加载错误。解决方法是使用VNC或类似工具。


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