STACK(3)

NAME
_beginStackCheck, _endStackCheck - report stack usage

SYNOPSIS
#include <gno/gno.h>

void _assertStack (unsigned int needed, int line, const char *file);
void _beginStackCheck (void);
int _endStackCheck (void);
unsigned int _getStackBottom (void);

DESCRIPTION
The _beginStackCheck and _endStackCheck routines are intended to determine the required stack usage for a program during the development cycle. _beginStackCheck should be called as soon as possible after the program starts. _endStackCheck should be called just prior to program exit. _endStackCheck will return the number of bytes of stack space used by the program. The result can then be used as a lower bound for the argument to occ's -s flag, or the stacksize pragma for ORCA/C.

The _getStackBottom routine returns the lowest direct page address which can legally be used for the stack. (The stack on the 65816 grows downward.) This routine is used internally in libc and should not normally be needed by an application.

The _assertStack routine ensures that there are at least needed bytes left unused on the stack. If this is not the case, then _assertStack prints an appropriate error message and calls exit(3) with a value of 1. This routine is intended for use when you have a function that is either directly or indirectly recursive, and you do not want to use the ORCA/C stack checking mechanism for every function in your source file. The needed number of bytes is usually determined either through code inspection or empirically (lseg(1) is a good tool for assisting in this determination). Either way, you should probably make needed slightly larger than the value you expect to need.

If file is non-NULL, then _assertStack will also print out the file name and line number as specified. These values are available in any C program as the macros __FILE__ and __LINE__, respectively.

CAVEAT
The _assertStack routine itself uses stack space, especially when printing out error messages. Ensure you allow at least 100 bytes extra to allow for this.

EXAMPLE
An easy way to use the first two routines is to make use of the atexit(3) function, so that you don't have to determine all the possible exit points of your program. The GNO base sources make use of the macro __STACK_CHECK__ to control whether or not this check is done. You may want to use the same macro.
  #include <stdio.h>
  #include <gno/gno.h>
  #ifdef __STACK_CHECK__
  void cleanup (void) {
    fprintf(stderr,"Stack Usage: %d bytes, _endStackCheck());
  }
  #endif
  void main (int argc, char **argv) {
  #ifdef __STACK_CHECK__
    _beginStackCheck();
    atexit(cleanup);
  #endif
    ... <program continues> ...
The _assertStack routine is typically used in the following manner:
  #include <gno/gno.h>
  int recurse (int arg) {
    int i, j;
    /*
     * The value 350 was determined through code
     * inspection or with the help of lseg(1).
     */
    _assertStack(350, __LINE__, __FILE__);
    ... <routine continues> ...
    i = recurse(j);
    ... <routine continues> ...
    return i;
  }

AUTHORS
Phillip Vandry <vandry@cam.org> Devin Reade <gdr@myrias.com>

HISTORY
The _beginStackCheck and _endStackCheck routines first appeared as stand-along object file, under the names begin_stack_check and end_stack_check. They were first incorporated into GNO in v2.0.6.

The _getMinStack and _assertStack routines first appeared in GNO v2.0.6.

SEE ALSO
lseg(1), occ(1), atexit(3), exit(3).
The ORCA/C Reference Manual, Chapter 12.