调试时如何在满足 if 语句中的条件时停止?例如:
if (!check()) {
int a = 0;
}
int a = 0; 是虚拟代码,然后我在那里放了一个断点。如果我在一个空的 if 循环中放置一个断点,调试器不会停在那里,它只会在它可以执行的指令处停止。即使你做 int a; 只是一个声明,它不会停止。
我可以用其他方式而不是编写虚拟代码来做到这一点吗?
谢谢
调试时如何在满足 if 语句中的条件时停止?例如:
if (!check()) {
int a = 0;
}
int a = 0; 是虚拟代码,然后我在那里放了一个断点。如果我在一个空的 if 循环中放置一个断点,调试器不会停在那里,它只会在它可以执行的指令处停止。即使你做 int a; 只是一个声明,它不会停止。
我可以用其他方式而不是编写虚拟代码来做到这一点吗?
谢谢
我可以用其他方式而不是编写虚拟代码来做到这一点吗?
是的!
在调试器中,您应该能够添加断点并将其设置为仅在满足特定条件时才中断。如何执行此操作取决于您的 IDE,但在我的 IDE 中,我可以右键单击代码编辑器排水沟或单独的断点窗口中的断点,然后从弹出菜单中选择属性。然后我得到这个对话框:
您可以看到我设置了“条件”属性,每次代码遇到该断点时都会对其进行评估 - 但断点只会在条件为true
. 即,如果一切正常时返回,则check()
返回true
时!check()
将使其中断。check()
false
如果经常调用此方法,这往往会稍微减慢您的程序,因为通常要评估这样的表达式,调试器必须(内部)中断并评估某些内容。但它的功能很简洁。请注意您还可以设置的所有其他属性,并且在单击“高级”按钮后,甚至还没有看到对话框的样子......
要回答您的其他问题:
如果我在一个空的 if 循环中放置一个断点,调试器不会停在那里,它只会在它可以执行的指令处停止。即使你做 int a; 只是一个声明,它不会停止。
如果 if 块(不是循环)是空的,那么它就没有什么可以停止的了。它只能在实际代码上停止。 int a;
只是一个变量声明;对于简单类型,实际上没有为此生成任何代码。(例如,它可以用于更复杂的类型,MyClass a;
因为这会调用构造函数。)即使您编写更多代码:
if (!check()) {
int a;
a = 5;
b = a;
}
您的编译器可能仍然不会为此生成任何代码,因为它可能会发现代码实际上从未执行任何操作。这在一定程度上取决于您的优化设置,但即使没有任何特定的优化设置,一些编译器也会对其进行优化。
有时,由于各种原因(有时只是条件评估的速度),中断代码而不是使用 IDE 会很方便。在这种情况下,我倾向于使用函数调用来中断,因为编译器不会知道该函数不会修改程序的状态,也无法对其进行优化:
if (!check()) {
rand(); // <- breakpoint here
}
但通常充分利用您的 IDE 和调试器功能是一种更好的方法。
编辑:因为这得到了赞成(谢谢大家),为了完整起见,我想我会添加另一种方法。软件/调试器断点与中断 3 一起出现,由调试器修补。 汇编指令只有一个字节长,因此int 3
可以在任何其他指令上进行修补;当程序中断时,可以临时修补旧指令。但是除了调试器在运行中将其放入之外,您还可以将其放入代码中。
换句话说,您可以通过类似的方式强制您的程序中断代码(并被调试器捕获;如果您不在调试器下运行,这可能会导致问题;通常,您的程序将中止)。语法取决于您的环境:
if (!check()) {
__asm int 3
}
甚至更好的是,避免依赖于环境的代码,许多 C++ 编译器具有内在函数或宏,例如DebugBreak();
或__debugbreak
您可以像这样使用它们:
if (!check()) {
DebugBreak();
}
当您在调试器下运行程序时,您会发现该行的执行中断。
几乎没有理由正常使用它。我见过的一个自定义断言处理程序在断言失败时会中断调试器,但允许之后继续执行。
使用断言。它用于调试时错误检查。如果条件为假(等于零),则执行立即停止。