A frequent problem in embedded systems is a stack overflow. As the name suggests, it happens when stack grows so large, it overflows its memory region and overwrites the neighboring regions.
The worst thing that could happened is a silent stack overflow. It corrupts memory introducing all sorts of hard to track bugs. So the best thing to do is to fail big and loud in order to catch bugs at early development time. One of techniques of stack overflow indication is placing stack in the beginning of the RAM.
_stack_size = 0x100;
SECTIONS {
...
.stack : {
_stack_end = .;
. += _stack_size;
. = ALIGN(8);
_stack_start = ABSOLUTE(.);
} > RAM
.data : {
_data_vma = .;
*(.data)
_data_evma = .;
} > RAM AT>FLASH
.bss : {
*(.bss)
} > RAM
}
In this arrangement stack overflow results in invalid memory access triggering the Hard Fault
interrupt.
To catch stack overflow during debugging one could use memory watch points. Writing data to the memory region being watched halts running program.
For example, to set watch points at the begging of RAM use gdb
command
watch *0x20000000
In this example stack overflow occurs because of recursive implementation of
factorial
function. Such implementation is common in programming language tutorials but should not be used in a real program. Use analytical approximation functions to calculate factorial.