IDE: MCUXpresso IDE 25.6
Debugger: GNU Arm GDB 15.2.90.20241130-git
Toolchain: GNU Arm Toolchain 14.2.Rel1
Target: NXP LPC845, Arm Cortex-M0+
Debug probe: Onboard LPC-Link2 using LinkServer
Host: Windows
GDB becomes unresponsive when debugging a Cortex-M0+ application that uses a synthetic exception stack frame to return from SysTick into Thread-mode code.
The firmware executes an exception return using:
bx lrwith LR = 0xFFFFFFF9 (return to Thread mode using MSP).
The synthetic exception frame contains a valid Thumb-mode destination PC and xPSR. The application operates on the physical target, but GDB becomes unresponsive after stopping at the destination function.
Symptoms include:
Variable hover inspection stops working.
Memory views display ????????.
GDB commands, including info threads, become unresponsive.
The debug session generally requires termination and cleanup.
The problem also occurs when using a hardware breakpoint at the destination rather than instruction-stepping across the exception return.
Start debugging the application normally.
Stop immediately before the bx lr exception-return instruction.
Place another breakpoint at the destination function, System().
Step across the exception return or continue to the destination breakpoint.
GDB reaches the destination but subsequently becomes unresponsive.
The failure is reproducible with the normal GDB configuration.
Enabling remote-protocol tracing with:
set logging file gdb-remote.log
set logging overwrite on
set logging enabled on
set debug remote 1reveals that GDB repeatedly performs the same sequence of remote memory reads:
m1b4,4 -> 91010000
m1ba,4 -> 00000000
m1bc,4 -> 00000001
m1c0,4 -> f9ffffff
m190,4 -> 07490868This sequence repeats indefinitely.
LinkServer acknowledges and responds successfully to the requests. The trace therefore does not indicate an ordinary communication timeout.
Notably, the response at 0x1c0 contains 0xFFFFFFF9, the exception-return value.
Entering the following command in GDB:
set backtrace limit 1prevents the observed failure in repeated testing.
With this setting active:
The debugger repeatedly crosses the same exception-return boundary.
Both breakpoints function normally.
Variable hover inspection works at the destination.
The debug session remains responsive.
The workaround also functions when placed in a GDB command file configured through:
Debug Configurations → GDB Debugger → GDB command file
No application or assembly modifications are necessary.
The same target, debug probe, and IDE successfully debug conventional firmware.
Calling the destination function without the synthetic exception-return shim also works.
A conventional SysTick handler does not exhibit this failure.
The problem appears specifically associated with GDB processing the execution state following the synthetic exception return.
GDB should remain responsive after the exception return, permitting stepping, register inspection, memory inspection, and variable evaluation.
If GDB cannot interpret the resulting stack frames, it should report an error or terminate unwinding rather than enter an indefinitely repeating memory-read sequence.
The effectiveness of set backtrace limit 1 strongly suggests that GDB's ARM Cortex-M stack-frame unwinding or frame analysis is involved.
The exact internal cause has not been established.
Please investigate the interaction between GDB's ARM Cortex-M exception-frame handling and synthetic exception returns.
In particular, determine why the debugger repeatedly reads the same target memory locations and whether frame unwinding can enter an unbounded loop.
The workaround restores debugging functionality, but it restricts backtrace depth and should not be necessary for a valid exception-return sequence.