GDB incorrect backtrace when using several stacks and/or FPU after an exception -- with fix
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
GNU Arm Embedded Toolchain |
Opinion
|
Undecided
|
James-Adam Renquinha Henri |
Bug Description
`arm-none-
How to reproduce:
-----
FPU case: use a Cortex-M4 core with FPU activated (CP10 = CP11 = 3), breakpoint in any exception handler.
PSP case: any Cortex-M, initialize PSP and set bit 2 of CONTROL, breakpoint in any exception handler.
Example code to initialize both CONTROL and PSP (__main_stack_end__ must be defined):
.global __main_stack_end__
mrs r0, CONTROL
mov r1, #2
orr r0, r0, r1
mov r1, sp
ldr r2, =__main_stack_end__
msr PSP, r1
msr CONTROL, r0
msr MSP, r2
Behavior with code using multiple stacks (PSP & MSP):
-----
`gdb` doesn't know about the Process Stack Pointer, so it continues using the current (Main) stack pointer and it gets into the void. Example session:
(gdb) bt
#0 SysTick_Handler () at systick.cpp:8
#1 <signal handler called>
#2 0x000007b2 in ?? ()
#3 0x00000000 in ?? ()
Behavior with FPU active (used):
-----
`gdb` doesn't know the other EXC_RETURN codes involving the extended frame type, so it gets interpreted as a thumb address, again leading into the void. Example session:
(gdb) bt
#0 SysTick_Handler () at systick.cpp:8
#1 0xffffffe8 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
The fix provided (patch attached) is manifold and perform the following:
- Correctly recognize the other EXC_RETURN code involving the extended exception stack frame;
- On an exception stack frame, check LR[3:0] to determine which stack was used before the exception occured and use it;
- On an exception stack frame, check LR[4] to determine if the FPU was used and adjust the stack pointer and possibly load the stacked FPU registers. But please take note of the known issues below.
The fix was tested with the possible combinations of usage of PSP/FPU and the result of `info all-registers` on various frames thoroughly visually inspected.
Apply patch in gdb-7.11 with `patch -p1 < patch`.
Known Issue:
-----
As noted in a comment in the patch, the lazy stacking feature is not accounted for, and as a result may give incorrect results for FPU registers in a upper frame depending on whether the registers are actually stacked or not. However the backtrace is still functional. Actually, I verified that once the Cortex-M4 core stacks the FPU registers (for instance, upon execution of a FPU instruction in a exception handler), `gdb` reports them correctly.
description: | updated |
Changed in gcc-arm-embedded: | |
status: | New → Opinion |
assignee: | nobody → James-Adam Renquinha Henri (arenquinha) |
Hi James-Adam,
I suggest you report this bug and patch on the gdb mailinglist <email address hidden>. Hopefully they can apply it to the 7.11 release branch.
Cheers,
Andre