Chapter Contents

Previous

Next
Command Directory

storage

Display Storage Analysis

ABBREVIATION
sto{rage}

FORMAT
storage [heap|stack] [check|report] [file|term] [narrow|wide]

DESCRIPTION
The storage command prints an analysis of the program's use of both heap and stack storage. Heap storage is storage allocated by the malloc and calloc functions. Once allocated, this type of storage remains allocated until it is freed. Stack storage is storage used for automatic variables and register save areas. This storage is allocated when a function is entered and is freed when the function returns.

The storage command is executed by the same subsystem as that used when the run-time =storage option is used.

The keywords can be specified in any order. If conflicting options are entered, the last (rightmost) option is used.

heap
specifies that the analysis is to be limited to heap storage only.

free
specifies that free heap blocks are to be checked. All chains and blocks in free heap storage are inspected for correctness and consistency. If an error is detected, the block will be dumped.

stack
specifies that the analysis is to be limited to stack storage only. If neither heap nor stack is used, the analysis includes both.

check
specifies that the storage is to be checked; that is, the control blocks that describe the storage allocated are to be inspected for correctness and consistency. This type of analysis is similar to that performed by the library when heap storage is freed or when the program terminates. If check is used, storage attempts to predict storage-related user abends and to indicate the problem area.

report
specifies that the debugger is to produce a storage use report. If neither check nor report is used, the analysis includes both. Note that a report is not generated until the storage is checked for consistency.

file
specifies that the analysis is to be written to a file. Under OS/390 batch, the analysis is written to the data set allocated to the DDname DBGSTG. Under TSO, the debugger attempts to use DBGSTG. If the DD statement for the name DBGSTG is not defined, the output is written to 'DSN: userid.pgmnameDBGSTG'. If NOPREFIX is specified in your TSO profile, 'DSN: prefix.pgmname.DBGSTG' or a TSO prefix is specified. In either case, pgmname is the name of the program. If the program name cannot be determined, the debugger uses UNKNOWN as the pgmname. Under CMS it is written to the A-disk, using the program name as the filename and a filetype of DGBSTG.

The output of subsequent storage commands is appended to the output of the first. Each part of the analysis is identified by a header similar to the first line of a traceback.

term
specifies that the analysis is to be displayed on the terminal. Under CMS and TSO, term is the default. Under OS/390 batch, it is written to DBGLOG. User-installed debugger I/O exits have no effect on the output of the storage command.

narrow
specifies that the output is to be limited to 80 columns.

wide
specifies that the output is to be displayed in 132-column format. If neither narrow nor wide is used, the debugger chooses a format based on the choice of term or file. The term output defaults to narrow, and file output defaults to wide.

Interpreting the Reports: The following paragraphs explain how heap and stack allocation is performed by the run-time library. This information is necessary to understand the reports generated by the storage command. The following explanation is not exhaustive, but it gives enough information for you to understand and use the output from the storage command.

Heap storage: Heap storage is allocated by the malloc and calloc functions. Both functions interface to a routine called the heap manager to allocate storage. The heap manager creates control information for the allocated storage block and formats the storage block so that overlays (that is, information written outside the boundaries of the storage block) can be detected. When an overlay is detected (either when the storage is freed or when the program terminates), the heap manager issues a user ABEND. This alerts the programmer to storage overlays.

The heap manager can adjust the size of the allocated storage block in order to reduce fragmentation. Suppose the program allocates a 10-byte block using the following function call:

p = malloc(10);

The heap manager rounds the request size (10 bytes) to the next multiple of 8, which is 16 bytes. Then it adds 16 bytes of control information to the request, in the form of an 8-byte block header and an 8-byte block trailer.

If the request size is larger than 288 bytes, the heap manager adds the size of the header and trailer information to the request size and then rounds the sum to the next higher multiple of 64. For example, the following request results in a 320-byte (5 * 64) storage block:

p = malloc(300);

Validation: The most common storage overlay is caused by writing into the storage either immediately preceding or immediately following the boundaries of the storage block. For example, a program may allocate a 100-byte I/O buffer and then read 110 bytes of data into it. The heap storage manager formats the storage block so that this type of error is detected easily. Part of the control information is the word HEAP in the 4 bytes immediately preceding and following the original 16-byte block. The block looks like the following:

xxxxHEAPzzzzzzzzzzzzzzzzHEAPxxxx

In the original 16-byte block, x is a byte of control information and z is a byte.

