I ran into the following problem, debugging this:

8000036c <just_before_read_loop>:
8000036c:       01000393                li      t2,16

80000370 <read_loop>:
80000370:       00052303                lw      t1,0(a0)

Set a software breakpoint on just_before_read_loop, and run to it. Then set
a hardware watchpoint on the address in a0. Tell gdb to continue.
Gdb clears breakpoints and single steps to get past the software
breakpoint. Then it sets all breakpoints again, and tells the target to
resume. The target halts at read_loop because the watchpoint is hit, and
reports a trap at 0x80000370. gdb however, then forcibly writes back the pc
to 0x8000036c. The code for this behavior in gdb is in
adjust_pc_after_break() (infrun.c). I didn’t follow that code in detail,
but it seems to come down to gdb decrementing the PC because it’s not sure
whether the software breakpoint or the watchpoint was hit.

If OpenOCD tells gdb that it can tell the difference between the two, then
this code is bypassed and everything works as I expect. OpenOCD can do that
by adding swbreak+ to the reply to qSupported as follows:

--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -2357,7 +2357,7 @@ static int gdb_query_packet(struct connection *connection,
                        (GDB_BUFFER_SIZE - 1),
                        ((gdb_use_memory_map == 1) &&
(flash_get_bank_count() > 0)) ? '+' : '-',
                        (gdb_target_desc_supported == 1) ? '+' : '-');

My question is: is this safe for all targets? If it is, this is an easy
change. If not, I’ll have to invent some mechanism for targets to let the
gdb_server layer know what should be returned. If that’s required, are
there any guidelines I should follow?

My target is RISC-V, which I’m working on implementing OpenOCD support for.
I imagine this same issue exists on other targets as well.

Thank you,
OpenOCD-devel mailing list

Reply via email to