【问题标题】:How to stop when a condition in if statement is satisfied, when debugging调试时如何在满足 if 语句中的条件时停止
【发布时间】:2013-07-08 04:35:53
【问题描述】:

调试时,如果满足if语句中的条件,如何停止? 例如:

if (!check()) {
  int a = 0;
}

int a = 0;是虚拟代码,然后我在那里放了一个断点。 如果我在一个空的 if 循环中放置一个断点,调试器就不会停在那里, 它只在可以执行的指令处停止。即使你做 int a;只是一个声明 它不会停止。

我可以用其他方式而不是编写虚拟代码吗?

谢谢

【问题讨论】:

  • 你的平台是什么?大多数调试器应该能够使用某种条件断点。
  • “它只在它可以执行的指令处停止”这让我想知道你是否可能以一种优化了这些指令的方式进行编译。
  • 更大的问题是,我认为,为什么你有一个空的 if 语句体?
  • 您不能在声明中设置断点,但如果您还初始化变量,通常可以。在int a = 0; 设置断点应该没有问题,假设您没有在编译时启用优化。但由于无论如何都是虚拟代码,只需在代码中使用断言或在调试器中使用条件断点。
  • @JoachimPileborg 他不想要空的 if 语句体。他只想在条件满足的时候有个断点。 user2381422,您应该按照 Matzi 所述进行断言

标签: c++ debugging breakpoints


【解决方案1】:

我可以用其他方式而不是编写虚拟代码吗?

是的!

在调试器中,您应该能够添加断点并将其设置为仅在满足特定条件时才中断。如何执行此操作取决于您的 IDE,但在我的 IDE 中,我可以右键单击代码编辑器排水沟或单独的断点窗口中的断点,然后从弹出菜单中选择属性。然后我得到这个对话框:

您可以看到我设置了“条件”属性,每次代码遇到该断点时都会评估该属性 - 但断点只会在条件为true 时中断。即,如果check() 在一切正常时返回true,则!check() 将在check() 返回false 时使其中断。

如果经常调用此方法,这往往会稍微减慢您的程序,因为通常要评估这样的表达式,调试器必须(内部)中断并评估某些内容。但它的功能很简洁。请注意您还可以设置的所有其他属性,而且在单击“高级”按钮后,这甚至还没有显示对话框的样子...

回答您的其他问题:

如果我在空的 if 循环中放置断点,调试器将不会停止 在那里,它只在可以执行的指令处停止。即使你这样做 诠释一个;只是一个不会停止的声明。

如果 if 块(不是循环)是空的,那么它就没有什么可以停止的了。它只能在实际代码上停止。 int a; 只是一个变量声明;对于简单类型,实际上不会为此生成任何代码。 (不过,它可以用于更复杂的类型,例如 MyClass a;,因为它会调用构造函数。)即使您编写更多代码:

if (!check()) {
  int a;
  a = 5;
  b = a;
}

您的编译器可能仍然不会为此生成任何代码,因为它可能会发现代码实际上从未执行任何操作。这在一定程度上取决于您的优化设置,但即使没有任何特定的优化设置,一些编译器也会对其进行优化。

有时由于各种原因(有时只是条件评估的速度),中断代码而不是使用 IDE 会很方便。在这种情况下,我倾向于使用函数调用来中断,因为编译器不知道函数不会修改程序的状态,也不能优化掉:

if (!check()) {
  rand(); // <- breakpoint here
}

但通常充分利用您的 IDE 和调试器功能是一种更好的方法。

编辑: 因为这得到了赞成(谢谢大家),我想我会添加另一种方法,以保持完整性。软件/调试器断点出现interrupt 3, which is patched in by the debugger. int 3 汇编指令只有一个字节长,因此可以修补任何其他指令;当程序中断时,可以暂时将旧指令修补回去。但是除了调试器在运行时将其放入,您还可以将其放入代码中。

换句话说,您可以通过类似的方式强制您的程序中断代码(并被调试器捕获;如果您不在调试器下运行,这可能会导致问题;通常,您的程序将中止)。语法取决于您的环境:

if (!check()) {
  __asm int 3
}

甚至更好的是,避免依赖环境的代码,许多 C++ 编译器都有内在函数或宏,例如 DebugBreak();__debugbreak,您可以像这样使用它们:

if (!check()) {
  DebugBreak();
}

当您在调试器下运行程序时,您会发现该行的执行中断。

没有理由正常使用它。我见过一个自定义断言处理程序,它在断言失败时中断调试器,但允许之后继续执行。

【讨论】:

    【解决方案2】:

    使用assertion。它用于调试时错误检查。如果条件为假(等于零),则执行立即停止。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多