Я придумал способ, используя терминал MSYS2 . Другие методы могут работать с программным обеспечением GUI. Главное предостережение заключается в том, что это невозможно сделать на чистом C / C ++ и выпустить для конечных пользователей. Это только для разработчиков, но это лучше, чем ничего.
Установите Debugging Tools для Windows, загрузив Windows SDK и сняв все флажки, кроме Debugging Tools. Я могу ошибаться, но похоже, что установка этого программного обеспечения устанавливает ловушку в ядро Windows, позволяющую LoadLibrary()
записывать подробную информацию в stderr.
Откройте терминал MSYS2 Mingw64 от имени администратора и запустите
'/c/Program Files (x86)/Windows Kits/10/Debuggers/x64/gflags.exe' -i main.exe +sls
Это выводит на терминал следующее, чтобы подтвердить, что реестр был изменен.
Current Registry Settings for main.exe executable are: 00000002
sls - Show Loader Snaps
Используйте -sls
вместо +sls
, если вам нужно отменить, поскольку я считают, что изменение происходит для всех программ, называемых main.exe
в Windows, глобально, а не только для вашего файла.
Затем запуск main.exe
должен распечатать отладочную информацию в stderr, но поскольку я отлаживаю приложение -mwindows
, оно у меня не работает.
Но по какой-то причине запуск двоичного файла с помощью gdb MSYS2 позволяет распечатать эту отладочную информацию в stderr. Установите mingw-w64-x86_64-gdb
с MSYS2, запустите gdb ./main.exe
и введите run
или r
. Найдите раздел, похожий на следующий.
warning: 1ec8:43a0 @ 764081125 - LdrpNameToOrdinal - WARNING: Procedure "foo" could not be located in DLL at base 0x000000006FC40000.
warning: 1ec8:43a0 @ 764081125 - LdrpReportError - ERROR: Locating export "foo" for DLL "C:\whatever\plugin.dll" failed with status: 0xc0000139.
warning: 1ec8:43a0 @ 764081125 - LdrpGenericExceptionFilter - ERROR: Function LdrpSnapModule raised exception 0xc0000139
Exception record: .exr 00000000050BE5F0
Context record: .cxr 00000000050BE100
warning: 1ec8:43a0 @ 764081125 - LdrpProcessWork - ERROR: Unable to load DLL: "C:\whatever\plugin.dll", Parent Module: "(null)", Status: 0xc0000139
warning: 1ec8:43a0 @ 764081171 - LdrpLoadDllInternal - RETURN: Status: 0xc0000139
warning: 1ec8:43a0 @ 764081171 - LdrLoadDll - RETURN: Status: 0xc0000139
Отлично! Здесь написано Procedure "foo" could not be located in DLL
, значит, у нас есть отсутствующий символ, как в POSIX / UNIX s dlopen()
.