【发布时间】:2020-01-10 01:12:01
【问题描述】:
我是第一次构建一个 dll,一切都按预期工作,但我无法调试它。
我做了一个尽可能最小的例子,只有一个 dllmain() 并使用 windows DLL(非 MFC)向导设置项目。
活动构建配置:x86 调试
右键项目->设置为启动项目
禁用预编译头文件
项目属性 -> 调试 -> 命令 -> 输入的应用程序可执行文件路径
Generate Debug Info 是的
这是整个 DLL,没有其他源文件或头文件。当我按 F5 时,应用程序运行并加载 dll,消息框触发。如果调试中断未注释,则不会触发消息框,并且 DLL 不会执行任何操作,但会成功加载。调试器不会中断。如果使用断点,则不会中断。
应用程序肯定正在加载我正在构建的 DLL。
.pdb 文件在那里并且正在生成。
我尝试将调试器更改为混合、自动、本机,但仍然无法正常工作。 CALLING 应用程序可能是用 C# 编写的,但它不是我的。
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
// __debugbreak();
MessageBoxA(NULL, "Hit DLLMAIN", "test", MB_OK);
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
我做了很多研究,但我不知道为什么它不能调试。
更新:我编写了一个程序来调用 DLL 上的 LoadLibrary,并修改了我的项目以将该程序作为命令调用。
它进入调试器就好了。即使我将加载程序更改为发布配置。
不管是什么问题,都可能是第三方程序加载了dll造成的。
编辑:这是尝试使用第三方程序调试我的 dll 时的调试控制台输出,尽管程序继续运行,但调试器似乎出于某种原因退出。
'Program.exe' (Win32): Loaded 'C:\Users\Tech1\AppData\Local\ProgramDir\Program.exe'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ntdll.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel32.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\KernelBase.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\user32.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\win32u.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\gdi32.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\gdi32full.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcp_win.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ucrtbase.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\imm32.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\Private_API.dll'. Module was built without symbols.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msvcrt.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\advapi32.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sechost.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\rpcrt4.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\sspicli.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\cryptbase.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\bcryptprimitives.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\apphelp.dll'. Cannot find or open the PDB file.
'Program.exe' (Win32): Loaded 'C:\Windows\SysWOW64\kernel.appcore.dll'. Cannot find or open the PDB file.
The thread 0x4610 has exited with code 0 (0x0).
The thread 0x2614 has exited with code 0 (0x0).
The thread 0x45c0 has exited with code 0 (0x0).
The program '[21792] Program.exe' has exited with code 0 (0x0).
【问题讨论】:
-
使用 MessageBox 调试代码是个坏主意。在 DllMain() 中使用它是非法的,如果尚未加载 user32.dll,那么您的程序将死锁。使用 NULL 作为第一个参数很麻烦,对话框需要一个所有者窗口位于其顶部,如果找不到桌面成为所有者的窗口。使您可能看不到它,因为它与另一个窗口重叠。当 debugbreak() 导致焦点改变时随机看到它。您确实需要让调试器断点工作以取得任何真正的进展,很多关于此的现有问题。
-
@HansPassant 我通过编写一个程序来加载 dll 并使用它来使调试器工作。我同意 MB()。我开始将 AllocConsole 与 freopen stdout 一起使用,但试图理顺 DLL 入口/出口,因此我不会重复分配或打开。您认为什么可能会阻止 VS 通过第三方应用程序进行调试?
-
@HansPassant - 如果 user32.dll 尚未加载,那么您的程序将死锁。 - 即使 user32.dll 尚未加载 -程序将不会死锁。在加载器锁中加载 dll 从不死锁,因为我们的线程已经拥有这个加载器锁。只有当我们开始 wait 说另一个线程并且该线程尝试进入加载程序锁时,才会出现死锁。
-
@user10530562 有趣的是,我创建了一个程序来尝试重现您的情况。我不知道我是否理解错误。如果
debugbreak没有注释,debugbreak会起作用并触发断点提醒,看起来和你遇到的不一样。那我继续,程序就可以执行到Messagebox了。 -
@StriveSun-MSFT 嘿,谢谢你的关注。我今天又看了一遍,似乎调试器在启动后立即分离,但程序仍在运行。请查看我对帖子的更新。
标签: c# visual-studio winapi dll visual-studio-debugging