GNATstack – Stack Analysis Tool

GNATstack is a software analysis tool that enables Ada/C/C++ software development teams to accurately predict the maximum size of the memory stack required to host an embedded software application.

The GNATstack tool statically predicts the maximum stack space required by each task in an application. The computed bounds can be used to ensure that sufficient space is reserved, thus guaranteeing safe execution with respect to stack usage. The tool uses a conservative analysis to deal with complexities such as subprogram recursion, while avoiding unnecessarily pessimistic estimates.

This static stack analysis tool exploits data generated by the compiler to compute worst-case stack requirements. It performs per-subprogram stack usage computation combined with control flow analysis.

GNATstack is able to analyse object-oriented applications, automatically determining maximum stack usage on code that uses dynamic dispatching in both Ada and C++. A dispatching call challenges static analysis because the identity of the subprogram being invoked is not known until run time. GNATstack solves the problem by statically determining the subset of potential target primitive operations for every dispatching call. This heavily reduces the analysis effort and yields precise stack usage bounds on complex Ada/C++ code.

This is a static tool in the sense that its computation is based on information known at compile time. It implies that when the tool indicates that the result is accurate then the computed bound can never overflow.

On the other hand, there may be situations in which the results will not be accurate (the tool will actually indicate this situation) because of some missing information (such as subprogram recursion, indirect calls, etc.). We provide the infrastructure to allow users to specify this missing call graph and stack usage information.

The main output of the tool is the worst-case stack usage for every entry point, together with the paths that lead to these stack needs. The list of entry points can be automatically computed (all the tasks, including the environment task) or can be specified by the user (a list of entry points or all the subprograms matching a certain regular expression).

The tool can also detect and display a list of potential problems when computing stack requirements:

  • Indirect (including dispatching) calls. The tool will indicate the number of indirect calls made from any subprogram.
  • External calls. The tool displays all the subprograms that are reachable from any entry point for which we do not have any stack or call graph information.
  • Unbounded frames. The tool displays all the subprograms that are reachable from any entry point with an unbounded stack requirements. The required stack size depends on the arguments passed to the subprogram.
  • Cycles. The tool can detect all the cycles in the call graph.

The tool will allow the user to specify in a text file the missing information, such as the potential targets for indirect calls, stack requirements for externals calls, and user-defined bounds for unbounded frames.