call stack unwinding in ARM cortex m3

stdcall picture stdcall · Jul 4, 2012 · Viewed 9.3k times · Source

I would like to create a debugging tool which will help me debug better my application. I'm working bare-bones (without an OS). using IAR embedded workbench on Atmel's SAM3.

I have a Watchdog timer, which calls a specific IRQ in case of timeout (This will be replaced with a software reset on release). In the IRQ handler, I want to print out (UART) the stack trace, of where exactly the Watchdog timeout occurred.

I looked in the web, and I didn't find any implementation of that functionality.

Anyone has an idea on how to approach this kind of thing ?

EDIT: OK, I managed to grab the return address from the stack, so I know exactly where the WDT timeout occurred. Unwinding the whole stack is not simple as it first appears, because each function pushes different amount of local variables into the stack.

The code I end up with is this (for others, who may find it usefull)

void WDT_IrqHandler( void )
{
    uint32_t * WDT_Address;
    Wdt *pWdt = WDT ;
    volatile uint32_t dummy ;
    WDT_Address = (uint32_t *) __get_MSP() + 16 ;
    LogFatal ("Watchdog Timer timeout,The Return Address is %#X", *WDT_Address);
    /* Clear status bit to acknowledge interrupt */
    dummy = pWdt->WDT_SR ;

}

Answer

Marc Signer picture Marc Signer · Apr 19, 2014

ARM defines a pair of sections, .ARM.exidx and .ARM.extbl, that contain enough information to unwind the stack without debug symbols. These sections exist for exception handling but you can use them to perform a backtrace as well. Add -funwind-tables to force GCC to include these sections.