为什么条件断点会使我的程序减慢太多?

时间:2009-08-06 13:19:31

标签: delphi debugging breakpoints

当我在循环中调试出错的东西时,比如在第600次迭代中,对每个循环都要打破是一件痛苦的事。所以我尝试设置一个条件断点,只有在I = 600时才会中断。这样可行,但现在需要几乎整整一分钟才能到达那个点,在此之前几乎是瞬间。发生了什么事,有什么方法可以解决它吗?

6 个答案:

答案 0 :(得分:22)

当您点击断点时,Windows会停止该过程并通知调试器。它必须切换上下文,评估条件,决定不,您不希望收到通知,重新启动进程并切换回来。这可能需要很多处理器周期。如果你在一个紧密的循环中完成它,它将比循环的一次迭代花费几个数量级的处理器周期。

如果你愿意稍微搞乱你的代码,有一种方法可以在不产生所有这些开销的情况下完成条件断点。

if <condition here> then
  asm int 3 end;

这是一个简单的汇编指令,可以手动向OS发送断点通知。现在,您可以在不切换上下文的情况下评估程序内的条件。只要确保在完成后再将其取出。如果int 3在未连接到调试器的程序内部发生,则会引发异常。

答案 1 :(得分:6)

它减慢了速度,因为每次达到这一点时,都必须检查你的情况。

我倾向于暂时创建另一个这样的变量(在C中,但在Delphi中应该可行)。

int xyzzynum = 600;
while (true) {
    doSomething();
    if (--xyzzynum == 0)
        xyzzynum = xyzzynum;
}

然后我在"xyzzynum = xyzzynum;"行放置了一个非条件断点。

程序全速运行,直到它循环600次,因为调试器正在执行正常的断点中断,而不是每次检查条件。

您可以根据需要使条件变得复杂。

答案 2 :(得分:4)

除了Mason的回答之外,如果程序是使用定义的调试条件构建的,那么只能编译int 3 asserst:

{$ifdef debug}
{$message warn 'debug breakpoint present in code'}
if <condition here> then
  asm int 3 end;
{$endif}

因此,当您在ide中进行调试时,您在项目选项中具有调试条件。当您为客户构建最终产品(使用构建脚本?)时,您不会包含该符号,因此不会编译。

我还包含了$ message编译器指令,因此在编译时会看到警告,告知您代码仍然存在。如果你在任何地方都使用int 3,那么你就会有一个很好的地方列表,你可以双击它直接找到有问题的代码。

N - [

答案 3 :(得分:3)

梅森的解释非常好 通过测试你在调试器下运行,他的代码可以有点更安全

if (DebugHook <> 0) and <your specific condition here> then
  asm int 3 end;

当应用程序正常运行时,这不会执行任何操作,如果它在调试器下运行(无论是从IDE启动还是连接到调试器),它将停止运行。
如果您不在调试器下,则无法评估布尔快捷方式<your specific condition here>

答案 4 :(得分:1)

任何调试器中的条件断点(我只是在这里猜测)要求每次遇到断点时,程序和调试器之间每次都要来回切换。这个过程非常耗时,但我认为你无能为力。

答案 5 :(得分:0)

通常条件断点的工作方式是在代码中插入适当的break命令,然后检查指定的条件。它将在每次迭代时检查,并且很可能实现检查的方式是延迟,因为调试器不太可能编译并将完整的检查和断点代码插入到现有代码中。

你可能能够加速这种情况的一种方法是,如果你将条件后跟一个没有副作用的操作直接放入代码中并打破该操作。只要记住在完成后删除条件和操作。