简体   繁体   中英

For gdb, should an rwatch breakpoint activate the commands written to that breakpoint? Mine don't

After I finished writing this I saw that rwatch actives a signal, SIGTRAP, which seems to be different than a breakpoint. I'm confused now because the command 'info breakpoints' still lists it as a breakpoint.

I don't know if this is expected behavior or if I'm setting up something wrong. I have a setup running gdb (from ARM toolchain) and openocd with the target being a stm32 discovery board. I'm trying to run certain gdb commands on a watchpoint using the command

commands [breakpointnumber]

Then I add the commands when prompted, I'm using 'px' and 'py' to print the x and y variable, and end it with 'end' like it says I should.

This does work when I set a breakpoint using

b [linenumber]

Here is an example of it running on gdb

(gdb) b 15
Breakpoint 5 at 0x8000134: file main.c, line 15.
(gdb) commands 5
Type commands for breakpoint(s) 5, one per line.
End with a line saying just "end".
>p x
>p y
>end
(gdb) info breakpoints
Num     Type           Disp Enb Address    What
5       breakpoint     keep y   0x08000134 in main at main.c:15
        p x
        p y
(gdb) c
Continuing.

Breakpoint 5, main () at main.c:15
15          y++;
$21 = 46 '.'
$22 = 44 ','
(gdb) c
Continuing.

Breakpoint 5, main () at main.c:15
15          y++;
$23 = 47 '/'
$24 = 46 '.'
(gdb) c
Continuing.

Breakpoint 5, main () at main.c:15
15          y++;
$25 = 48 '0'
$26 = 48 '0'

but if I use the rwatch command such as

rwatch x

and set the commands like before, those commands don't run when the program reaches the rwatch breakpoint. Here is gdb running using rwatch

(gdb) delete
Delete all breakpoints? (y or n) y
(gdb) rwatch x
Hardware read watchpoint 6: x
(gdb) commands 6
Type commands for breakpoint(s) 6, one per line.
End with a line saying just "end".
>p x
>p y
>end
(gdb) info breakpoints
Num     Type            Disp Enb Address    What
6       read watchpoint keep y              x
        p x
        p y
(gdb) c
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0800012c in main () at main.c:14
14          x++;
(gdb) c
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0800012c in main () at main.c:14
14          x++;
(gdb) c
Continuing.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0800012c in main () at main.c:14
14          x++;

I have deleted all other breakpoints. Using 'info breakpoints' shows the commands are associated with the breakpoint

It's just a test program as I learn gdb and openocd so it's really short.

#include "stdint.h"
  5 uint8_t checker = 0x50;
  4 uint8_t x = 0x21;
  3 uint8_t y = 0x14;
  2 int main(void)
  1 {
12      while(1)
  1     {
  2         x++;
  3         y++;
  4         y++;
  5         ;
  6         if(x == 5000)
  7         {
  8             x = 0;
  9         }
 10         if(y == 10000)
 11         {
 12             y = 0;
 13         }
 14     }
 15 }

I suspect that this is an openocd bug. That the watchpoint is being reported as a SIGTRAP is not the correct behaviour, but most likely reflects what GDB is being told by openocd.

If we look at the behaviour of GDB running on native Linux, I see this behaviour:

$ gdb -q test
Reading symbols from test...
(gdb) start
Temporary breakpoint 1 at 0x401123: file test.c, line 10.
Starting program: /tmp/rwatch/test 

Temporary breakpoint 1, main () at test.c:10
10    int var = 0;
(gdb) rwatch var
Hardware read watchpoint 2: var
(gdb) commands
Type commands for breakpoint(s) 2, one per line.
End with a line saying just "end".
>echo hello world\n
>end
(gdb) c
Continuing.

Hardware read watchpoint 2: var

Value = 0
main () at test.c:12
12    func (&var);
hello world
(gdb) 

And, if I use gdbserver , then I see the same behaviour:

> gdb -q test
Reading symbols from test...
(gdb) target remote :54321
Remote debugging using :54321
... snip lots of library loading text ...
(gdb) b main
Breakpoint 1 at 0x401123: file test.c, line 10.
(gdb) c
Continuing.
... snip lots more library loading text ...
Breakpoint 1, main () at test.c:10
10    int var = 0;
(gdb) rwatch var
Hardware read watchpoint 2: var
(gdb) command
Type commands for breakpoint(s) 2, one per line.
End with a line saying just "end".
>echo hello world\n
>end
(gdb) c
Continuing.

Hardware read watchpoint 2: var

Value = 0
main () at test.c:12
12    func (&var);
hello world
(gdb) 

So we can see that GDB can handle read watchpoints better than just reporting a SIGTRAP, so I suspect the problem here is openocd reporting that the stop is due to a SIGTRAP, rather than being due to a read watchpoint triggering.

You might be able to work around this problem by making use of the Python API, there is a gdb.StopEvent , you could catch these and then try printing out the variables you are interested in maybe? The following Python code, placed into a file and then sourced into GDB should do the job:

def stop_handler (event):
    if (type (event) == gdb.SignalEvent
        and event.stop_signal == 'SIGTRAP'):
        print ("Use gdb.execute to run arbitrary commands here!")

gdb.events.stop.connect (stop_handler)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM