在Visual Studio中调试使用CreateProcess生成的进程

17

我创建了一个 Windows/C++/WTL 应用程序,该应用程序会生成一个子进程。这两个进程通过匿名管道进行通信。

我希望能够调试子进程。

由于父进程和子进程项目都在 Visual Studio 2008 的同一解决方案中,有没有办法告诉 VS2008,要调试两个进程呢?

当我使用父进程启动调试器时,调试器不会在子进程代码中停止任何断点。

而且由于子进程是由父进程生成的,我想不出什么简单的方法来附加子进程(也许可以通过另一个 VS2008 实例),当它被生成时。

非常感谢您提供任何见解!


好问题,当我尝试在VS2008中调试一个Apache模块时,我遇到了这个问题。 - SirDarius
3个回答

15

多种可选方案:

  • 使用调试+附加,您可以使用一个调试器实例调试多个.exe文件。然而,我总是使用两个Visual Studio实例,在第二个实例中使用调试+附加。

  • 您可以在子进程代码中放置__debugbreak(),JIT调试器窗口将提示您选择一个调试器。

  • 您可以使用“Image File Execution Options”注册表键,在启动子.exe时自动启动调试器。添加一个名为HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\YourApp.exe的键,将其“Debugger”值设置为“vsjitdebugger.exe”。

  • 有一个VS插件,使操作更加简单,但我还没有尝试过。

我有兴趣尝试Debug + Attach,以便在一个调试器实例中调试多个.exe文件,但是我无法确定如何在父进程使用CreateProcess生成的子进程中执行Debug + Attach。根据我的先前评论,DebugBreak()无法工作,因为新的调试器实例中没有源代码。如果将子进程分离到单独的解决方案文件中,我是否会更成功? - user206705
调试 + 查看 + 模块,右键单击 .exe,符号加载信息会告诉您它在哪里查找所需的 .pdb 文件。 - Hans Passant
VS2008中的调试菜单没有查看选项吗? 你是指工具->选项->调试->符号吗? - user206705
2
抱歉,调试 + 窗口 + 模块。点击一下以了解其中的内容。 - Hans Passant
我刚刚尝试了VS 2015(社区版)中的插件,它像魔法一样正常工作。感谢您在6年后更新了您的答案! - Christopher Gurnee
显示剩余2条评论

4

您可以在子进程的启动代码中暂时调用DebugBreak()。这将导致Windows提示您是否要调试该进程。


我在Windows 7 x64上尝试了这个。当子进程中的DebugBreak()被调用时,操作系统通过弹出消息框告诉我子进程已停止工作。我选择调试应用程序,但只能在新的VS2008实例中启动调试会话。这样做后,由于“当前位置没有可用的源代码”,我无法逐步执行代码。不过还是很不错的尝试! - user206705

3
您可以在CreateProcess调用周围放置一个全局命名互斥量,然后尝试在子进程中抓取该互斥量。如果您在CreateProcess调用上设置断点,则应有时间在子进程执行任何实质性操作之前附加到它。
请注意,您将错过子进程中main之前发生的任何事情。
编辑:例如,像这样的未经测试的东西:
// parent.cpp
HANDLE hMutex = ::CreateMutex(NULL, TRUE, "Global\\some_guid");
::CreateProcess(...);
::ReleaseMutex(hMutex); // breakpoint here
::CloseHandle(hMutex);

// child.cpp
int main(...)
{
  HANDLE hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, "Global\\some_guid");
  ::WaitForSingleObject( hMutex, INFINITE );
  ::CloseHandle(hMutex);

  ...
}

你可能希望将其包装在#if _DEBUG或环境变量检查中。


很棒的想法,令人惊讶的是VS2008 / VS2010没有这种功能 - 我本来以为这种需求很普遍。 - user206705

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