2020-10-06 05:14 AM
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);
}
2020-10-07 01:59 AM
Thank you @KnarfB I'll try that
2024-08-28 02:35 PM
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
2024-08-28 03:25 PM
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
2024-08-29 11:40 AM
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
2024-08-29 11:56 AM
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.