在 MSVC++ 调试器中,是否可以在一个函数中创建断点,其条件取决于其他堆栈帧中的局部变量?我经常发现自己在一个函数中创建了一个条件断点,当该断点命中时,我启用另一个断点(我希望在退出当前函数调用之前触发它)并继续。这既费时又容易出错。
我过去采用的一种方法是将相关变量写入全局变量,并将该全局变量用作条件。但这需要重新编译,并且不适用于多线程代码。
在 MSVC++ 调试器中,是否可以在一个函数中创建断点,其条件取决于其他堆栈帧中的局部变量?我经常发现自己在一个函数中创建了一个条件断点,当该断点命中时,我启用另一个断点(我希望在退出当前函数调用之前触发它)并继续。这既费时又容易出错。
我过去采用的一种方法是将相关变量写入全局变量,并将该全局变量用作条件。但这需要重新编译,并且不适用于多线程代码。
是的,这在技术上是可行的。请注意,没有什么大不了的,您必须告诉调试器取消引用指针以获取另一个堆栈帧中的局部变量的值。
一个简单的例子:
#include "stdafx.h"
#include <iostream>
void foo() {
for (int ix = 0; ix < 5; ++ix) {
std::cout << ix << " "; // <=== Conditional breakpoint here
}
}
void bar() {
for (int jx = 0; jx < 5; ++jx) {
std::cout << jx << ": "; // <=== Start with a breakpoint here
foo();
std::cout << std::endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
bar();
return 0;
}
您首先需要获取要设置条件的变量的地址。在 bar() 中的指示行上设置断点。当它命中时,评估&jx
并复制该值。
现在使用该值设置条件断点。我用了:
*(int*)0x0073fbc8 == 2 && ix == 3
其中 0x0073fbc8 是我在第一个断点处获得的值。或者您可以使其与基指针寄存器相对。设置一个无条件断点,当它命中时使用 Debug + Windows + Registers 来查看 EBP 值。从 &jx 值中减去它。我用了:
*(int*)(ebp+0xd8) == 2 && ix == 3
两者都运作良好。请注意,您需要为 Debug 构建关闭 ASLR,以希望这些地址在一次运行到另一次运行中可重复。项目 + 属性、链接器、高级、随机基地址 = 否。