How to get a stack trace in RTEMS

Stanislav Pankevich s.pankevich at gmail.com
Thu Jun 27 08:27:03 UTC 2024


A small further update here to support the discussion further. It turns out
that there is an undocumented function that, in contrast to
_Unwind_Backtrace, allows passing a given stack:

*    In my practice standard _Unwind_Backtrace failed to switch to
pre-signal stack. I've managed to get some before-signal stacks by calling
internal libgcc __gnu_Unwind_Backtrace - it has an extra argument being
"current registry values" - so it operates on given stack, not on current
stack.*
https://stackoverflow.com/a/30515756/598057

The challenge with this is how to access the crashed stack frame, i.e., the
right context has to be passed to __gnu_Unwind_Backtrace.

    _Unwind_Reason_Code
    __gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void *
trace_argument, phase2_vrs * entry_vrs);
    ...
    pre_signal_state.core = *reinterpret_cast<const
core_regs*>(&(signal_context->uc_mcontext.arm_r0));
    __gnu_Unwind_Backtrace(tracer, &state, &pre_signal_state);


In this SO example, they are using the signal_context while what we have in
the RTEMS, for example in bsp_fatal_extension() is:

    const rtems_exception_frame *exception_frame = (const
rtems_exception_frame *) code;

Could anyone advise on how we access the original crashed stack trace from
the code variable? We confirm that _Unwind_Backtrace can work on both Zynq
UltraScale+ and TMS570. It would be great to get it or
__gnu_Unwind_Backtrace to work with the real user frames.

Thanks,
Stanislav Pankevich

On Wed, Jun 26, 2024 at 4:14 PM Stanislav Pankevich <s.pankevich at gmail.com>
wrote:

