An earlier question explained that on x86 the size of objects being watched is limited by debug registers. here. As expected, I can "watch" a double variable. But I can't watch a double datamember, eg

watch pObject->dPrice

produces

Hardware watchpoint 1: pObject->dPrice

But when you try to continue execution, it says

Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.

even though this is the only breakpoint/watchpoint.

I'm curious why this is so, but more importantly is there a way around it? According to gdb docs it may use software watchpoints if it can't use hardware. In this case it makes no attempt to use a software watchpoint -- is there a way to force it to do so?

2 Answers
2

You can force gdb to use only software watchpoints with the set can-use-hw-watchpoints 0 command. With this variable set to zero, gdb will never try to use hardware watchpoints, even if the underlying system supports them. (Note that hardware-assisted watchpoints that were set before setting can-use-hw-watchpoints to zero will still use the hardware mechanism of watching expression values.)

I'm not 100% sure, but my understanding is that when you watch pObject->dPrice, gdb tries to watch anything that can change the watched value.

Using software watchpoints, after each step gdb checks if the expression has changed. Using hardware watchpoints, gdb has to set a watchpoint for dprice, as you expect, but also for pObject.

Now, you tagged the question 'x86'. On x86 you can set breakpoints for up to 4 bytes. A double is 8 bytes. If you want to watch a double, I would guess that gdb would need two hardware watchpoints. You need an additional watchpoint for pObject as well. I'm guessing that gdb tries to watch all of pObject, which goes back to the problem in the question you linked in the question.

When I want to do something similar, if I'm certain that the pointer pObject will not change, I usually do:

p &pObject->dprice

Let's say gdb says the address is (double *) 0xabcdef10, now I do:

watch (double *) *0xabcdef10

and watch only what I want to.

Note: I don't have gdb open in front of me, so I may have the exact syntax for the watch command wrong (regarding the placement of the *), so check it out first.