Watchpoint is a feature similar to Breakpoint, but instead of stopping when the Program Counter reach a function or code line, watchpoint stops when an address memory is read (rwatch), write (watch) or read/write (awatch).
Watchpoints are very useful when you are doing reverse engineering or when you want to debug a code that access many registers.
First we need to know if our processor supports hardware watchpoints:
(gdb) show can-use-hw-watchpoints Debugger's willingness to use watchpoint hardware is 1.
Case your uP/uC doesn’t, no problem! It will work, but with Software Watchpoint ( *slow* )
Some processors (i.e. PowerPC) support masking a memory position, then any address accessed in this area will generate a stop condition:
(gdb) watch *0xdeadbeef mask 0xffffff00
Unfortunately my microcontroller (ARM Cortex-M0+) doesn’t support:
(gdb) awatch *0x40000000 mask 0xffff0000 This target does not support masked watchpoints.
In this case I need to add many watchpoints manually:
(gdb) b main Breakpoint 1 at 0x1c3a: file ../src/qs_i2c_master_basic_use.c, line 108. (gdb) c Continuing. Breakpoint 1, main () at ../src/qs_i2c_master_basic_use.c:108 108 system_init(); (gdb) n 113 configure_i2c_master(); (gdb) awatch *0x40000000 mask 0xffff0000 This target does not support masked watchpoints. (gdb) awatch *0x40002800 Hardware access (read/write) watchpoint 2: *0x40002800 (gdb) awatch *0x40002804 Hardware access (read/write) watchpoint 3: *0x40002804 (gdb) awatch *0x40002808 Hardware access (read/write) watchpoint 4: *0x40002808 (gdb) awatch *0x40002828 Hardware access (read/write) watchpoint 5: *0x40002828 (gdb) awatch *0x400018d0 Hardware access (read/write) watchpoint 6: *0x400018d0 (gdb) awatch *0x42000800 Hardware access (read/write) watchpoint 7: *0x42000800 (gdb) awatch *0x42000804 Hardware access (read/write) watchpoint 8: *0x42000804 (gdb) awatch *0x4200080c Hardware access (read/write) watchpoint 9: *0x4200080c (gdb) awatch *0x42000814 Hardware access (read/write) watchpoint 10: *0x42000814 (gdb) awatch *0x42000816 Hardware access (read/write) watchpoint 11: *0x42000816 (gdb) awatch *0x42000818 Hardware access (read/write) watchpoint 12: *0x42000818 (gdb) awatch *0x4200081a Hardware access (read/write) watchpoint 13: *0x4200081a (gdb) awatch *0x4200081c Hardware access (read/write) watchpoint 14: *0x4200081c (gdb) awatch *0x42000824 Hardware access (read/write) watchpoint 15: *0x42000824 (gdb) awatch *0x42000828 Hardware access (read/write) watchpoint 16: *0x42000828 (gdb) c Continuing. Program received signal SIGTRAP, Trace/breakpoint trap. 0x000016f0 in system_gclk_chan_disable (channel=20 '24') at ../src/ASF/sam0/drivers/system/clock/clock_saml21/gclk.c:371 371 GCLK->PCHCTRL[channel].reg &= ~GCLK_PCHCTRL_CHEN;
Sources:
http://stackoverflow.com/questions/58851/can-i-set-a-breakpoint-on-memory-access-in-gdb
https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html