'c code to paint an embedded stack with a pattern say (0xABABABAB) just after main begins?
I am working on dynamic memory analysis using stack painting/foot print analysis method.
dynamic-stack-depth-determination-using-footprint-analysis
basically the idea is to fill the entire amount of memory allocated to the stack area with a dedicated fill value, for example 0xABABABAB, before the application starts executing. Whenever the execution stops, the stack memory can be searched upwards from the end of the stack until a value that is not 0xABABABABis found, which is assumed to be how far the stack has been used. If the dedicated value cannot be found, the stack has consumed all stack space and most likely has overflowed.
I want a c code to fill the stack from top to bottom with a pattern.
void FillSystemStack()
{
extern char __stack_start,_Stack_bottom;
}
NOTE
- I am using STM32F407VG board emulated with QEMU on eclipse.
- stack is growing from higher address to lower address
- start of the stack is 0x20020000
- bottom of the stack is Ox2001fc00
Solution 1:[1]
You shouldn't completely fill the stack after main()
begins, because the stack is in use once main()
begins. Completely filling the stack would overwrite the bit of stack that has already been used and could lead to undefined behavior. I suppose you could fill a portion of the stack soon after main()
begins as long as you're careful not to overwrite the portion that has been used already.
But a better plan is to fill the stack with a pattern before main() is called. Review the startup code for your tool chain. The startup code initializes variable values and sets the stack pointer before calling main()
. The startup code may be in assembly depending on your tool chain. The code that initializes variables is probably a simple loop that copies bytes or words from the appropriate ROM to RAM sections. You can probably use this code as an example to write a new loop that will fill the stack memory range with a pattern.
Solution 2:[2]
This is a Cortex M so it gets the stack pointer set out of reset. Meaning it's pretty much instantly ready to go for C code. If your reset vector is written in C and performs stacking/C function calls, it will be too late to fill the stack at a very early stage. Meaning you shouldn't do it from application C code.
The normal way to do the trick you describe is through an in-circuit debugger. Download the program, hit reset, fill the stack with the help of the debugger. There will be some convenient debugger command available to do that. Execute the program, try to use as much of it as possible, observe the stack in the memory map of your debugger.
Solution 3:[3]
Using another Coretex-M4 (TI: TM4C1294KCPDT), I'm able to fill the stack with an arbitrary uint32_t value using the linker command file:
SECTIONS
{
...
.text : > FW_CODE
.const : > FW_CODE
.cinit : > FW_CODE
.pinit : > FW_CODE
...
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM (HIGH) , fill = 0xDEADDEAD
}
Take note of the line .stack : > SRAM (HIGH) , fill = 0xDEADDEAD
.
Your linker script should have a section that looks something like this:
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
Both linkers are probably very similar, so I'd give it a shot and change the line } >RAM
to } >RAM, FILL = 0xABABABAB
or } >RAM FILL = 0xABABABAB
.
Furthermore, the STM32CubeIDE User Manual discusses the Static Stack Analyzer in chapter 9.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | kkrambo |
Solution 2 | Lundin |
Solution 3 | Seir |