How can I trace the cause of an invalid PC fault on Cortex M3?

2

I have an STM32 Cortex M3 that is experiencing an intermittent invalid PC (INVPC) fault. Unfortunately it takes a day or more to manifest and I don't know the cause.

I have the device paused in the debugger after the fault happened. The INVPC flag is set. The stacked registers are as follows:

0x08003555 xPSR
0x08006824 PC
0x08006824 LR
0x00000000 R12
0x08003341 R3
0x08006824 R2
0xFFFFFFFD R2
0x0000FFFF R0

Unfortunately the return address 0x08006824 is just past the end of the firmware image. The decompilation of that region is as follows:

    Region$$Table$$Base
        0x08006804:    08006824    $h..    DCD    134244388
        0x08006808:    20000000    ...     DCD    536870912
        0x0800680c:    000000bc    ....    DCD    188
        0x08006810:    08005b30    0[..    DCD    134241072
        0x08006814:    080068e0    .h..    DCD    134244576
        0x08006818:    200000bc    ...     DCD    536871100
        0x0800681c:    00001a34    4...    DCD    6708
        0x08006820:    08005b40    @[..    DCD    134241088
    Region$$Table$$Limit

** Section #2 'RW_IRAM1' (SHT_PROGBITS) [SHF_ALLOC + SHF_WRITE]
    Size   : 188 bytes (alignment 4)
    Address: 0x20000000

I'm not sure this address is valid. The disassembly of that address in the debugger looks like nonsense, maybe data interpreted as code or something.

enter image description here

Is there any way I can trace this back to see where the exception happened? If necessary I can add some additional code to capture more information.

arm
asked on Stack Overflow Dec 3, 2018 by shogged • edited Dec 3, 2018 by shogged

1 Answer

0

Don't sure how it works on Cortex M3, but on some other ARMs PSR register holds processor mode bits that could help you find out when it happens (in user mode, IRQ, FIQ etc). Each mode generally have it's own stack.

For user mode, if you use some RTOS with multi-tasking, you probably have many stacks for each task, but you could try to find out which task is current one (was running before crash).

When you find crashed task (or IRQ) you could try to look at it's stack for addresses of all routines and find out what was called before accident. Of course if stack was not unrecoverably corrupted.

This is what I'd start investigation from. If you find crashed task or even function but still have no idea what happens, you could make something like small circular history buffer where you write some codes on every step of your program, so you could find what it does last even if stack was destroyed.

answered on Stack Overflow Dec 3, 2018 by G-Shadow

User contributions licensed under CC BY-SA 3.0