除了太多硬件断点/观察点之外,您是否知道为什么无法插入观察点?
我有以下调试会话:
GNU gdb (GDB) 7.1
...
(gdb) watch itrap_t_beg[1][222]
Hardware watchpoint 1: itrap_t_beg[1][222]
(gdb) cont
Continuing.
...
Hardware watchpoint 1: itrap_t_beg[1][222]
...
(gdb) cont
Continuing.
Warning:
Could not insert hardware watchpoint 1.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.
(gdb) info break
Num Type Disp Enb Address What
1 hw watchpoint keep y itrap_t_beg[1][222]
breakpoint already hit 1 time
Run Code Online (Sandbox Code Playgroud)
如您所见,只有一个观察点,但它无法插入断点.
你知道我怎么解决这个问题?
拍摄答案:使用watch -location itrap_t_beg[1][222],或简称watch -l。
长答案:引用 GDB 手册:
观察引用许多变量的复杂表达式也会耗尽硬件辅助观察点的可用资源。那是因为 gdb 需要使用单独分配的资源监视表达式中的每个变量。
gdb 从字面上看是监视表达式本身,而不是它指向的任何地址。在这种情况下,这意味着如果itrap_t_beg自身发生更改,则断点将命中itrap_t_beg[1][222];不仅有一个观察点itrap_t_beg[1][222],还有一个观察点itrap_t_beg。这可能比可用的更多。
在您的情况下,itrap_t_beg是 7 个整数,28 个字节。x86_64 观察点最多为 8 个字节,因此 GDB 需要整个结构的四个观察点 - 再加上第五个观察点itrap_t_beg。x86 系列仅支持四个同步观察点。
关于观察点如何工作的更全面的例子:
//set a watchpoint on '*p' before running
#include <stdio.h>
int a = 0;
int b = 0;
int c = 0;
int* p = &a;
int main()
{
puts("Hi"); // Dummy lines to make the results clearer, watchpoints stop at the line after the change
*p = 1; // Breaks: *p was changed from 0 to 1
puts("Hi");
a = 2; // Breaks: a is *p, which changed from 1 to 2
puts("Hi");
p = &b; // Breaks: p is now b, changing *p from 2 to 0
puts("Hi");
p = &c; // Doesn't break: while p changed, *p is still 0
puts("Hi");
p = NULL; // Breaks: *p is now unreadable
puts("Hi");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
理论上,这是一个有用的功能;你可以观察一个复杂的表达式,一旦它是错误的就会被破坏,有点像一个不断测试的断言。例如,你可以watch a==b在上面的程序中。
在实践中,这是出乎意料的,经常触发这个问题,通常不是你想要的。
要仅查看目标地址,请使用watch -location itrap_t_beg[1][222]. (自 2011 年 7 月发布的 GDB 7.3 起可用;如果您仍在使用 7.1,请使用print &itrap_t_beg[1][222]andwatch *(itrap_t)0x12345678或它打印的任何地址。)