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

Reply via email to