Watching expressions that don't involve memory (e.g., watch $regfoo)

Pedro Alves
2010-03-04T01:57:05Z

Anyone else things this is useful? Here's a 5 minute hack at it.

It allows for e.g.:

(top-gdb) watch $rax
Watchpoint 4: $rax
(top-gdb) c
Continuing.
Watchpoint 4: $rax

Old value = 11802104
New value = 140737488347216
0x0000000000456647 in main (argc=1, argv=0x7fffffffe158) at ../../src/gdb/gdb.c:28
28 memset (&args, 0, sizeof args);
(top-gdb)

Current GDB will successfuly create the watchpoint in the
breakpoint list, but it never triggers, because since the
watchpoint isn't watching any memory, it ends up with
no bp_location associated.

For extra fun, even watching $_siginfo works.

--
Pedro Alves

2010-03-04 Pedro Alves <pedro@codesourcery.com>

* breakpoint.c (update_watchpoint): Create a sentinel location if
the software watchpoint isn't watching any memory.
(breakpoint_address_bits): Skip dummy software watchpoint locations.

* NEWS: Mention support for watching expressions that don't
involve memory.

---
gdb/NEWS | 6 ++++++
gdb/breakpoint.c | 20 +++++++++++++++++++-
2 files changed, 25 insertions(+), 1 deletion(-)

Index: src/gdb/breakpoint.c
===================================================================
--- src.orig/gdb/breakpoint.c 2010-03-04 01:17:24.000000000 +0000
+++ src/gdb/breakpoint.c 2010-03-04 01:50:42.000000000 +0000
@@ -1237,6 +1237,19 @@ update_watchpoint (struct breakpoint *b,
value_free (v);
}

+ /* If a software watchpoint is not watching any memory, then it
+ will not have any location set up yet. But,
+ bpstat_stop_status requires a location to be able to report
+ stops, so add a sentinel one now. */
+ if (b->type == bp_watchpoint && b->loc == NULL)
+ {
+ b->loc = allocate_bp_location (b);
+ b->loc->pspace = frame_pspace;
+ b->loc->address = -1;
+ b->loc->length = -1;
+ b->loc->watchpoint_type = -1;
+ }
+
/* We just regenerated the list of breakpoint locations.
The new location does not have its condition field set to anything
and therefore, we must always reparse the cond_string, independently
@@ -4516,7 +4529,12 @@ breakpoint_address_bits (struct breakpoi

for (loc = b->loc; loc; loc = loc->next)
{
- int addr_bit = gdbarch_addr_bit (loc->gdbarch);
+ int addr_bit;
+
+ if (b->type == bp_watchpoint && loc->watchpoint_type == -1)
+ continue;
+
+ addr_bit = gdbarch_addr_bit (loc->gdbarch);
if (addr_bit > print_address_bits)
print_address_bits = addr_bit;
}
Index: src/gdb/NEWS
===================================================================
--- src.orig/gdb/NEWS 2010-03-04 01:44:06.000000000 +0000
+++ src/gdb/NEWS 2010-03-04 01:45:37.000000000 +0000
@@ -3,6 +3,12 @@

*** Changes since GDB 7.1

+* Watchpoints on expressions not involving memory
+
+ GDB now supports watching expressions that don't involve memory.
+ This allows, for example, watching for register changes.
+ E.g. "watch $pc" will do the right thing.
+
* X86 general purpose registers

GDB now supports reading/writing byte, word and double-word x86