The Science of Debugging
Chapter 6


6.5.3 Watchpoints

Watchpoints are one of those things that even many veteran gdb debuggers forget to use. It's strange too, because it's an incredibly powerful command. A watchpoint is a breakpoint which is triggered when a variable being watched is either read or modified.

I'll give you a moment of silence to realize how cool that is.

Okay, enough silence, back to the code.

There are two commands to set a watchpoint, 'watch' and 'rwatch'. They set a write watchpoint and a read watchpoint, respectively, and both take a variable as an argument. That means that a variable with a watch watchpoint will cause a program to halt when it is written to, and a read watchpoint will do the same when that variable is read. If you're very determined, you can also use 'awatch' which sets both a read and write watchpoint with just one command. We're going to use a new short program, cut and paste below and save as gdbex3.c. Compile it and load it into gdb, but don't run it yet.

#include 

int main(int argc, char *argv[])
{
  int i = 1;
  int j = 2;

  j = i;

  return 0;
}
Unfortunately, we can't just set a watchpoint on a variable that isn't global. You'll have to wait until the variable comes into scope, or else gdb has no idea which instance of a given variable you're looking for. This isn't too hard to setup though; create a temporary breakpoint in the function with the variable you want to use. I did this, but I'll leave that as an exercise to the reader. Once we've gotten the variable in scope , we simply use the commands listed above:

(gdb) watch j
Hardware watchpoint 4: j
(gdb)






The very observant of you may notice that gdb declares there's a watchpoint on the variable 'j' at line 4. It's obvious that's wrong. I can't really explain this very well, but it has to do with some wierd things involving scope, and the fact that the program's execution must actually pass through the line with the variable initialization in order to acquire it as a variable in gdb's memory. Confusing, and really, it makes no difference, so ignore it.

Now, we get to see what happens when we 'continue' on.

(gdb) continue
Continuing.
Hardware watchpoint 4: j

Old value = 2
New value = 1
main (argc=1, argv=0xbffffd04) at gdbex3.c:10
10       return 0;











Once again, gdb is a little mucked up when it comes to figuring out the initialization line and the sort. Once again, ignore it. Execution will be placed at the start of the next line, and, as we can see, the old and new values are displayed for all to see.

You can use the command 'info breakpoints' to see all the watchpoints you have set, and the 'disable' command will let you disable them, just like a breakpoint.



Index
6.1.4.2 Advanced Breakpoints 6.1.4.4 Stepping Through Code