Stack usage analysis
This page describes how to perform a stack usage analysis using the linker.
In the rl78\src directory, you can find an example project that demonstrates stack usage analysis.
Introduction to stack usage analysis
Under the right circumstances, the linker can accurately calculate the maximum stack usage for each call graph, starting from the program start, interrupt functions, tasks etc. (each function that is not called from another function, in other words, the root).
If you enable stack usage analysis, a stack usage chapter will be added to the linker map file, listing for each call graph root the particular call chain which results in the maximum stack depth.
The analysis is only accurate if there is accurate stack usage information for each function in the application.
In general, the compiler will generate this information for each C function, but if there are indirect calls—calls using function pointers—in your application, you must supply a list of possible functions that can be called from each calling function.
If you use a stack usage control file, you can also supply stack usage information for functions in modules that do not have stack usage information.
You can use the check that directive in your stack usage control file to check that the stack usage calculated by the linker does not exceed the stack space you have allocated.
Performing a stack usage analysis
Enable stack usage analysis:
Caution
In the IDE, choose Project>Options>Linker>Advanced>Enable stack usage analysis.
Enable the linker map file:
Caution
In the IDE, choose Project>Options>Linker>List>Generate linker map file.
Danger
On the command line, use the linker option
‑‑map.Link your project.
Note: The linker will issue warnings related to stack usage under certain circumstances, see Situations where warnings are issued.
Review the linker map file, which now contains a stack usage chapter with a summary of the stack usage for each call graph root. For more information, see Result of an analysis—the map file contents.
For more details, analyze the call graph log, see Call graph log.
Note: There are limitations and sources of inaccuracy in the analysis, see Limitations.
You might need to specify more information to the linker to get a more representative result. See Specifying additional stack usage information.
Caution
In the IDE, choose Project>Options>Linker>Advanced>Enable stack usage analysis>Control file.
To add an automatic check that you have allocated memory enough for the stack, use the
check thatdirective in your linker configuration file. For example, assuming a stack block namedMY_STACK, you can write like this:check that size(block MY_STACK) >=maxstack("Program entry") + totalstack("interrupt") + 100;When linking, the linker emits an error if the check fails. In this example, an error will be emitted if the sum of the following exceeds the size of the
MY_STACKblock:The maximum stack usage in the category
Program entry(the main program).The sum of each individual maximum stack usage in the category
interrupt(assuming that all interrupt routines need space at the same time).A safety margin of 100 bytes (to account for stack usage not visible to the analysis).
See also check that directive and Stack considerations.
Result of an analysis—the map file contents
When stack usage analysis is enabled, the linker map file contains a stack usage chapter with a summary of the stack usage for each call graph root category, and lists the call chain that results in the maximum stack depth for each call graph root. This is an example of what the stack usage chapter in the map file might look like:
*****************************************************************
*** STACK USAGE
***
Call Graph Root Category Max Use Total Use
‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑ ‑‑‑‑‑‑- ‑‑‑‑‑‑‑‑-
interrupt 104 136
Program entry 168 168
Program entry
"__iar_program_start": 0x000085ac
Maximum call chain 168 bytes
"__iar_program_start" 0
"__cmain" 0
"main" 8
"printf" 24
"_PrintfTiny" 56
"_Prout" 16
"putchar" 16
"__write" 0
"__dwrite" 0
"__iar_sh_stdout" 24
"__iar_get_ttio" 24
"__iar_lookup_ttioh" 0
interrupt
"FaultHandler": 0x00008434
Maximum call chain 32 bytes
"FaultHandler" 32
interrupt
"IRQHandler": 0x00008424
Maximum call chain 104 bytes
"IRQHandler" 24
"do_something" in suexample.o [1] 80
The summary contains the depth of the deepest call chain in each category as well as the sum of the depths of the deepest call chains in that category.
Each call graph root belongs to a call graph root category to enable convenient calculations in check that directives.
Limitations
Apart from missing or incorrect stack usage information, there are also other sources of inaccuracy in the analysis:
The linker cannot always identify all functions in object modules that lack stack usage information. In particular, this might be a problem with object modules written in assembler language or produced by non-IAR tools. You can provide stack usage information for such modules using a stack usage control file, and for assembler language modules you can also annotate the assembler source code with
CFIdirectives to provide stack usage information. See Call frame information directives for stack usage analysis.If you use inline assembler to change the frame size or to perform function calls, this will not be reflected in the analysis.
Extra space consumed by other sources (the processor, an operating system, etc) is not accounted for.
If you use other forms of function calls, they will not be reflected in the call graph.
Using multi-file compilation (
‑‑mfc) can interfere with using a stack usage control file to specify properties of module-local functions in the involved files.
Note
Stack usage analysis produces a worst case result. The program might not actually ever end up in the maximum call chain, by design, or by coincidence. In particular, the set of possible destinations for a virtual function call in C++ might sometimes include implementations of the function in question which cannot, in fact, be called from that point in the code.
Warning
Stack usage analysis is only a complement to actual measurement. If the result is important, you need to perform independent validation of the results of the analysis.
Situations where warnings are issued
When stack usage analysis is enabled in the linker, warnings will be generated in the following circumstances:
There is a function without stack usage information.
There is an indirect call site in the application for which a list of possible called functions has not been supplied.
There are no known indirect calls, but there is an uncalled function that is not known to be a call graph root.
The application contains recursion (a cycle in the call graph) for which no maximum recursion depth has been supplied, or which is of a form for which the linker is unable to calculate a reliable estimate of stack usage.
There are calls to a function declared as a call graph root.
You have used the stack usage control file to supply stack usage information for functions in a module that does not have such information, and there are functions referenced by that module which have not been mentioned as being called in the stack usage control file.
Call graph log
To help you interpret the results of the stack usage analysis, there is a log output option that produces a simple text representation of the call graph (‑‑log call_graph).
Example output:
Program entry:
0 __iar_program_start [168]
0 __cmain [168]
0 __iar_data_init3 [16]
8 __iar_zero_init3 [8]
16 - [0]
8 __iar_copy_init3 [8]
16 - [0]
0 __low_level_init [0]
0 main [168]
8 printf [160]
32 _PrintfTiny [136]
88 _Prout [80]
104 putchar [64]
120 __write [48]
120 __dwrite [48]
120 __iar_sh_stdout [48]
144 __iar_get_ttio [24]
168 __iar_lookup_ttioh [0]
120 __iar_sh_write [24]
144 - [0]
88 __aeabi_uidiv [0]
88 __aeabi_idiv0 [0]
88 strlen [0]
0 exit [8]
0 _exit [8]
0 __exit [8]
0 __iar_close_ttio [8]
8 __iar_lookup_ttioh [0] ***
0 __exit [8] ***Each line consists of this information:
The stack usage at the point of call of the function
The name of the function, or a single '-' to indicate usage in a function at a point with no function call (typically in a leaf function)
The stack usage along the deepest call chain from that point. If no such value could be calculated,
"[‑‑-]"is output instead."***"marks functions that have already been shown.
Call graph XML output
The linker can also produce a call graph file in XML format. This file contains one node for each function in your application, with the stack usage and call information relevant to that function. It is intended to be input for post-processing tools and is not particularly human-readable.
For more information about the XML format used, see the callGraph.txt file in your product installation.