GDB:如何强制在返回函数后不删除监视点?

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 *)&objwa *(mystruct *)(void*)&obj,都无济于事.

我需要它,因为我正在使用的嵌入式ARM设备上的GDB被破坏了:有时它会毫无理由地删除一个观察点; 回溯然后看起来像标有"??"的行 标志和关于损坏的堆栈的消息.即使应用程序实际上很好.

Mar*_*ick 7

正如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)

请注意,如果您正在观看的内存被其他函数的局部变量重用,则在堆栈上观察位置可能会导致虚假通知.

作为替代方案,您可以自动在自动变量上设置观察点,该变量不断进入和退出范围.在一个断点处设置一个断点 - 例如,在声明它的函数或块的开头 - 然后附加一个watchcontinue命令:

(gdb) break MyFunc
(gdb) commands $bpnum
>watch obj
>continue
>end
Run Code Online (Sandbox Code Playgroud)

  • 在IRC#gdb parcs上也提供了更简单的解决方案:只需使用`watch -l obj`. (3认同)