| |||
| Home > Compiler Coding Practices > Stack use in C and C++ | |||
C and C++ both use the stack intensively. For example, the stack is used to hold:
the return address of functions
registers that must be preserved, as determined by the ARM Architecture Procedure Call Standard (AAPCS)
local variables, including local arrays, structures, unions, and in C++, classes.
In general, there is no way to automatically measure stack use. However, it is possible to manually estimate the extent of stack utilization using the following methods:
Link with --callgraph to
produce a static callgraph. This shows information on all functions,
including stack use.
Link with --info=stack or --info=summarystack to
list the stack usage of all global symbols.
Use the debugger to set a watchpoint on the last available location in the stack and see if the watchpoint is ever hit.
In general, you can lower the stack requirements of your program by:
writing small functions that only require a small number of variables
minimizing the number of variables that are in use at any given time at each point in a function
avoiding the use of large local structures or arrays
using C block scope
avoiding recursion.
The avoidance of large local structures or arrays can be achieved
by using malloc() and free() instead.
The use of C block scope involves declaring variables only where they are required. This minimizes use of the stack by overlapping memory required by distinct scopes.
To estimate stack usage using a debugger:
Allocate space for the stack that is much larger than you expect to require.
Fill the stack with a known value, for example,
zero or 0xDEADDEAD.
Run your application, or a fixed portion of it. Aim to use as much of the stack as possible in the test run. For example, try to execute the most deeply nested function calls and the worst case path found by the static analysis. Try to generate interrupts where appropriate, so that they are included in the stack trace.
After your application has finished executing, examine
the stack area of memory to see how many of the known values (zeros
or 0xDEADDEAD) have been overwritten. The stack shows
garbage in the part of the stack that has been used and zeros or 0xDEADDEAD values in
the remainder.
Count the number of known entries and multiply by four.
Subtract the size of the remaining known entries from the size of the stack, in bytes.
The result of the calculation shows how far the stack has grown in memory, in bytes.
Linker Reference:
Using the fromelf Image Converter