How to get a stack trace in RTEMS
Sebastian Huber
sebastian.huber at embedded-brains.de
Thu Jun 27 08:37:52 UTC 2024
On 27.06.24 10:27, Stanislav Pankevich wrote:
> 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
> <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.
The rtems_exception_frame is CPU port specific. For arm, we have:
typedef struct {
uint32_t register_r0;
uint32_t register_r1;
uint32_t register_r2;
uint32_t register_r3;
uint32_t register_r4;
uint32_t register_r5;
uint32_t register_r6;
uint32_t register_r7;
uint32_t register_r8;
uint32_t register_r9;
uint32_t register_r10;
uint32_t register_r11;
uint32_t register_r12;
uint32_t register_sp;
void *register_lr;
void *register_pc;
#if defined(ARM_MULTILIB_ARCH_V4)
uint32_t register_cpsr;
Arm_symbolic_exception_name vector;
#elif defined(ARM_MULTILIB_ARCH_V6M) || defined(ARM_MULTILIB_ARCH_V7M)
uint32_t register_xpsr;
uint32_t vector;
#endif
const ARM_VFP_context *vfp_context;
uint32_t reserved_for_stack_alignment;
} CPU_Exception_frame;
This is basically the full register view of the interrupted context.
For arm, the register_pc needs adjustments to get the real PC.
--
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/
More information about the users
mailing list