GNAT GPL User's Guide: Stack Related Facilities

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

# 24. Stack Related Facilities

This chapter describes some useful tools associated with stack checking and analysis. In particular, it deals with dynamic and static stack usage measurements.

> 24.1 Stack Overflow Checking |  |
> 24.2 Static Stack Usage Analysis |  |
> 24.3 Dynamic Stack Usage Analysis |  |

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 24.1 Stack Overflow Checking

For most operating systems, `gcc` does not perform stack overflow checking by default. This means that if the main environment task or some other task exceeds the available stack space, then unpredictable behavior will occur. Most native systems offer some level of protection by adding a guard page at the end of each task stack. This mechanism is usually not enough for dealing properly with stack overflow situations because a large local variable could "jump" above the guard page. Furthermore, when the guard page is hit, there may not be any space left on the stack for executing the exception propagation code. Enabling stack checking avoids such situations.

To activate stack checking, compile all units with the gcc option ``-fstack-check'`. For example:

    gcc -c -fstack-check package1.adb

Units compiled with this option will generate extra instructions to check that any use of the stack (for procedure calls or for declaring local variables in declare blocks) does not exceed the available stack space. If the space is exceeded, then a `Storage_Error` exception is raised.

For declared tasks, the stack size is controlled by the size given in an applicable `Storage_Size` pragma or by the value specified at bind time with ``-d'` (see section 4.2 Switches for `gnatbind`) or is set to the default size as defined in the GNAT runtime otherwise.

For the environment task, the stack size depends on system defaults and is unknown to the compiler. Stack checking may still work correctly if a fixed size stack is allocated, but this cannot be guaranteed. To ensure that a clean exception is signalled for stack overflow, set the environment variable `GNAT_STACK_LIMIT` to indicate the maximum stack area that can be used, as in:

    SET GNAT_STACK_LIMIT 1600

The limit is given in kilobytes, so the above declaration would set the stack limit of the environment task to 1.6 megabytes. Note that the only purpose of this usage is to limit the amount of stack used by the environment task. If it is necessary to increase the amount of stack for the environment task, then this is an operating systems issue, and must be addressed with the appropriate operating systems commands.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 24.2 Static Stack Usage Analysis

A unit compiled with ``-fstack-usage'` will generate an extra file that specifies the maximum amount of stack used, on a per-function basis. The file has the same basename as the target object file with a ``.su'` extension. Each line of this file is made up of three fields:

- The name of the function.
- A number of bytes.
- One or more qualifiers: `static`, `dynamic`, `bounded`.

The second field corresponds to the size of the known part of the function frame.

The qualifier `static` means that the function frame size is purely static. It usually means that all local variables have a static size. In this case, the second field is a reliable measure of the function stack utilization.

The qualifier `dynamic` means that the function frame size is not static. It happens mainly when some local variables have a dynamic size. When this qualifier appears alone, the second field is not a reliable measure of the function stack analysis. When it is qualified with `bounded`, it means that the second field is a reliable maximum of the function stack utilization.

A unit compiled with ``-Wstack-usage'` will issue a warning for each subprogram whose stack usage might be larger than the specified amount of bytes. The wording is in keeping with the qualifier documented above.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 24.3 Dynamic Stack Usage Analysis

It is possible to measure the maximum amount of stack used by a task, by adding a switch to `gnatbind`, as:

    $ gnatbind -u0 file

With this option, at each task termination, its stack usage is output on ``stderr'`. It is not always convenient to output the stack usage when the program is still running. Hence, it is possible to delay this output until program termination. for a given number of tasks specified as the argument of the ``-u'` option. For instance:

    $ gnatbind -u100 file

will buffer the stack usage information of the first 100 tasks to terminate and output this info at program termination. Results are displayed in four columns:

Index | Task Name | Stack Size | Stack Usage

where:

Index
  is a number associated with each task.

Task Name
  is the name of the task analyzed.

Stack Size
  is the maximum size for the stack.

Stack Usage
  is the measure done by the stack analyzer. In order to prevent overflow, the stack is not entirely analyzed, and it's not possible to know exactly how much has actually been used.

The environment task stack, e.g., the stack that contains the main unit, is only processed when the environment variable GNAT_STACK_LIMIT is set.

The package `GNAT.Task_Stack_Usage` provides facilities to get stack usage reports at run-time. See its body for the details.

[ << ] | [ >> ] |  |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

This document was generated by GNAT Mailserver on April, 17 2014 using texi2html