Skip to main content
AAl-H.1
Associate
October 6, 2020
Question

unwind the stack in non-exception

  • October 6, 2020
  • 1 reply
  • 4052 views

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);
}

1 reply

KnarfB
Super User
October 6, 2020

line 31 nextFp = nextFp + 4; look suspicious. Needs a pointer dereferencing.

AAl-H.1
AAl-H.1Author
Associate
October 7, 2020

Wouldn't the dereferencing in line 26 be enough?

For now, I've replaced line 6 with this:

uint32_t topFp = __get_PSP(); //or __get_MSP();

It seems that it's working but I don't think this is the right way to do it