首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >设置GDB硬件监视点/如何设置软件监视点

设置GDB硬件监视点/如何设置软件监视点
EN

Stack Overflow用户
提问于 2010-08-12 18:15:24
回答 3查看 15.6K关注 0票数 24

先前的一个问题解释说,在x86上,所监视对象的大小受调试寄存器的限制。正如预期的那样,我可以“观察”一个双变量。但我不能看双倍的数据,例如,

代码语言:javascript
运行
复制
watch pObject->dPrice

产生

代码语言:javascript
运行
复制
Hardware watchpoint 1: pObject->dPrice

但是当你试图继续执行的时候,它说

无法插入硬件断点:您可能请求了太多的硬件断点/监视点。

尽管这是唯一的断点/观察点。

我很好奇为什么会这样,但更重要的是,有办法绕过它吗?根据GDB文档,如果它不能使用硬件,它可以使用软件监视点。在这种情况下,它没有尝试使用软件观察点--有没有办法强迫它这样做?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-08-12 18:42:41

不,你可以:

设置can-使用-hw-监视点0

来自5.1.2设置监视点

您可以强制GDB只使用软件监视点和set可以使用-hw-监视点0命令。如果将此变量设置为零,GDB将永远不会尝试使用硬件监视点,即使底层系统支持它们。(请注意,在将can hw-监视点设置为零之前设置的硬件辅助监视点仍将使用监视表达式值的硬件机制。)

set can-use-hw-watchpoints

是否使用硬件监视点。

show can-use-hw-watchpoints

显示当前使用硬件监视点的模式。

票数 22
EN

Stack Overflow用户

发布于 2017-02-15 13:29:37

简短的回答:使用watch -location pObject->dPrice,或简短的watch -l

较长答案:引用GDB手册

查看引用许多变量的复杂表达式也会耗尽硬件辅助监视点可用的资源。这是因为GDB需要使用单独分配的资源监视表达式中的每个变量。

GDB实际上是在观察表达式本身,而不是它所指向的任何地址。在本例中,这意味着如果pObject本身更改为指向新的dPrice,则断点就会命中;不仅有pObject->dPrice的监视点,而且还有pObject本身的观察点。这可能比现有的更多。

一个更全面的例子是:

代码语言: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 pObject->dPrice。(在2011年7月发布的GDB 7.3中,这是可用的;如果您使用的是旧版本,请使用print &pObject->dPricewatch *(double*)0x12345678,或者它打印的地址。)

票数 10
EN

Stack Overflow用户

发布于 2010-08-13 07:53:15

我不是百分之百确定,但我的理解是,当您观看pObject->dPrice时,GDB会尝试查看任何可以更改所监视值的内容。

使用软件监视点,在每个步骤之后,GDB检查表达式是否已更改。使用硬件监视点,GDB必须像您预期的那样为dprice设置一个监视点,但也必须为pObject设置一个监视点。

现在,你标记了'x86‘这个问题。在x86上,您可以设置最多4个字节的断点。双字节是八个字节。如果你想看一个双点,我猜GDB需要两个硬件监视点。您还需要为pObject提供一个额外的监视点。我猜GDB试图查看所有的pObject,这可以追溯到您在问题中链接到的问题。

当我想做类似的事情时,如果我确信指针pObject不会改变,我通常会这样做:

代码语言:javascript
运行
复制
p &pObject->dprice

假设GDB的地址是(double *) 0xabcdef10,现在我说:

代码语言:javascript
运行
复制
watch (double *) *0xabcdef10

只看我想看的。

注意:我前面没有打开GDB,所以我可能对watch命令有错误的确切语法(关于*的位置),所以首先检查它。

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

https://stackoverflow.com/questions/3470704

复制
相关文章

相似问题

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