Easily detecting stack overflows / moving stack to beginning of DTCM

jmarsh

Well-known member
By default, memory in DTCM (for Teensy 4.x) is ordered like this:

Initialized data -> Uninitialized data -> Stack

This means if there's a stack overflow, the uninitialized data can be silently corrupted. There's a 32 byte "no man's land" setup by the MPU to try to catch that happening, but it's not rare for a function with a lot of local variables to jump right over it without triggering the fault handler.

What can be done instead, is arranging the DTCM like this:

Stack -> Initialized data -> Uninitialized data

This way if the stack overflows, the stack pointer will definitely be pointing at an invalid memory address (below the beginning of DTCM) and trigger a fault. I managed to tweak the linker script for Teensy 4.1 to make this work:
I also removed the MPU section for the no man's land region, since it wasn't needed.
This does waste a little bit of space (4095 bytes max) since the Initialized data has to be aligned to a 4096 byte boundary for the static usb endpoint queue to function correctly.
 
Ahh, I didn't know about the no mans land. I just went through all the code, easy enough, to see what heap arrays I'm using. Only one function has more than a couple hundred bytes, but looking at them, the functions that do so are all mutually exclusive, so I'll reduce that to two I think static buffers and reuse them. I don't like a lot of dynamic allocation crap in embedded code, the simpler structure is better to make reliability.

I put the moved stack core stuff in, after quit and restart. That's a nice hack. Honestly I've not paid a lot of attention to how the IDE does it's thing but I assume that stuff gets compiled on the first compile. It's in place and running now. I'm at the point where stress testing is getting harder and harder and taking longer to fail so that's good but it will be a while before I report back, but I will.

Thanks so much for the help!
 
Back
Top