Peter Maydell <[email protected]> writes: > 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 ?
For TCG guests we never insert BKPT instructions and treat the system as having infinite hardware breakpoints. >From what I can tell we should only route the debug event to an external monitor if the right DHCSR and DEMCR bits are set. Even then the spec has a lot of behaviour with is IMPDEF. I think the v7M rules are different to the v7a/v8a ones. > > -- PMM -- Alex Bennée Virtualisation Tech Lead @ Linaro
