【发布时间】:2016-02-29 11:03:30
【问题描述】:
当程序在调试器中停止时,是否可以释放资源(文件锁、计时器)?
更一般地说,我可以在 MSVC 停止程序进行调试之前和恢复执行之后执行代码吗?
我想完成的事情: - 在调试期间自动释放文件锁定以进行编辑。 - 进程恢复后自动重新加载文件 - 防止定时器在调试停止期间触发溢出 - 从计时器中减去调试所花费的持续时间
解决方法:如果在程序被调试器停止之前我无法执行代码,那么在程序中以编程方式检测调试器停止了应用程序已经很有帮助。
编辑:
我查看了用于调试器集成的 Windows API 函数,但似乎 ContinueDebugEvent 之类的函数仅适用于调试器的编写者,而不适用于被调试的进程。
编辑 2: 似乎对 DbgBreakPoint 函数进行热修补可能是一种在 Debugger 想要中断进程时进行拦截的方法。
附加的主要思想是调试器调用 “DebugActiveProcess”函数最终调用 “RtlCreateUserThread”函数创建一个新的远程线程进入 目标进程,以“DbgUiRemoteBreakin”函数为新 线程入口点。
(来自http://waleedassar.blogspot.de/2011/12/debuggers-anti-attaching-techniques.html)
DbgUiRemoteBreakin 似乎调用 DbgBreakPoint 来实际停止进程。
编辑 3:
我对 DbgBreakPoint 和 DebugBreak 进行了热补丁,以查看当我以交互方式中断时是否从 MSVC 调试器调用这些方法。唉,他们没有!似乎 MSVC 调试器只是在断点位置插入 int 3 而没有调用任何处理方法。
编辑 4: 阅读结构化异常及其与 DebugBreak 陷阱的交互也会导致死路:当遇到断点时,中断 3 将首先到达内核,内核首先将结构化异常传递给调试器(如果附加)。调试器处理中断,而应用程序永远不会看到它。
【问题讨论】:
-
并非如此。断点条件在被调试的进程中不可见。
-
@HansPassant:对于每个用户来说,使用中间窗口是一种手动过程。我宁愿编写代码将行为直接放入应用程序中。
-
如果你不知道它是如何工作的,那么我猜任何事情都是可能的。 C++ 需要一个编译器和一个链接器,它们没有内置在调试器中。您必须在调试之前编写该代码。只要确保您可以从即时窗口轻松调用它。您也忽略了好的建议,在您的代码中使用 IsDebuggerPresent() 是个好主意。只需使用很长的超时时间,并且在文件返回 TRUE 时不要锁定文件。编写可调试的代码与编写正确的代码一样重要。
标签: c++ debugging visual-c++ timer