GDB incorrect backtrace when using several stacks and/or FPU after an exception -- with fix

Bug #1566054 reported by James-Adam Renquinha Henri
40
This bug affects 7 people
Affects Status Importance Assigned to Milestone
GNU Arm Embedded Toolchain
Opinion
Undecided
James-Adam Renquinha Henri

Bug Description

`arm-none-eabi-gdb`, as of 7.11, cannot show backtraces properly when using PSP & MSP and/or FPU is active after the debugged program receives any exception. The following shows the issues encountered.

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.

Tags: fpu gdb
Revision history for this message
James-Adam Renquinha Henri (arenquinha) wrote :
description: updated
Revision history for this message
Andre Vieira (andre-simoesdiasvieira) wrote :

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

Changed in gcc-arm-embedded:
status: New → Opinion
assignee: nobody → James-Adam Renquinha Henri (arenquinha)
Revision history for this message
James-Adam Renquinha Henri (arenquinha) wrote :

This bug and its associated patch are being discussed in the `gdb-patches` mailing list. You can follow the discussion here: https://sourceware.org/ml/gdb-patches/2016-04/msg00170.html

Revision history for this message
pruesch (peter-ruesch) wrote :

@James-Adam:
my suspicion is that if you answer this open question, your patch will make it into the gdb trunk faster :)
https://sourceware.org/ml/gdb-patches/2016-04/msg00481.html

thanks!

Revision history for this message
Jonathan Dumaresq (jdumaresq) wrote :

Hi,

Is it possible to have this patch used even if it's not officialy approved ?

Regards

Jonathan

Revision history for this message
Thomas Preud'homme (thomas-preudhomme) wrote :

Hi Jonathan,

Unfortunately our policy is to only include patches that have not been approved to avoid the maintainance burden of carrying the patch forever. At this point we have no guarantee that this patch would be accepted by the GDB community.

Best regards.

Revision history for this message
xintianzhang (zxtxin) wrote :

Will this bug be solved in the future release of gdb?

description: updated
Revision history for this message
Thomas Preud'homme (thomas-preudhomme) wrote :

FYI: I've contacted James-Adam to ask him about the current status of his effort to get this patch in GDB source code.

Revision history for this message
Robert North (russetrob) wrote :

Thomas, Any updates from James-Adam?
Has he made any progress?
Or should someone else take up the work?

Revision history for this message
Thomas Preud'homme (thomas-preudhomme) wrote :

Hi Robert,

James-Adam replied me that the patch needs further rework (see [1]) and he has very little time to work on it right now. Unfortunately I'm not sure taking over his work is an option since it might involve some copyright assignment issue. So it might take a while I'm afraid, unless someone help James-Adam directly.

[1] https://sourceware.org/ml/gdb-patches/2016-04/msg00231.html

Best regards.

Revision history for this message
Robert North (russetrob) wrote :

Did a little more digging, and found that Fredrik Hederstiern proposed a similar patch[1] later that year. It was partially accepted, but the FPU and PSP elements weren't accepted (advice was to submit as separate patches). Further down the thread James asserts the copyright assignment is done for himself, and Fredrik [2].

So with a check that the maintainers have copyright assignments on record, the patches could be safely worked on, and Fredrik's patch is probably best to use, as it was partially accepted.

[1] http://sourceware-org.1504.n7.nabble.com/PATCH-Fix-exception-unwinding-for-ARM-Cortex-M-tt406665.html

[2] http://sourceware-org.1504.n7.nabble.com/PATCH-Fix-exception-unwinding-for-ARM-Cortex-M-td406665.html#a414646

Revision history for this message
Kevin Bracey (kevin-bracey) wrote :

Started looking at this, as this "can't see where HardFaults are happening" problem has been also bugging me for years.

Having considered the previous patches, I'm pondering a different approach for the "jump from MSP to PSP", now over in the GDB Server.

See https://github.com/mbedmicro/pyOCD/pull/430

Is anyone aware of analogues here, either in other Cortex M servers or even non-Cortex M embedded debuggers?

Revision history for this message
xintianzhang (zxtxin) wrote :

any update?

Revision history for this message
rojer (rojer9) wrote :

stack backtrace is useless without this, would be really nice to see this happen.

Revision history for this message
Petteri Aimonen (jpa-lp) wrote :

I'm using a macro like this as a workaround:

define hf_backtrace
 set $pc = ((uint32_t*)$psp)[6]
 set $lr = ((uint32_t*)$psp)[5]
 set $r12 = ((uint32_t*)$psp)[4]
 set $r3 = ((uint32_t*)$psp)[3]
 set $r2 = ((uint32_t*)$psp)[2]
 set $r1 = ((uint32_t*)$psp)[1]
 set $r0 = ((uint32_t*)$psp)[0]
        # Use 4*26 with FPU, 4*8 without FPU
 set $sp = $psp + 4*26
 bt
end

Basically it emulates an exception return and gdb can then backtrace from the position where the exception occurred.

Revision history for this message
Fredrik Hederstierna (fredrikhederstierna) wrote :

Finally the patch made it into the repo, and will be part of GDB-10 upcoming release.

https://sourceware.org/pipermail/gdb-patches/2020-September/171871.html

Thanks, Best Regards,
Fredrik Hederstierna

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Related questions

Patches

Remote bug watches

Bug watches keep track of this bug in other bug trackers.