A Guide to Using ARM Stack Limit Registers | Interrupt

Stack overflows have notoriously plagued the development processes. They often can go undetected and can present themselves in obscure ways. We have implemented software mechanisms to protect against them, but these have limitations and still don’t protect against all conditions.


This is a companion discussion topic for the original entry at https://interrupt.memfault.com/blog/using-psp-msp-limit-registers-for-stack-overflow

Hi,
I am not able to detect whether PSPLIM or MSPLIM caused the fault.
Your UsageFault_Handler in assembly expects, that corresponding SP changed value equal to its’ limit. I am observing, that PSP is never updated into invalid value and remain on the old one.
This agrees to “ARM v8-M Architecture Reference Manual” code listings which describe these checks.
Look for “// Memory operation only performed if limit not violated”
Was this code successfully tested? It would work if you repeatedly increment SP by 1. Code checks for SP==LIM which is, in fact, valid state just before next increment which causes fault.

In my test I am allocating 60 kiB on FreeRTOS task stack (just a few kiB stack). Usagefault triggers, but all SP values are higher than their limits.

Hi @xorly,
Apologies for the late reply, as I didn’t have notifications set. Yes this code is tested, and does properly detect the MSP and PSP in the UsageFault_Handler. It is a slight oversight, as you mention, that it doesn’t cover all conditions. Changing to bge from beq is probably better in this case.

Hi @jkurtz ,
presented code works as expected, but according to my observation is not applicable in more real life scenarios.

Detection in your code assumes, that in invalid value remains in SP and SP==LIM is invalid. According to my observation, neither of these is true. Can you point me to docs which tell otherwise?

My observation:
SP==LIM is valid state and PSP is never updated into invalid value and remain on the last valid one.

Lets have SP == 6, LIM == 5, now decrement SP by 2. Fault is generated, but SP will have value == 6.

Hi @xorly,

I possibly didn’t communicate this properly. You are correct, this was an oversight in the assembly code above. But very easily corrected, which I am sure you have addressed by now.
I have a PR in the repository to reflect this.