Сбой приложения C ++ \ CLI при загрузке - PullRequest
3 голосов
/ 05 мая 2011

У меня есть приложение 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

Поиск в Google для ntdll!LdrOpenImageFileOptionsKey показывает, что он является частью системного загрузчика . Отсюда больше никакой помощи, за исключением того, что у одного бедняка была похожая проблема, но без решения. Была однажды ошибка при загрузке смешанных сборок, но это было для Visual Studio 2003, а я был на 2005 и .NET Framework 2.0.

В полном отчаянии я попытался .Net Framework исправить но, конечно, безуспешно. Я вернулся к Google и получил сообщение , в котором была небольшая подсказка. Это заявляет

Поскольку вы получили сообщение об ошибке «Необработанный, не продолжаемый исключение было сгенерировано во время процесса загрузить », кажется, проблема вызвана по сложной проблеме, связанной с DLL файлы. Есть несколько дискуссий на эту тему, может быть, некоторые из них могут Справка:

  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 one упоминает, что с аналогичной проблемой помог параметр линкера /DELAYLOAD. Установив CustomCpp_CLI.DLL в качестве загружаемой задержки, я получил свое решение. Мое приложение рок-н-роллы сейчас!

Я до сих пор точно не знаю причину, почему это помогает. С другой стороны, моя C ++ DLL делает что-то странное в DllMain, а Ларри Остерман и Раймонд Чен пишет, что это страшно . Может быть, мои DLL как-то связываются с загрузчиком? Я не знаю.

Я написал это как AAR (Отчет о действиях) , чтобы оно появилось в результатах Google и однажды в будущем обессилело, так что Интернет - лучшее место.

Кстати, если кто-то знает, почему /DELAYLOAD помог, пожалуйста, просветите меня.

Ответы [ 4 ]

4 голосов
/ 28 ноября 2012

У меня была похожая проблема сегодня на сервере Windows 2003 с пакетом обновления 2 (SP2) ... и я нашел решение задержать загрузку проблемной библиотеки DLL.

Как указано в

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

Мое основное приложение было в Delphi 2010, и я использовал ключевое слово с задержкой в ​​Delphi, как указано в

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

Теперь это работает как шарм ..

3 голосов
/ 23 мая 2012

Я столкнулся с точно такой же проблемой и попробовал несколько разных стратегий, от которых мне в конечном итоге пришлось отказаться из-за проблем с базой кода, в которой я работаю. Стратегия / delayload не была для меня вариантом.

Однако я наткнулся на эту публикацию в Microsoft Connect, которая предоставляет обходной путь, который работает для меня довольно хорошо.

По сути, неуправляемый исполняемый файл C ++ должен ссылаться на файл lib для смешанногоРежим C ++ dll перед установкой ссылки на файлы lib для любых неуправляемых dll C ++.

Я указал эту опцию следующим образом:

  1. Перейдите в диалоговое окно «Свойства» для исполняемого проекта.
  2. Выберите Linker-> вкладка ввода.
  3. Добавьте файл lib в смешанном режиме в начало поля Дополнительные зависимости.

Для моей ситуации это было наилучшее решение.Это позволяет мне использовать преимущества моего dll в смешанном режиме, не выполняя тонны работы и не вызывая огромного бремени контроля качества.

Еще одно потенциальное решение, которое работает, но не пригодилось для кодовой базы, которую яработа с ним - сделать неуправляемый исполняемый файл C ++ смешанным.

Чтобы сделать это без превращения всего исполняемого файла в исполняемый файл CLR ...

  1. Добавить новый файл cpp в проект.

  2. Щелкните правой кнопкой мыши этот файл cpp.

  3. Выберите Свойства.

  4. Выберите вкладку "Общие"

  5. Установите флаг поддержки поддержки общего языка на /clr.

Файл cpp может быть пустым, ему не нужен определенный класс.Он просто должен быть там, чтобы сделать исполняемый смешанный режим так, чтобы он правильно связывал все.

Надеемся, что одно из этих решений поможет кому-то в будущем, так что ему не придется тратить кучу времени на выяснениеэта проблема.

2 голосов
/ 05 мая 2011

Я столкнулся с аналогичной проблемой, связанной с падением приложения C ++ / CLI во время запуска, и это также было довольно неясно, мне потребовались некоторые отладки и поиск в Google, чтобы выяснить, что виновником была WinMM DLL (библиотека мультимедиа Windows), которая делал некоторые «небезопасные» вещи в своей функции точки входа (а именно, несколько раз вызывал «FreeLibrary» - что, я думаю, явно отмечено как небезопасное в документации). Я нашел статью или пост KB на веб-сайте Microsoft по этому поводу, и решение было - как и в вашем случае - динамически загрузить DLL (что имеет тот же эффект, что и переключатель / DELAYLOAD) вместо статической ссылки на нее.

В вашем случае я вижу, что вы также загружаете библиотеку WinMM. Загружается ли оно напрямую вашим приложением или случайно через ваш модуль CustomCpp_CLI? Было бы интересно узнать, есть ли у вас такая же проблема, но в любом случае кажется, что общее правило состоит в том, что статически не безопасно статически ссылаться на некоторые "плохо себя ведущие" библиотеки DLL в проекте C ++ / CLI.

0 голосов
/ 07 мая 2011

Я вижу, что вы загружаете winsta.dll - проблема на форумах MSDN (и распространенная для разрабатываемого мной серверного приложения) показывает, что службы терминалов в XP / 2003 вызывают ошибку загрузки библиотек C ++ / CLI в смешанном режиме (по крайней мере для CLR2) на сеансах TS.Обходной путь должен был бы использовать VNC / подобное.

...