GDB:如何在函数返回后强制观察点不被删除? [英] GDB: How to force a watchpoint to not be deleted after a function returned?

查看:268
本文介绍了GDB:如何在函数返回后强制观察点不被删除?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果一个观察点被设置在一个函数上,然后函数返回,那么GDB总是会删除一个观察点,并显示一条消息,如«观察点7被删除,因为程序已经将块留在»中。下面只是一个例子来说明:

  struct mystruct {
int a,b,c;
// char arr [16];
};

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

int main(){
MyFunc();
}

gdb会话示例

 (gdb)b 8 
0x4004f1的断点1:file /tmp/test2.cpp,第8行。
(gdb) r
开始程序:/ tmp / test2

断点1,MyFunc()在/tmp/test2.cpp:8
8 obj.a = 2;
(gdb)wa obj
硬件观察点2:obj
(gdb)c
继续。
硬件观察点2:obj

旧值= {a = 4195600,b = 0,c = 4195328}
新值= {a = 2,b = 0,c = 4195328}
MyFunc()在/tmp/test2.cpp:9
9}
(gdb)c
继续。

观察点2被删除,因为程序已经将其表达式有效的块
中的块删除。
main()at /tmp/test2.cpp:13
13}

我试图像 wa *(mystruct *)& obj 一样转换观察点,甚至像 wa *(mystruct *)(void *) & obj 但在返回一个函数后,一个观察点总是被删除。



我需要它,因为ARM上的GDB被某种方式搞砸了:没有真正的理由去除观察点;如果在这一刻看回溯,它会显示几行标有??的行。标志,并写入关于损坏的堆栈。但实际上应用程序工作,所以它是一个GDB的问题。

说:

$ block $ $ b

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


然而,从7.3版开始(感谢IRC上的@ Hi-Angel和user parcs 我错过了在文档中看到它), watch 命令接受一个 -location 参数:


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


在旧版本的GDB中,您可以运行此代码,使用你的问题的例子:

  evalwatch *(mystruct *)%p,& obj 

请注意,如果您正在观看的内存被其他函数的本地重用,堆栈中的位置可能会导致虚假通知变量。

另一种方法是,您可以自动设置一个自动变量的观察点,该自动变量不断进入和退出示波器。在一个断点处设置一个断点 - 例如,在声明它的函数或块的开头 - 然后附加一个 watch 继续命令:

 (gdb)break MyFunc 
(gdb)命令$ bpnum
> watch obj
> continue
> end


If a watchpoint was set on a function and then the function returned, the GDB always removes a watchpoint with a message like «Watchpoint 7 deleted because the program has left the block in». Below just an example to illustrate:

struct mystruct{
    int a, b, c;
    //char arr[16];
};

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

int main(){
    MyFunc();
}

gdb session example

(gdb) b 8
Breakpoint 1 at 0x4004f1: file /tmp/test2.cpp, line 8.
(gdb) r
Starting program: /tmp/test2 

Breakpoint 1, MyFunc () at /tmp/test2.cpp:8
8               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:9
9       }
(gdb) c
Continuing.

Watchpoint 2 deleted because the program has left the block in
which its expression is valid.
main () at /tmp/test2.cpp:13
13      }

I am tried to cast the watchpoint like wa *(mystruct *)&obj and even like wa *(mystruct *)(void*)&obj but after a function returned a watchpoint always deleted.

I am need it because GDB on ARM is somehow screwed: it is sometimes without a real reason removes a watchpoint; if in this moment look at the backtrace it is shows a few lines marked with "??" signs, and writes about a corrupted stack. But in fact application working, so it is rather a GDB problem.

解决方案

As GDB: Setting Watchpoints says,

GDB automatically deletes watchpoints that watch local (automatic) variables, or expressions that involve such variables, when they go out of scope, that is, when the execution leaves the block in which these variables were defined.

However, as of release 7.3 (thanks to @Hi-Angel and user parcs on IRC for pointing this out; I missed seeing it right there in the documentation), the watch command accepts a -location argument:

Ordinarily a watchpoint respects the scope of variables in expr (see below). The -location argument tells GDB to instead watch the memory referred to by expr. In this case, GDB will evaluate expr, take the address of the result, and watch the memory at that address. The type of the result is used to determine the size of the watched memory.

On older versions of GDB, you can run this instead, using the example from your question:

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

Note that watching locations on the stack may cause spurious notifications if the memory you're watching gets reused by another function's local variables.

As an alternative, you can automate the setting of a watchpoint on an automatic variable that keeps coming into and out of scope. Set a breakpoint at a point where it's in scope - for example, at the beginning of the function or block in which it's declared - then attach a watch and continue command:

(gdb) break MyFunc
(gdb) commands $bpnum
>watch obj
>continue
>end

这篇关于GDB:如何在函数返回后强制观察点不被删除?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