Using Watchpoints in the GDB to verify register access

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

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s