6

函数局部变量上的观察点通常在函数返回时被删除,并显示消息«Watchpoint 7 deleted because the program has left the block in»。插图:

struct mystruct{
    int a, b, c;
};

void MyFunc(){
    mystruct obj;
    obj.a = 2;
}

int main(){
    MyFunc();
}

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      }

我尝试像wa *(mystruct *)&objand一样投射它wa *(mystruct *)(void*)&obj,但无济于事。

我需要它,因为我正在使用的嵌入式 ARM 设备上的 GDB 已损坏:有时它会无缘无故地删除观察点;然后回溯看起来像标有“??”的行 标志,以及有关损坏堆栈的消息。即使应用程序实际上很好。

4

1 回答 1

7

正如GDB:设置观察点所说,

当本地(自动)变量或涉及此类变量的表达式超出范围时,即执行离开定义这些变量的块时,GDB 会自动删除观察点。

但是,从 7.3 版开始(感谢 @Hi-Angel 和 IRC 上的用户parcs指出这一点;我错过了在文档中看到它的地方),该watch命令接受一个-location参数:

通常,观察点尊重 expr 中变量的范围(见下文)。-location 参数告诉 GDB 改为监视 expr 引用的内存。在这种情况下,GDB 将评估 expr,获取结果的地址,并观察该地址处的内存。结果的类型用于确定被监视内存的大小。

在旧版本的 GDB 上,您可以使用问题中的示例来运行它:

eval "watch *(mystruct *)%p", &obj

请注意,如果您正在查看的内存被另一个函数的局部变量重用,则查看堆栈上的位置可能会导致虚假通知。

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

(gdb) break MyFunc
(gdb) commands $bpnum
>watch obj
>continue
>end
于 2014-09-19T22:03:08.893 回答