Hi-*_*gel 4 debugging gdb watchpoint
关于函数局部变量的观察点通常会在函数返回时被删除,并显示消息«Watchpoint 7已删除,因为程序已将块保留在»中.插图:
struct mystruct{
int a, b, c;
};
void MyFunc(){
mystruct obj;
obj.a = 2;
}
int main(){
MyFunc();
}
Run Code Online (Sandbox Code Playgroud)
gdb会话示例
(gdb) b 7
Breakpoint 1 at 0x4004f1: file /tmp/test2.cpp, line 7.
(gdb) r
Starting program: /tmp/test2
Breakpoint 1, MyFunc () at /tmp/test2.cpp:7
7 obj.a = 2;
(gdb) wa obj
Hardware watchpoint 2: obj
(gdb) c
Continuing.
Hardware watchpoint 2: obj
Old value = {a = 4195600, b = 0, c = 4195328}
New value = {a = 2, b = 0, c = 4195328}
MyFunc () at /tmp/test2.cpp:8
8 }
(gdb) c
Continuing.
Watchpoint 2 deleted because the program has left the block in
which its expression is valid.
main () at /tmp/test2.cpp:12
12 }
Run Code Online (Sandbox Code Playgroud)
我试图铸造它喜欢wa *(mystruct *)&obj和wa *(mystruct *)(void*)&obj,都无济于事.
我需要它,因为我正在使用的嵌入式ARM设备上的GDB被破坏了:有时它会毫无理由地删除一个观察点; 回溯然后看起来像标有"??"的行 标志和关于损坏的堆栈的消息.即使应用程序实际上很好.
正如GDB:设置观察点所说,
当GDB超出范围时,即当执行离开定义了这些变量的块时,GDB会自动删除监视本地(自动)变量或涉及此类变量的表达式的观察点.
但是,从7.3版开始(感谢@ Hi-Angel和IRC上的用户parcs指出这一点;我错过了在文档中看到它),该watch命令接受一个-location参数:
通常,观察点尊重expr中变量的范围(见下文).-location参数告诉GDB改为查看expr引用的内存.在这种情况下,GDB将评估expr,获取结果的地址,并观察该地址的内存.结果的类型用于确定监视内存的大小.
在旧版本的GDB上,您可以使用您问题中的示例来运行它:
eval "watch *(mystruct *)%p", &obj
Run Code Online (Sandbox Code Playgroud)
请注意,如果您正在观看的内存被其他函数的局部变量重用,则在堆栈上观察位置可能会导致虚假通知.
作为替代方案,您可以自动在自动变量上设置观察点,该变量不断进入和退出范围.在一个断点处设置一个断点 - 例如,在声明它的函数或块的开头 - 然后附加一个watch和continue命令:
(gdb) break MyFunc
(gdb) commands $bpnum
>watch obj
>continue
>end
Run Code Online (Sandbox Code Playgroud)