cancel
Showing results for 
Search instead for 
Did you mean: 

stack unwinding during exception

andy_long
Associate III

Hi, 

I am trying to test my fault exceptions. In the event of an exception, I would like to get more information about the problem. In the event of an exception, I am finding the stack pointer and trying to get PC by unwinding the stack. I think the PC would tell me the address where the problem occurred.

I have a test code in main() as given below to test my code.

andy_long_0-1711036399176.png

andy_long_2-1711038262222.png

Exception happens at PC 0x8042326.

andy_long_2-1711036630362.png

Please note that the active stack pointer is SP_main, and the PC is 0x8042322.

I get an usage fault exception once the divide by zero is executed. The LR is 0xFFFFFFE9 in the exception handler which is correct. I expect to see the PC as 0x08042322 when I unwind the stack but this is different.

void UsageFault_Handler(void)
{
    uint32_t StackPointer = 0UL;
    __ASM volatile
    (
        "   tst lr, #4          \n"
        "   ite eq              \n"
        "   mrseq %0, msp       \n"
        "   mrsne %0, psp       \n"
        :   "=r"( StackPointer )
    );

I read the stack pointer as 0x2001'f070, but from the memory map 0x2001'f080 seems to be correct.

andy_long_4-1711038592697.png

IAR says 0xC2500000 as PC which can be seen in the above memory map. Why is there an offset ?

andy_long_5-1711038883430.png

 

 

 

 

 

2 REPLIES 2

>>Why is there an offset ?

Probably because your inside a subroutine where you've pushed other stuff on the stack and have a local/auto variable?

Perhaps try disassembling what you actually built, or write a function directly in assembler in the .s file, where you've got 100% visibility into the registers you're using and touching.

The magic with handlers is that you're free to use R0-R3 immediately as they are already on the context stack.

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

 

Okay, so I have been checking the disassembly and I see that  R4, R5, R6 and LR have been pushed to the stack, and this is the reason I see an offset of 16 bytes.  

andy_long_4-1711101651476.png

I have removed two local variables and I see that the disassembly has changed like below. It still pushes R4 and LR and I see an offset of 8 bytes this time. Why is R4 and LR being pushed ?

andy_long_1-1711101304741.png

I was under the impression that on exception it is always the below given registers that will be pushed on to the stack (additional bytes if float enabled). Why in my case additional bytes are pushed ?

andy_long_3-1711101603154.png

Please note that MSP was used when the exception occurred.