On Sun, 5 Jul 2026 at 23:44, Gilles Grimaud <[email protected]> wrote: > > While working on Raspberry Pi Pico/RP2040 support, I noticed that Pico SDK > programs deliberately execute BKPT from _exit(). On real hardware this is > useful when a debug probe is attached: returning from main() stops the > debugger at the program exit point. > > Under QEMU this currently does not behave like the debug-probe case. For > M-profile guests, the BKPT instruction is routed through the architectural > guest debug exception path. Without halting debug, that path should remain a > guest-visible DebugMonitor exception when DebugMonitor is enabled, or escalate > towards HardFault otherwise. This patch deliberately leaves that no-debugger > architectural path unchanged. > > The problem addressed here is the case where GDB is connected to QEMU's > gdbstub. In that situation, firmware that uses BKPT as a debugger stop point > should stop in the attached debugger. Instead, the M-profile guest currently > continues down the guest exception path and may end in HardFault/lockup rather > than reporting a clean trap to GDB. > > This is not specific to the RP2040 machine model. It is a generic > Cortex-M/gdbstub interaction: firmware that uses BKPT as a debugger stop point > should be reported to the attached debugger, while keeping the guest > architectural exception path when no debugger is attached. > > Expose a small gdbstub helper to test whether a CPU is visible to an attached > debugger. When an M-profile BKPT instruction is executed with such a debugger > attached, leave the translated block with EXCP_DEBUG so the existing gdbstub > stop path reports a trap to GDB. > > Signed-off-by: Gilles Grimaud <[email protected]> > --- > gdbstub/gdbstub.c | 13 ++++++++++++- > include/exec/gdbstub.h | 6 ++++++ > target/arm/tcg/debug.c | 9 +++++++++ > 3 files changed, 27 insertions(+), 1 deletion(-) > > diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c > index c3c944e965..9f259fc005 100644 > --- a/gdbstub/gdbstub.c > +++ b/gdbstub/gdbstub.c > @@ -237,6 +237,18 @@ static GDBProcess *gdb_get_cpu_process(CPUState *cpu) > return gdb_get_process(gdb_get_cpu_pid(cpu)); > } > > +bool gdb_cpu_is_attached(CPUState *cpu) > +{ > + GDBProcess *process; > + > + if (!gdbserver_state.init || !cpu) { > + return false; > + } > + > + process = gdb_get_cpu_process(cpu); > + return process && process->attached; > +}
No other architecture, CPU or board in QEMU needs to do this, so my instinct is to say that M-profile should not be special here. Richard, Alex: how do we usually handle breakpoint insns for the gdbstub ? -- PMM
