Very simple stack overflow detection for Cortex-M and RISC-V
There are many ways of detecting and dealing with stack overflow in embedded systems. Here is a very, very easy stack canary with minimal overhead that can be used on Cortex-M and RISC-V with GNU and LLVM toolchains.
The first thing to realize is that the default GNU linker script (at least for Cortex-M and RISC-V)
provides a symbol __bss_end__ that is the next address after the static data section.
Older versions of the script may call it _ebss.
Quick reminder how the classic C memory layout looks like from Wikipedia.
Let's assume that the heap is not used.
If the stack grows over the bss section you are in deep trouble.
In C you can access the __bss_end__ like any other variable using extern.
1 2 3 | |
The technique is as simple as writing a magic value to the address of __bss_end__
and checking it periodically, for example in main(). volatile is needed to force
the compiler to generate code that does an actual read every time.
Writing
1 | |
Checking
1 2 3 | |
On RISC-V the equivalent is asm("ebreak"). Breakpoint is just one of the options, definitely very obvious
during development under debugger control. An infinite loop is also easy to spot, however a watchdog reset
will not leave much debugging information so leaving explicit
breadcrumbs
is probably the best.
Complete code example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
