This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Hardfault Exception Debugging

The hardfault exception sometimes occurs during operation.

The register and stack value is like the following at the time of the hardfault exception occurrence.

  

According to this information, the LR(Link Register) is 0x080085CD before the hardfault exception.

So I think that the hardfault exception have occurred when the following code is executed.

0x080085CC    ADD    sp, sp, #0x14          : sp = 0x2000377C

0x080085CE    POP    {r4-r5, pc}

0x02020000(in the address 0x20003798 of the above stack area) is loaded into the PC by the POP instrunction ==> Hardfault Exception occurs.

The normal stack area value is like the following before POP instruction execution.

So the PC value should be 0x08008542(address 0x200038784) for the normal operaion.

I guess that the address 0x20003784 value would be overwrited the value 0x02020000.

Is it right?

Breakpoint like the following expression to stop the code execution just before the hardfault exception occur ?

BS WRITE * ((unsigned int*)0x20003784) == 0x02020000

How could I solve this problem(hardfault exception)?

  • Helpful: 

    Using Cortex-M3/M4/M7 Fault Exceptions: Abstract: (keil.com)

  • Hi Andy117,

    in your case when you see stacked LR value of 0x080085CD in the exception handler it means that the address 0x080085CC actually represents the address where the function that was executing would return after it finishes.

    So, you have to check the address before 0x080085CC since that should be a jump to the function which was executing when the fault happened.

    And in your case the fault was caused by trying to execute the instruction at address 0x02020000 as indicated by the content on the stack right after LR, called ReturnAddress.

    Best regards, Milorad

  • Popping a bad value into PC smells of stack corruption.

    A function's prologue pushes r7, lr so that the function can itself use them and still get back to its caller. A function's epilog reverses the prologue, by popping r7, lr back off the stack into those registers.  If you trash the stack in between these two actions, you are in trouble. Any misuse of local variables can cause this, e.g.

    int is[2];
    is[2] = 10;

    I have created a fault exception handling api.  In the main C file, you can find more discussion on this very issue.  See here

    github.com/.../faultHandling.c