如何让一个Win32程序在启动时请求调试器?

3
我们有一个C++ Win32应用程序,使用Qt的QProcess(无疑是CreateProcess()的包装器)生成一个次要的“从属”程序。
不幸的是,在使用Visual Studio 2008调试系统时,调试器不会自动附加到生成的进程上。
我知道可以通过__debugbreak()以编程方式触发调试器断点,但是从属程序是否能够立即在启动时弹出“选择要调试的程序”窗口,因为目前我们必须争取手动附加到新进程?

尝试在从程序的开头添加_asm int 3。使用调试符号编译,并将Visual Studio 2008用作JIT调试器。 - toto
@toto:基本上这就相当于调用DebugBreak()。 - i_am_jorf
1
你知道真正的悲剧是操作系统级别的钩子已经存在了 - 当调试器创建一个进程时,它可以指定标志,让它自动地在子进程启动时立即得到通知。10年后,我们的开发环境仍然不支持它们 :( - Chris Becke
2个回答

4

太好了,那绝对有所帮助 - 现在它出现了一个错误框(Windows 无法找到“<完整路径到exe文件>”。确保您正确输入名称等等),但我现在肯定走上了正轨;非常感谢。 - leegent
是的,你想用实际路径替换它,以便使用jit调试器。应该在c:\program files\microsoft visual blah blah blah... - i_am_jorf

2

我从Jeffrey Richter的书籍 "Programming Applications for Windows" 中学到了另一个很棒的技巧:

  1. 在DLLMain()函数中的DLL_PROCESS_ATTACH case中调用DebugBreak(),创建一个带有该调用的DLL。
  2. 将新DLL的路径添加到注册表中(以逗号分隔):
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs

图像加载器将创建您的进程并加载注册表中输入的所有DLL。这将调用DLLmain,使您的断点被触发。

注意:为了避免对所有应用程序进行调试,请使用“GetModuleBasename”检查进程名称,并仅针对您感兴趣的进程调用断点。


1
由于这是一个已记录的技巧,它很可能会继续工作。但请注意,您将会触发保持加载器锁定的断点。 - MSalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接