> Hi Sebastian,
>
> We had to add -funwind-tables to have this trace() called, and we can now
> see the function names as follows. The challenge is that the functions of
> the exception handler are printed, not the code that led to the exception.
> Now we need to figure out how to switch this code to print our function
> names instead.
>
> FUNC NAME: bsp_fatal_extension
> FUNC NAME: _User_extensions_Iterate
> FUNC NAME: _Terminate
> FUNC NAME: _ARM_Exception_default
>
> static _Unwind_Reason_Code trace(_Unwind_Context *ctx, void *arg)
> {
>     (void)arg;
>
>     const uint32_t func_entry  = _Unwind_GetRegionStart(ctx);
>
>     char          *func_name = "??";
>     uint8_t       *canary    = (uint8_t *)(func_entry - 0x4);
>     const uint32_t len       = (*((uint32_t *)(func_entry - 0x4))) &
> 0x00FFFFFF;
>     if (*canary == 0xFF)
>     {
>         func_name = (char *)((uint32_t)canary - len);
>         *canary   = '\0';
>     }
>     printk("FUNC NAME: %s\n", func_name);
>
>     return _URC_NO_REASON;
> }
>
> Thanks,
> Stanislav Pankevich
>
> On Wed, Jun 26, 2024 at 11:25 AM Sebastian Huber <
> sebastian.huber at embedded-brains.de> wrote:
>
>> Hello Stanislav,
>>
>> On 26.06.24 11:15, Stanislav Pankevich wrote:
>> > Dear RTEMS community,
>> >
>> > My colleague George cannot register to post to this forum, getting 403
>> > when subscribing at https://lists.rtems.org/mailman/listinfo/users
>> > <https://lists.rtems.org/mailman/listinfo/users>. I am posting this
>> > question on his behalf.
>> >
>> > ---
>> >
>> > We are currently seeing an RTEMS_FATAL_SOURCE_EXCEPTION right at the
>> > start of execution and can debug the program once the exception handler
>> > has been reached. From here we can inspect the call stack however we
>> > only see the trace that led to the final function call (void
>> > bsp_reset(void) while loop) that handles the exception, not the trace
>> > that caused the exception. We would like to implement an exception
>> > handler that prints the trace that caused the exception to be
>> triggered.
>> > Is this something that is already implemented in RTEMS? We have
>> > developed an RTEMS port to the Zynq UltraScale+ MPSoC Cortex R5 RPU
>> > running in lockstep. Code execution is from the shared DDR4 memory with
>> > a 256MB region allocated.
>>
>> I have some improvements for this BSP in my patch queue. It adds support
>> for the split mode for example.
>>
>> >
>> > What we want is to have the actual stack trace to be printed to the
>> console.
>> >
>> > Here is an example of what we have now in GDB:
>> >
>> > bsp_reset at 0x0017b062
>> > (.../rtems/bsps/arm/xilinx-zynqmp-rpu/start/bspreset.c:40)
>> > _User_extensions_Iterate at 0x00186854
>> > (.../rtems/cpukit/score/src/userextiterate.c:194)
>> > _User_extensions_Fatal at 0x00183108
>> > (.../rtems/cpukit/include/rtems/score/userextimpl.h:467)
>> > _Terminate at 0x00183108 (.../rtems/cpukit/score/src/interr.c:55)
>> > rtems_fatal at 0x0018adc2 (.../rtems/cpukit/include/rtems/fatal.h:160)
>> > _ARM_Exception_default at 0x0018adc2
>> > (.../rtems/cpukit/score/cpu/arm/arm-exception-default.c:37)
>> > save_more_context at 0x00186cfc
>> > (.../rtems/cpukit/score/cpu/arm/armv4-exception-default.S:176)
>> >
>> > This is currently what is printed on the serial port:
>> >
>> > *** FATAL ***
>> > fatal source: 9 (RTEMS_FATAL_SOURCE_EXCEPTION)
>> >
>> > R0   = 0x00000056 R8  = 0x00ac8aec
>> > R1   = 0xf000e3a0 R9  = 0x00ac8a5c
>> > R2   = 0x00000020 R10 = 0x00000000
>> > R3   = 0x00000020 R11 = 0x00000000
>> > R4   = 0x00000056 R12 = 0x010e6630
>> > R5   = 0x010e67c0 SP  = 0x010e65d4
>> > R6   = 0x010e6698 LR  = 0x001854ae
>> > R7   = 0x001867f5 PC  = 0x001854ae
>> > CPSR = 0x200f01f7 VEC = 0x00000004
>> > RTEMS version: 6.0.0.62f15c07482dd953663143554e78b4bf287ccb83
>> > RTEMS tools: 12.2.1 20230224 (RTEMS 6, RSB
>> > 4c73a76c802588d3864c64ee4dd48a84b953201a, Newlib 17ac400)
>>
>> Getting stack traces on arm is not that easy since you need a
>> description of the stack frames. You can try to use the unwinder from
>> libgcc:
>>
>> static _Unwind_Reason_Code trace(_Unwind_Context *ctx, void *arg)
>> {
>>    (void)arg;
>>    printk("%08" PRIuPTR "\n", (uintptr_t)_Unwind_GetIP(ctx));
>>    return _URC_NO_REASON;
>> }
>>
>> static void f(int i);
>>
>> static void h(int i)
>> {
>>    f(i + 1);
>> }
>>
>> static void f(int i)
>> {
>>    if (i > 10) {
>>      _Unwind_Backtrace(trace, NULL);
>>    } else {
>>       h(i + 1);
>>    }
>> }
>>
>> --
>> embedded brains GmbH & Co. KG
>> Herr Sebastian HUBER
>> Dornierstr. 4
>> 82178 Puchheim
>> Germany
>> email: sebastian.huber at embedded-brains.de
>> phone: +49-89-18 94 741 - 16
>> fax:   +49-89-18 94 741 - 08
>>
>> Registergericht: Amtsgericht München
>> Registernummer: HRB 157899
>> Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
>> Unsere Datenschutzerklärung finden Sie hier:
>> https://embedded-brains.de/datenschutzerklaerung/
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20240627/7291dc3d/attachment-0001.htm>


More information about the users mailing list