2

这是我的场景:我有一个程序可以生成调试输出,OutputDebugString()其中可能包含指示错误的消息。我想在日常构建中运行这个程序并自动监听调试输出,解析它并报告可疑输出。

有几个这样的监听器实现的例子,例如这个。它们都做同样的事情——监听系统范围的事件,然后从文件映射中读取数据。问题是这个协议只允许监听器的一个实例——首先抓住事件的人是唯一访问输出的人。

与 DebugView 程序相同。如果我有一个正在运行的实例,那么启动另一个实例会产生一个“断开连接”的实例,它将无法“连接本地”。

每日构建同时运行多个程序,因此我希望能够运行此侦听器的多个实例,并且每个实例只侦听特定程序。看起来 Visual Studio 可以做到这一点 - 当我在 Visual Studio 下启动一个程序时,我只能看到该程序的调试输出,而不是其他程序的调试输出,而且我还可以运行多个 Visual Studio 实例并在每个程序中调试一个程序同时

是否可以运行多个等效于 DebugView 的程序实例,以便每个实例只侦听正在观察的特定程序并且实例不会相互干扰?

4

1 回答 1

3

我按照用户500 -评论中的内部服务器错误给出的提示,尝试了“假装 Visual Studio”的方式。它非常接近“拿着我的啤酒”难度级别(但我有 10 年以上的 WinAPI 软件开发经验)。整个过程花了几个小时,实现不到 200 行 C++ 代码,包括一些用于调用 WinAPI 函数的庞大代码以及过滤输出并以可用方式报告可疑项目的代码。

有趣的部分是我使用 Visual Studio 编写和调试代码 - Visual Studio 充当我正在开发的程序的调试器,而正在开发的程序充当产生好奇调试输出的程序的调试器,并且这个链工作正常美好的。

这是一个很好的教程来获得这个想法和一些灵感:编写一个基本的 Windows 调试器这是一个 MSDN 解释如何编写一个调试器主循环:编写调试器的主循环

这是它的工作原理:

  1. CreateProcess()通过使用和传递DEBUG_ONLY_THIS_PROCESS标志启动要处理调试输出的程序。这将启动程序暂停并处于“正在调试”模式。
  2. 运行一个无限循环并调用WaitForDebugEvent()每次迭代。调用WaitForDebugEvent()恢复挂起的程序并允许它运行直到下一个调试事件发生。
  3. Process OUTPUT_DEBUG_STRING_EVENT,用于ReadProcessMemory()从正在调试的进程中复制字符串,按照您认为合适的方式处理字符串。
  4. 还有进程EXIT_PROCESS_DEBUG_EVENT- 这意味着正在调试的进程已退出,您可能想要结束循环。
  5. 还要处理EXCEPTION_DEBUG_EVENT- 当EXCEPTION_DEBUG_INFO.dwFirstChance为零时,您必须终止正在调试的进程,TerminateProcess()否则您会从 Windows 收到一个不方便的“程序已停止工作”对话框
  6. ContinueDebugEvent()在循环迭代结束时调用,通过DBG_EXCEPTION_NOT_HANDLED

就这样。是的,现在您可以声称您有编写调试器的经验。

于 2019-10-17T08:02:31.140 回答