Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine maximum stack usage?

What methods are available for determining the optimum stack size for embedded/memory constrained system? If it's too big then memory is wasted that could be used elsewhere. However, if it is too small then we get this website's namesake...

To try to jump start things: Jack Ganssle states in The Art of Designing Embedded Systems that, "With experience, one learns the standard, scientific way to compute the proper size for a stack: Pick a size at random and hope." Can anyone do better than that?

A more specific example was requested. So, how about a C program targeting an MSP430 MCU with 2 kB of RAM using the IAR Embedded Workbench toolchain without an operating system? This IDE can display the stack contents and usage while using a JTAG debugger.

like image 944
Judge Maygarden Avatar asked Dec 23 '08 15:12

Judge Maygarden


People also ask

How is Max stack calculated?

Count the number of complete strings, multiply by 8 (since "STACK---" is 8 bytes long), and you have the number of bytes of remaining stack space.

How is stack usage calculated in embedded systems?

The total maximum stack usage for the complete system is calculated by adding together the result for each call graph root. It is important to remember that this type of stack usage analysis produces a worst-case result. The application might not actually end up in the maximum call chain, by design or by coincidence.

How do I calculate task stack size?

The stack requirement is determined by the call depth and the number of local non-static variables instantiated in each function in a call chain. So the task stack required would be the the worst case of all possible call chains being the sum of the stack frame size of each call in that chain.

What is the limit of stack?

The stack size limit is the maximum size of the stack for a process, in units of 1024 bytes. The stack is a per-thread resource that has unlimited hard and soft limits.


2 Answers

The most common way to determine the deepest stack usage is to initialize the stack memory with some known but unusual value, then periodically (or at the end of a big test run) see where that pattern stops.

This is exactly how the IAR IDE determines the amount of stack used.

like image 92
Michael Burr Avatar answered Sep 19 '22 23:09

Michael Burr


You tagged your question with static-analysis, but this is a problem that is difficult to solve through static-analysis. The stack usage depends on the program's runtime profile, especially, if you're using recursion or alloca. Given that this is an embedded platform I guess it's also difficult to run something like ps or top and see how much stack your application is using.

An interesting approach is to use the address of the current stack frame in order to determine how much stack is used. You can do this by taking the address of a function's argument or local variable. Do that for the main function and for functions you think are using the most stack. The difference will tell you the amount of stack your application requires. Here is an example (assuming customary high-to-low stack growth).

char *stack_top, stack_bottom;  int main(int argc, char *argv[]) {     stack_top = (char *)&argc;     // ...     printf("Stack usage: %d\n", stack_top - stack_bottom); }  void deeply_nested_function(void) {     int a;     stack_bottom = (char *)&a;     // ... } 

If your compiler allows you to specify a custom function prologue (many do it to allow graph-based program profiling), you can even arrange for all functions to call such measuring code. Then your measurement function mecomes something like

void stack_measurement_function(void) {     int a;     stack_bottom = min(stack_bottom, (char *)&a);     // ... } 

I used an approach similar to what I've described to generate these charts.

like image 20
Diomidis Spinellis Avatar answered Sep 21 '22 23:09

Diomidis Spinellis