question about ARM watchpoints

Joel Brobecker
Mon Sep 1 08:57:00 GMT 2014


Some of our ARM bareboard testing is done over QEMU, and we came
across an issue with watchpoints. The testcase is very simple:
We set a watchpoint on a integer global variable, and then
resume the execution until the variable gets updated.

Everything works pretty well, except that we noticed that GDB stops
2 instructions after the variable update, rather than at the next
instruction. For instance, this is the code we have:

       0x00000060:    movt    r3, #0
       0x00000064:    str     r2, [r3]  <<<--- new value stored here
       0x00000068:    pop     {r11, pc}

Looking at the infrun+remote debug traces, we can see that QEMU sends
GDB a watchpoint event with the PC set to the insn after the store:

    infrun: stop_pc = 0x68
    infrun: stopped by watchpoint
    infrun: stopped data address = 0xd820

At this point, GDB then does a single-step, which takes us past
the "pop" to the next instruction. My guess is that GDB probably
thinks that we got notified before the watched data got modified,
and thus needs to do a single-step in order to read the new value.

The question then becomes: Is QEMU behaving correctly, in which
case we should be modifying GDB, or is QEMU signaling GDB too
late, in which case we should be fixing QEMU?

We tried finding an answer to that question, but without much
success. We found the following in the ARMv7-M Architecture
Reference Manual, for instance:

    For all other debug events, including PC match watchpoints,
    the address is that of an instruction which in a simple execution
    model is one which executes after the instruction which caused
    the event, but which itself has not executed

But I'm a little confused when reading this, and I am not even
sure that it applies to data watchpoints. We tried experimenting
with other systems that do not involve QEMU, but came up short.
Surprisingly, watchpoints didn't even trigger when trying on a system
that runs GNU/Linux, for instance. Slightly better, but still not
completely convincing - we tried debugging via stlink, a tool
which provides a gdbserver-like interface.  The watchpoint was inserted,
and triggered an event, but stlink reported a SIGTRAP instead of
a watchpoint event. The only element which might be a clue is the fact
that the PC at the SIGTRAP event is at the instruction after the store,
so it might be confirming QEMU's behavior and indicate that GDB should
be modified.

I am sending this email to ask if anyone might have a more
authoritative answer than ours. If we were able to know for sure,
we can then work on fixing the bug on the right side of the fence :).


More information about the Gdb mailing list