3
votes

I have a C++ app that loads lot of C++ DLL and few selected C++\CLI ones. On one of the machines (Windows Server 2003 SP2) on start-up I was getting error message

The application failed to initialize properly (0xC0000005). Click on OK to terminate the application.

When app was opened with WinDbg instead of getting proper DbgBbreak breakpoint I was getting this:

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.

Result of kc command was

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

Googling for ntdll!LdrOpenImageFileOptionsKey reveals that it is a part of a system loader. No more help from here except that it seems one poor guy had a similar issue but without solution. There was once a bug in loading of mixed assemblies but it was for Visual Studio 2003 and I was on 2005 and .NET Framework 2.0.

In sheer despair I tried .Net Framework repair but of course with no luck. I went back to Google and got this post that had a small clue. It states

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

First two link are no use but the last one mentions that with similar problem /DELAYLOAD linker option helped. By setting CustomCpp_CLI.DLL as delay loadable I got my solution. My application rock'n'rolls now!

I still don't know exactly a reason why this helps. On the other side my C++ DLL do some strange stuff in DllMain and as Larry Osterman and Raymond Chen write this is scary. Maybe my DLLs mess somehow with loader? I don't know.

I wrote this as a AAR (After Action Report) so it pops out in Google results and will poor soul one day in the future so Internet is a better place.

BTW If someone knows why /DELAYLOAD helped please enlighten me.

4
What strange stuff is your C++ DLL's DllMain doing?Marc Sherman

4 Answers

4
votes

I had a similar issue today on a Windows 2003 SP2 server .. and the solution I found was to delay load the problematic dll.

As given in

https://connect.microsoft.com/VisualStudio/feedback/details/586715/unmanaged-exe-linked-to-a-mixed-mode-dll-crashes-at-startup-on-some-xp-machines

My main app was in Delphi 2010 and I used the delayed keyword in delphi as given in

http://www.drbob42.com/examines/examinC1.htm

It works like a charm now ..

3
votes

I've run into this exact same problem and tried several different strategies that I ultimately had to discard due to issues with the codebase I'm working in. The /delayload strategy wasn't an option for me.

However I stumbled upon this posting on Microsoft Connect that provides a workaround that works fairly well for me.

Basically the unmanaged C++ executable needs to link to the lib file for the mixed mode C++ dll before linking to the lib files for any unmanaged C++ dlls.

I specified this option by:

  1. Go into the Properties dialog for the executable project.
  2. Select Linker-> input tab.
  3. Add the mixed mode lib file to the beginning of the Additional Dependencies field.

For my situation this has been the best solution. It lets me take advantage of my mixed mode dll without having to do a ton of work or causing a huge QA burden.

Another potential solution that works, but wasn't useful for the code base that I'm working with is to make the unmanaged C++ executable a mixed mode executable.

To do this without making the entire exe a CLR exe...

  1. Add a new cpp file to the project.

  2. Right click on that cpp file.

  3. Select Properties.

  4. Select the general tab

  5. Set the Common Language Runtime Support flag to /clr.

The cpp file can be empty, it doesn't need a class defined. It just needs to be there to make the executable mixed mode so that it correctly links everything.

Hopefully one of these solutions helps someone out in the future so they don't have to spend a ton of time figuring out this problem.

2
votes

I ran into a similar problem with a C++/CLI application crashing during start-up and it was also pretty obscure, it took me some debugging and googling to find out that the culprit was the WinMM DLL (Windows Multimedia library) that was doing some "unsafe" stuff in it's entry point function (namelly calling "FreeLibrary" multiple times - something that I think is explicitly marked as unsafe in the documentation). I did find some KB article or post in the Microsoft Website about this and the solution was - as in your case - to dynamically load the DLL (that has the same effect as the /DELAYLOAD switch) instead of linking statically to it.

In your case I see that you also load the WinMM library. Is it loaded directly by your application or indireclty via your CustomCpp_CLI module? Would be interesting to know if you have the same problem but in any case it seems that the general rule is that it's not safe to statically link to some "misbehaving" DLLs in a C++/CLI project.

0
votes

I see you loading winsta.dll - an issue on the MSDN forums (and common with a server application I'm developing) shows that Terminal Services on XP/2003 causes a loading error for C++/CLI mixed-mode DLLs (at least for CLR2) on TS sessions. A workaround would be to use VNC/similar.