首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当只有一个观察点时,gdb会停止并显示过多的观察点。

当只有一个观察点时,gdb会停止并显示过多的观察点。
EN

Stack Overflow用户
提问于 2010-07-09 01:32:48
回答 3查看 14.5K关注 0票数 19

除了硬件断点/观察点太多之外,您是否知道无法插入观察点的任何其他原因?

我有以下调试会话:

代码语言:javascript
复制
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

正如您所看到的,只有一个观察点,但它不能插入断点。

你知道我该怎么解决这个问题吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-07-09 02:20:38

据我所知,商用x86 CPU有四个debug registers可用于支持硬件中断/监视。这限制了您可以观察的对象大小。对象对齐在这里也起作用。

尝试将监视范围限制为较小的对象,如结构的第一个和最后一个成员对。

票数 17
EN

Stack Overflow用户

发布于 2011-01-15 06:43:06

可以通过运行以下命令强制软件断点(没有大小限制)

设置can-use-hw-观察点%0

票数 12
EN

Stack Overflow用户

发布于 2017-02-15 21:49:28

简单的回答:使用watch -location itrap_t_beg[1][222],或者简称为watch -l

冗长的答案:Quoting the GDB manual

监视引用了许多变量的复杂表达式也会耗尽硬件辅助观察点可用的资源。这是因为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系列仅支持四个同步观察点。

关于观察点如何工作的更全面的示例:

代码语言:javascript
复制
//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;
}

从理论上讲,这是一个有用的特性;您可以观察一个复杂的表达式,只要它是假的,就会立即断开,这有点像一个不断测试的断言。例如,您可以在上面的程序中使用watch a==b

在实践中,这是意想不到的,经常会触发这个问题,而且通常不是您想要的。

要仅查看目标地址,请使用watch -location itrap_t_beg[1][222]。(这是从2011年7月发布的gdb7.3开始提供的;如果您仍然使用7.1,请使用print &itrap_t_beg[1][222]watch *(itrap_t)0x12345678,或者使用它打印的任何地址。)

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3206332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档