GDB:如何在函数返回后强制观察点不被删除? [英] GDB: How to force a watchpoint to not be deleted after a function returned?
问题描述
如果一个观察点被设置在一个函数上,然后函数返回,那么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屋!