为啥条件断点会在调试时降低应用程序的执行速度?

Posted

技术标签:

【中文标题】为啥条件断点会在调试时降低应用程序的执行速度?【英文标题】:Why does Conditional breakpoint decrease the application execution speed at debug time?为什么条件断点会在调试时降低应用程序的执行速度? 【发布时间】:2009-02-11 07:32:25 【问题描述】:

当我在VS2005中使用条件断点而不是使用临时代码来检查特定条件时,我注意到它需要更多时间并且执行速度降低了!! 你知道为什么吗?以及如何解决这个问题?

示例:

    int sequence = atoi(m_SequenceNumber.GetAscii());
    if( sequence == 392914)//temporary code to check to step into code
    
        int x = 0;//I put breakpoint here
    

之前的代码将比我使用条件断点(序列 == 392914)更快地执行

【问题讨论】:

这在vs2010中杀死了我。相当繁重的循环,但通常在 1 秒内完成.. 有条件,它永远不会完成。 【参考方案1】:

最好(如果可能的话)使用内存观察点而不是条件断点。条件断点(正如其他人指出的那样)必须在每次执行指针越过该点时运行额外的代码,以确定它是否会中断 - 显然这需要额外的时间。某种类型的内存观察点可以使用某些特殊的硬件寄存器 - 您可以设置多少个可以加速的观察点是有限制的,但如果您可以使用它们,则几乎没有速度损失。

使用断点窗口设置内存观察点。您不是在一行代码上设置它,而是在内存中的一个地址上设置它。这表明了明显的限制,它仅适用于您实际上可以获取地址的东西,例如全局变量和动态分配的内存区域(使用new 等)。您被允许观看的内存量是有限的(基于 CPU,我认为您可能会获得或多或少分配的特殊寄存器)。

我现在实际上并没有坐在VS前面,但粗略地说,您在断点窗口中单击鼠标右键并选择“新数据断点”之类的内容。然后输入内存地址和大小(以字节为单位)。每当值更改时,您的观察点就会触发。这对于找出内存损坏问题特别有用。

【讨论】:

【参考方案2】:

我过去也遇到过这个问题,但从未真正找到在大循环中继续使用条件断点而不影响性能的方法。我确实了解到您可以插入一些这样的临时代码,这些代码不会影响性能并且会导致 VS 中断(与条件断点的行为相同)。

if ( condition ) Debugger.Break();

【讨论】:

【参考方案3】:

想想如果您正在编写调试器,您将如何实现条件断点。调试器唯一有机会评估条件的时间是断点被命中时。因此,即使断点就您而言是有条件的,但就处理器而言,每次执行指令时都会遇到断点。调试器获得控制权并执行以下操作:

确定断点是有条件的 计算表达式 如果表达式为假,调试器继续执行 否则,调试器会将控制权交给您

因此,即使您从未看到断点命中(因为条件不满足),调试器也可能会处理断点并每秒评估条件数千次(或更多次)。

【讨论】:

这正是重点——如果我正在编写一个调试器,我会找到一种方法来使用某种 jit 技术(直接更改可执行文件)就地编译断点条件——这并非不可能. 这是一个很好的观点,也是一个有趣的想法——你说得对,这样的事情并非不可能。尤其是在已经使用 JIT 的环境中。 您可以将调试器附加到现有进程。考虑到执行程序已经将 MSIL 编译为本机,因为它已经在运行,我认为这将大大增加 JIT 注入方法的复杂性。在那种情况下你会怎么做?您必须使框架动态使 JIT 代码过期,将断点代码注入 MSIL,然后即时重新 JIT?听起来已经很复杂了。【参考方案4】:

我认为这是因为执行条件需要时间。它仍然比手动步进必要的次数要快得多。

【讨论】:

【参考方案5】:

编译器可以优化(至少一点)添加的临时代码。 条件断点可能会跳转到一些 Visual Studio 代码,这些代码将手动检索所需信息以了解它是否真的需要暂停。

这可以解释为什么需要更多时间。 但我只是猜测。

【讨论】:

以上是关于为啥条件断点会在调试时降低应用程序的执行速度?的主要内容,如果未能解决你的问题,请参考以下文章

《软件调试艺术》读后感四

VS调试技巧:如何让断点在for循环中变量满足某个条件的时候停下来(条件调试)

VS调试技巧:如何让断点在for循环中变量满足某个条件的时候停下来(条件调试)

为啥在调试没有断点的访问区域时使用eclipse?

Eclipse 的一些调试技巧

实现 ABAP 条件断点的三种方式分享