If the program has written over either of the HEAP markers when the storage block is freed, the heap manager detects that the storage was overlaid.

Similarly, when a storage block is freed, the heap manager changes the HEAP markers to FREE, as shown in the following:

xxxxFREEzzzzzzzzzzzzzzzzFREExxxx

These markers remain in place until the block is reallocated or the program terminates; at which time, if either marker is changed, the heap storage manager detects the overlay.

The heap manager also ensures the validity of its own internal control blocks and performs other consistency checks to determine if a storage overlay occurred.

If the check option is used, the storage command performs the same consistency checks as the heap manager. Instead of issuing a user ABEND, storage displays a formatted dump of the block in question. The programmer can use this information to trace the error that caused the overlay.

Reporting usage: In order to reduce storage fragmentation, the heap manager keeps track of freed storage blocks. When the program allocates another block, the heap manager checks for a freed block of the same or larger size. If one exists, the heap manager reallocates it instead of allocating a new storage block. If the report keyword is used, the storage command counts the number of allocated and freed storage blocks to produce a report on heap storage usage by the program.

Stack storage: Stack storage is storage that is allocated automatically for auto variables, register save areas, and other temporary use by a function. Normally, stack storage is allocated from the stack when a function is called and is returned to the stack when the function returns. However, if the stack overflows (that is, runs out of available storage), the stack manager is called to allocate another block of storage for the stack.

Each stack storage block is called a tract. Just as the heap manager formats heap storage blocks, the stack manager formats tracts. The start of the tract is marked with the word AST and the end with the word EAST. The stack manager also maintains control information about the stack, including information on the current size of the stack and the stack top.

The part of the stack that is allocated for each function is called a DSA (dynamic save area). Part of the DSA is a register save area. These save areas are chained to each other.

Validation: As the stack manager operates, the tract markers, save area chains, and the stack control information are checked for consistency. If an overlay is detected for example, caused by storing outside the boundaries of an auto array the stack manager issues a user ABEND.

If the check option is used, the storage command performs these same checks. If an overlay is detected, the storage command produces a dump of the overlaid storage. Because most validation by the stack manager is delayed until program termination, it is difficult to determine which function in the program is causing the problem. The storage command is used to localize the bug.

Reporting usage: If the report option is used, the storage command produces a report showing how many DSAs are in use. Usually this corresponds to the number of functions in the calling sequence. The report also shows how much of the stack is unused.

Coprocess stacks: If the program uses the coprocessing functions, storage checks and reports on each coprocess's stack separately.

EXAMPLES
The following line-mode example shows the output produced by the storage command in an uncorrupted situation.
CDEBUG:
storage
At     SUB1(PGM1)     entry    ------
  SIZE: FREE/USED  SIZE: FREE/USED  SIZE: FREE/USED  SIZE: FREE/USED
    24:    0/116     32:    0/118     40:    0/18      48:    0/69
    56:    0/10      64:    0/7       72:    0/59      80:    0/10
    88:    0/9       96:    0/4      104:    0/3      120:    0/2
   144:    0/5      152:    0/1      160:    0/1      280:    0/1
   512:    1/0      792:    1/0     1152:    1/0     1472:    1/1
  1792:    0/2     8192:    0/1
No corruptions found in heap.

  SIZE  NUMBER  SIZE  NUMBER  SIZE  NUMBER  SIZE  NUMBER  SIZE  NUMBER

   152:    1     168:    1     208:    1     248:    1     256:    1
   296:    2     672:    1
 Total unused space in stack (bytes): 1768
No corruptions found in stack.

In this example, neither heap nor stack is specified, so storage produces a report for both. Also, because neither check nor report is specified, storage both checks the storage and produces a report on its use. Because no output option (term or file) is specified, the report is displayed on the terminal in the narrow format.

Line 1 shows the current function name and section name.

At     SUB1(PGM1)     entry    ------

The current hook is entry to the function.

Lines 2 through 8 show the heap storage usage report. Each of the six lines following the subtitle is divided into four columns. There is an entry for each size of allocated storage block. For example, the following entry in line 3, column 1 shows that there are 116 allocated blocks of size 24 and no freed blocks:

24:     0/116

Similarly, the following entry in line 7, column 1 shows that there is one free block of size 512 and no allocated blocks:

512:     1/0

