Отладка ошибки времени загрузки в программе С++ SDL2, скомпилированной с VS2015 на Win10

Я пишу проект на С++ с SDL2 в 64-разрядной Windows 10 с помощью Visual Studio 2015. Недавно я купил новый ноутбук под управлением Windows 10 и клонировал свой проект из github. Мой проект правильно компилируется, но при запуске я получаю следующую ошибку:

Приложение не смогло начать правильно (0xc000007b). Нажмите "ОК", чтобы закрыть приложение.

Основываясь на моих исследованиях до сих пор, эта ошибка обычно вызвана загрузкой несовместимой DLL, например. 64-битная версия вместо 32-разрядной. Предложения, которые я нашел до сих пор, включают:

  • Проверка того, что я использую 32-разрядные версии DLL файлов SDL2
  • Установка/переустановка x86-версии распространяемого Visual С++ для Visual Studio 2015
  • Использование Уклонение зависимостей для устранения неполадок, из-за которого происходит сбой DLL

Мой проект настроен для сборки для Win32, и я гарантировал, что я использую 32-разрядные версии всех DLL, с которыми я напрямую связываюсь (libfreetype-6, libpng16-16, SDL2, SDL2_image, SDL2_mixer, и SDL2_ttf). Я подтвердил, что x86 VС++ Redistributable установлен на моей машине.

Наконец, я попытался использовать Dependency Walker, чтобы определить, какая DLL может вызвать проблему (хотя я читал оговорки, что Dependency Walker имеет много ложных срабатываний). Это были результаты:

Статический анализ зависимостей Уолкера Статический анализ зависимостей Уолкера

Результаты профилирования зависимостей Уокер Результаты профилирования зависимостей зависания

После этого профайлер зависает и никогда не продолжает. Обратите внимание, что компоненты SDL и среда выполнения VC загружаются без ошибок.

Программа компилируется и загружается правильно на моих двух старых компьютерах, одна из которых работает с 32-разрядной Windows 7 и одна работает под 64-разрядной Windows 10.

Теперь для актуального вопроса. Какие еще шаги я могу предпринять для отладки этого сбоя? Или кто-нибудь видит из информации, которую я представил, что я делаю неправильно?

Похожие вопросы:

Изменить:

Как предложил rflobao, я использовал 64-разрядную версию Dependency Walker на 32-разрядной версии exe. Вот новый вывод моего профайлинга:

Новый профиль профиля Walker Profile

В этот момент, как и прежде, Dependency Walker замерзает. Я все еще полностью потерян и не чувствую, что я ближе к тому, чтобы определить, что вызывает проблему.

Ответ 1

Я чувствую себя глупо, но, наконец, понял реальную проблему. Я использую библиотеку шрифтов SDL SDL2_ttf, и я просто не копировал zlib.dll из каталога SDL2_ttf lib в мой каталог сборки. Я не понимаю, почему сообщение об ошибке было настолько загадочным; в прошлом отсутствующие DLL файлы предоставили мне полезное сообщение об ошибке "foo.dll missing".

В любом случае, спасибо вам за вашу помощь. По крайней мере, я узнал полезный урок: всегда убедитесь, что все необходимые библиотеки DLL присутствуют, прежде чем заподозрить более сложную проблему.

Ответ 2

Обратите внимание, что Dependency Walker имеет 32- и 64-разрядную версию. Если ваше приложение 32-битное, вы должны использовать 32-битную версию. В противном случае Dependency Walker увидит libs для System32, а не SisWOW64. Вы показываете 32-битные и 64-битные библиотеки смешанного типа, где 64 имеет ошибку.

Ответ 3

Это отнюдь не полностью надежное, но вы можете попробовать. Для этого требуется dumpbin.exe, который входит в состав Visual Studio.

Сначала получите список зависимых DLL для вашей программы, разрешенных по вашему пути:

del dlls.txt
for /f %d in ('dumpbin /dependents Questless.exe ^| findstr /ic:".dll"') do @echo %~$PATH:d >> dlls.txt

Затем получите битту каждого:

for /f "delims=" %d in (dlls.txt) do @echo %d & dumpbin /headers "%d" | findstr /c:"machine (x"

Это будет выдавать вывод, например:

C:\Windows\System32\kernel32.dll
            8664 machine (x64)
C:\programs\ed23\bin\hydra.dll
             14C machine (x86)

Обратите внимание, что это неправильное использование kernel32.dll из System32, а не WOW6432, поэтому оно показывает это как x64. Это связано с тем, что он просто использовал путь, когда загрузчик Windows фактически будет использовать преобразователь WOW6432, SxS, манифест приложения и только отпадет на путь, если ни один из них не разрешит зависимость. Он также не находит иждивенцев иждивенцев (вы можете script рекурсировать через иждивенцы, но обязательно отфильтровывать дубликаты) и, конечно, ничего не знаете о явных динамических нагрузках во время выполнения.

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