先前的问题解释说,在x86上,被监视对象的大小受debugging寄存器的限制。 这里。 正如所料,我可以“看”一个双重variables。 但我不能看双数据库,例如
watch pObject->dPrice
产生
Hardware watchpoint 1: pObject->dPrice
但是,当你试图继续执行,它说
Could not insert hardware breakpoints: You may have requested too many hardware breakpoints/watchpoints.
即使这是唯一的断点/观察点。
我很好奇这是为什么,但更重要的是有办法解决这个问题吗? 根据gdb文档,如果它不能使用硬件,它可能会使用软件观察点。 在这种情况下,它不会尝试使用软件观察点 – 是否有办法强制这样做?
是的你可以:
设置can-use-hw-watchpoints 0
从5.1.2设置观察点 :
您可以通过设置can-use-hw-watchpoints 0命令强制gdb仅使用软件观察点。 将此变量设置为零,gdb将永远不会尝试使用硬件观察点,即使底层系统支持它们。 (请注意,将can-use-hw-watchpoints设置为零之前设置的硬件辅助观察点仍将使用观察表达式值的硬件机制。)
set can-use-hw-watchpoints
设置是否使用硬件观察点。
show can-use-hw-watchpoints
显示当前使用硬件观察点的模式。
我不是100%确定的,但我的理解是,当你观看pObject->dPrice
,gdb会尝试观察任何可以改变观察值的东西。
使用软件观察点,在每一步gdb检查表达式是否已经改变。 使用硬件观察点,gdb必须为dprice
设置一个观察点,正如你所期望的那样,而且也是为了pObject
。
现在,你把问题标记为“x86”。 在x86上,您可以设置多达4个字节的断点。 一个double是8个字节。 如果你想看双倍的话,我猜测gdb需要两个硬件观察点。 你也需要一个额外的观察点。 我猜gdb试图看所有的pObject
,这回到问题中的问题,你链接的问题。
当我想做类似的事情时,如果我确定指针pObject
不会改变,我通常会这样做:
p &pObject->dprice
比方说gdb说地址是(double *) 0xabcdef10
,现在我这样做:
watch (double *) *0xabcdef10
只看我想要的东西
注:我没有在我面前打开gdb,所以我可能有错误的关于watch
命令的确切语法(关于*
的位置),所以先检查一下。
简短的回答:使用watch -location pObject->dPrice
,或简短的watch -l
。
长答案: 引用GDB手册 :
观察引用许多变量的复杂表达式也会耗尽可用于硬件辅助观察点的资源。 这是因为gdb需要使用单独分配的资源来监视表达式中的每个变量。
gdb从字面上看它本身,而不是它指向的地址。 在这种情况下,这意味着如果将pObject
本身更改为指向一个新的dPrice
, dPrice
; 这不仅仅是pObject->dPrice
一个观察点,也是pObject
本身的一个观察点。 这可能比可用的更多。
一个更全面的例子:
//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->dPrice
并watch *(double*)0x12345678
,或者打印出的任何地址。