Note that the block size shown in the entry is the size known to the heap manager. This size includes the 16 bytes of header and trailer information, plus rounding. For example, the 10-byte allocation discussed earlier in Heap storage is shown as an entry for 32-byte blocks.

The large number of 24- and 32-byte blocks (representing allocations of 1 to 8 bytes and 9 to 16 bytes, respectively) indicates that this program can benefit from memory pooling via pool and its related functions.

The last part of the heap report, line 9, indicates that storage detected no overlays in heap storage.

No corruptions found in heap.

The stack report consists of two lines (12 and 13) of output divided into five columns. Each entry in the report shows the number of DSAs allocated by size. For example, the following entry shows that two 296-byte DSAs are in use:

296:     2

Line 14 of the report shows the amount of unused stack space, 1768 bytes. Again, storage reports that no overlays are detected in the stack.

The next example shows the output from storage when a heap storage block is overlaid.

CDEBUG: }

storage check heap
At     SUB1(PGM1)         2    00005A
LSCD622 Block (size: 00000078 (120)) at address 00007F20 has been
        overwritten.
        Header Address: 00007F20     Trailer Address: 00007F90
 00007F20   00000078  C8C5C1D7  FCFCFCFC  FCFCFCFC *....HEAP........*
 00007F30   FCFCFCFC  FCFCFCFC  FCFCFCFC  FCFCFCFC *................*
                         .
                         .
                         .
 00007F50   FCFCFCFC  FCFCFCFC  FCFCFCFC  FCFCFCFC *................*
 00007F60 TO 00007F90 SAME AS ABOVE .................
 00007F90   C7C5C1D7  00008310  00000078  FFFFFFFF *GEAP..c.........*

Because the check keyword is specified, storage does not produce a report. (In fact, because heap storage is corrupted, no usage report is created.) The heap keyword limits the analysis to heap storage. Again, the output is displayed on the terminal in 80-column format.

In this example, a 104-byte storage block is allocated, starting at 0x7f28. The heap manager adds header and trailer information at 0x7f20 and 0x7f90, respectively, resulting in a 120-byte storage allocation. This information is summarized in message LSCD622:

LSCD622 Block (size: 00000078 (120)) at address 00007F20 has been overwritten.
        Header Address: 00007F20     Trailer Address: 00007F90

The program has not yet changed the contents of the storage block at all. It manages, though, to overwrite the byte immediately following the end of the block, at 0x7f90, with the letter G. Because this changes a heap storage marker from HEAP to GEAP, storage detects the change and produces a dump.

In this example, storage is uncertain about the exact location of the overlay. Either the program overlays the HEAP marker in the trailer information or the length of the block is overwritten (in which case GEAP can be user data). Therefore, storage dumped the first 32 bytes of the storage block, including the header information, and then dumped 32 bytes surrounding the probable end of the block.

The next example shows the output produced by storage when it detects a stack overlay.

CDEBUG:

storage check stack
At     SUB1(PGM1)         2    00005A
LSCD612 Auto storage control block has been overwritten at 00005FB5.
 00005F98   00000FE0  00005FA8  00000000  40C1E2E3    *......^y.... AST*
 00005FA8   0000C6E8  00000000  00000000=>00000000    *..FY............*

In this example, storage analysis is limited to stack storage by use of the stack option.

The overlay is not obvious in this example. Note, however, that storage adds a => at the location (0x5fb0) where it detects the overlay. The storage command puts this mark in the dump when it can show the location of the overlay exactly.

Assuming that an earlier storage check shows no corruption, it is likely that one of the functions in the current calling sequence caused the overlay. (The where command can be used to produce a traceback.) From this information, it should be easy to check these functions to determine if one is storing a word of 0x00's outside the boundaries of its stack storage.

SYSTEM DEPENDENCIES
The name of the file that is used when the file keyword is used depends on the operating system. (See DESCRIPTION.)

Under OS/390, the debugger tries to open DBGSTG only once, the first time storage is used. If it is not defined, all subsequent storage output is written to 'DSN: userid.pgmname.DBGSTG' if NOPREFIX is specified in your TSO profile, or 'DSN: prefix.pgmname.DBGSTG' if a TSO prefix is specified. That is, you cannot use the system command to allocate a data set to DBGSTG after the storage command is used.

COMMAND CAN BE ISSUED FROM

PROFILE no
configuration file no
Source window prefix none

SCOPE
The storage command is not affected by changes in scope.

RETURN CODES SET
Successful: 0
Unsuccessful: 1


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.