The ARM-v7m code for stack overflow detection does the following:
Code: Select all
#define port_switch(ntp, otp) do { \
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
if ((stkalign_t *)(r13 - 1) < (otp)->wabase) { \
chSysHalt("stack overflow"); \
} \
__port_switch(ntp, otp); \
} while (0)
It can be seen that, when a thread is switched out, the switch code check the current value of the PSP, and compares it with the base of the thread's stack. If it's lower, then a stack overflow occurred.
The problem with this method is that we can't detect if the stack was corrupted and then the PSP returned to the correct reserved area before the context switch. Maybe a better approach would be to add a guard (single word) to the stack, and check its value. As a proof of concept, I did:
Code: Select all
#define port_switch(ntp, otp) do { \
if ((*(const uint8_t *)((otp)->wabase) != CH_DBG_STACK_FILL_VALUE) { \
chSysHalt("stack overflow"); \
} \
__port_switch(ntp, otp); \
} while (0)
With this modification in place ChibiOS detected a stack corruption that was previously unnoticed.
Thanks,
Diego.