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