cancel
Showing results for 
Search instead for 
Did you mean: 

unwind the stack in non-exception

AAl-H.1
Associate II

Hello

I have STM32F407VG MCU with STM32CubeIDE

I want to unwind the stack

I've found answers online and I've tried that code

The code works fine after a hardfault happens

I tried to use the same code within running (no fault happens) but couldn't do that

The stack has the exact same value

I unwind the stack inside an IRQ and I want to know where the code was before the IRQ got called

Here's the IRQ code:

void TIM4_IRQHandler(void)
{
  /* USER CODE BEGIN TIM4_IRQn 0 */
  if(++iwdg_timer >= Get_IWDG_Threshold()){
	  uint32_t lrStacked[5] = {0};
	  uint32_t topFp = __get_LR();
	  uint32_t nextFp = (uint32_t)&topFp;
	  Stack_Unwind(256, nextFp, lrStacked, 5);
	  //RTC_Write_LR_Stack(lrStacked);
  }
/*
  if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKUP_WDG_MAX) < iwdg_timer){
	  HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKUP_WDG_MAX, iwdg_timer);
  }
*/
  /* USER CODE END TIM4_IRQn 0 */
  HAL_TIM_IRQHandler(&htim4);
  /* USER CODE BEGIN TIM4_IRQn 1 */
 
  /* USER CODE END TIM4_IRQn 1 */
}
 
static void Stack_Unwind(uint32_t iteration, uint32_t nextFp, uint32_t *lrStacked, uint32_t size){
    /* loop backtrace using lr to unwind the call stack */
    for(uint32_t i=0, j=0; i<iteration; i++){
    	uint32_t lr = *((uint32_t*)nextFp);
        if((lr >= 0x08000000) && (lr <= 0x080FFFFF)){
        	lrStacked[j] = lr;
            j++;
        }
        nextFp = nextFp + 4;
        if (nextFp == 0x20020000 || j == size){
        	break;
        }
    }
}
 
__STATIC_FORCEINLINE uint32_t __get_LR(void)
{
  uint32_t result;
 
  __ASM volatile ("MOV %0, lr\n" : "=r" (result) );
  return(result);
}

14 REPLIES 14

Thank you @KnarfB​ I'll try that

Hi @AAl-H.1 

 

Did you solve this problem? I am trying to do the same thing and i have so far come up empty handed.

 

Best regards

Martin

Not sure the efficacy of paging users from ~4 years ago. Forum has been transitioned.

LR reflects a call gate in the core.

Use it to determine if you need the PSP or MSP

Fix the stacked context (r0 .. r3, lr, pc, etc), advance PC, etc

BX LR to unstack the context and continue.

Frame described in Joseph Yiu Essential CM3, and subsequent books, or ARM TRM

 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Id say it worked perfectly :)

Anyway. It seems to not be that simple from what I gathered so far. There are projects like backtrace (https://github.com/red-rocket-computing/backtrace) that attempts to tackle the problem, but so far I have failed to get it to work.

 

// Martin

The complex part would you having to decode the instruction that faulted to step over or emulate it. The core provides no help there.

And the stack content, the consistency of the tools pushing frames, and your ability to derive some associativity with the symbols/debug in the object file, and chasing back up the call-tree, etc.

Add if the tools add anything to aid you in the task, say calling specific routines as part of the usual subroutine prologue / epilogue, and stack checking or profiling.

 

 

https://www.pdqlogic.com/

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..