【问题标题】:GDB: How to force a watchpoint to not be deleted after a function returned?GDB:如何在函数返回后强制不删除观察点?
【发布时间】:2014-11-14 08:07:21
【问题描述】:

函数局部变量上的观察点通常会在函数返回时被删除,并显示消息«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 *)&objwa *(mystruct *)(void*)&obj,但无济于事。

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

【问题讨论】:

    标签: debugging gdb watchpoint


    【解决方案1】:

    正如GDB: Setting Watchpoints 所说,

    当监视本地(自动)变量或涉及此类变量的表达式超出范围时,即执行离开定义这些变量的块时,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
    

    【讨论】:

    • 好的,但不是这样wa *(mystruct *)&obj 我会强制gdb 只看一段内存而不是有范围的变量?
    • 顺便说一句,我无法设置 commands,因为我什至不知道当 gdb 认为变量从作用域中消失时,问题在实际代码中的位置。正如我提到的,gdb 目前甚至没有显示足够的回溯。
    • 我添加了一种使用原始地址为内存区域创建观察点的方法的描述。它不会被 GDB 自动删除。请记住,函数返回后,用于自动变量的内存可以被后续函数调用重用,因此堆栈上原始地址的观察点可能会显示不相关的更改。
    • 在 IRC #gdb parcs 上也提供了更简单的解决方案:只需使用 watch -l obj
    • 好的,我看到 -location 是在 GDB 7.3 中添加的。我已经更新了我的答案。谢谢你和parcs。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多