Stack Analyzer

The UPMEM toolchain contains a static stack analyzer: dpu_stack_analyzer. It provides the maximum size of the stack needed by the specified program. The tool details the call trace for which the maximum size is needed.

How to use

To obtain accurate results, one should compile the source files with the options -g and -fstack-size-section (which are enabled by default).

Let’s try on a simple example:

int foo(int x) {
    return x * 5;
}

int bar(int x) {
    return foo(x + 1);
}

int main() {
    return bar(4) + 2;
}
dpu-upmem-dpurte-clang dpustackanalyzer_example.c -o dpustackanalyzer_example

We can now call dpu_stack_analyzer:

dpu_stack_analyzer dpustackanalyzer_example
Task: 0 Allocated size: 1024
Max size: 36
Call Trace:
    main (16) [dpustackanalyzer_example.c:9] 800000b8
        -> main[dpustackanalyzer_example.c:10] 800000d8
    bar (16) [dpustackanalyzer_example.c:5] 80000078
        -> bar[dpustackanalyzer_example.c:6] 800000a0
    foo (4) [dpustackanalyzer_example.c:1] 80000058
Unresolved indirect callsites:
Unresolved annotation signatures:

The tool provides the maximum stack size needed, the actual stack size for each tasklet, and the sequence of function calls that requires the maximum stack size.

By default, main is used as the entry function. One can use the --entry func option to set func as the entry point.

Additional steps for assembly code

When using an assembly source file, the program binary will not have information concerning the assembly “functions”. The tool will treat calls to these functions as indirect calls, that cannot be analyzed. In most cases, this may not be an issue, but here are the steps to take to provide the needed information:

  • make sure that all local symbols start with the prefix .L to hide them when building the program

  • add a .size directive for each assembly function

  • add a .type directive for each assembly function, to specify that a symbol is a function

  • add a .stack_size.<FUNCTION> section for each assembly FUNCTION with contains: - a .long directive storing the function start address - a series of .byte directives storing the maximum stack size for the function, encoded in the LEB128 format

Limitations

The tool cannot follow indirect calls, which are the results of the use of function pointers or switch tables.