MAINPM User's Guide, Chapter 7

previous   next   top   contents   index   framed top   this page unframed


7. TRACECHUNKS Command

The command TRACECHUNKS {f} traces the allocation history of each chunk (dynamic object) allocated in a monitored area. The resulting printout is an aid in determining the origin of chunks that are garbage collected or still in existence at program termination.

f is the name of the output “trace file” into which the trace data are written; if omitted, MAINPM chooses a unique name. This is an auxiliary data file that is separate from the (pm statistics file) file. The data in the trace file are not human-readable; they are only for analysis by MAINPM. By default, this analysis is done upon return to MAINPM, in which case the trace file is deleted if f was not explicitly specified. The NOTRACEREPORT command suppresses this report so that it can be done in a later run of MAINPM. Since trace data are written at some sensitive points during memory management, low-level runtime routines are used to write f on the assumption that f is a normal disk file; therefore, a device prefix should not be specified as part of f's file name.

To use MAINPM just to analyze a trace file created during an earlier run, give MAINPM the TRACECHUNKS f command, where f is the name of the trace file created earlier, then give it the LIST g command where g is the name of the output file. The trace file is written in PDF (“portable data format”) so that it can be analyzed on a different kind of computer from that on which the run occurred. This may be necessary since the trace file may become quite large, in which case creation of the summary report uses a lot of memory, perhaps more than is available on the traced machine.

If a trace file is analyzed on a different operating system or MAINSAIL version number from the system where the trace file was generated, then when you analyze the file, you should give the TARGET command to specify the operating system abbreviation of the system where the trace file was created and/or the VERSION command to specify the MAINSAIL version under which it was created.

Data are written to the trace file every time a traced chunk is allocated, disposed, garbage collected, or reclaimed by $clearArea or $disposeArea. Data are also written for certain memory management events such as the movement of a traced chunk or chunk page in a traced area. The potentially large size of the trace file may prevent the use of the TRACECHUNKS command in some cases due to limitations on available disk space. Of course, the exact size for a given program execution depends on the number of traced events that occur.

An example of part of the report generated by MAINPM from the trace file is:

module{.proc}.offset                                  $clear/
{
file filePos}                                        $dispose   still
{
source text}            new's   dispose's  collects    Area   allocated
---------------------- --------- --------- --------- --------- ---------
LPIOPR.GENERATE.7984       67073         0      3936         0     63137
/
usr/clark/xp.new/lpiopr.ms 16351
pi := new(layoutPin);

LNIOPR.GENERATE.8104       36081         0      2120         0     33961
/
usr/clark/xp.new/lniopr.ms 16161
ni := new(layoutNode);

SPKOPR.GENERATE.13146      16323         0       961         0     15362
/
usr/clark/xp.new/defopr.hdr 2046
newRec := new(defaultClass);

CFGIO.STRUCTUREIN.4652     11407       133     10353         0       921
/
usr/clark/xp.new/cfgio.ms 22604
RETURN($structureRead(ctlFileAccess.ctlDataFile,

SEM0.OBJECTREAD.1514        4986       754         0      4210        22
/
usr/clark/xp.new/sem0.ms 7623
RETURN($structureRead(filePtr,objAddr,objSize,

PCKOPR.GENERATE.4604        3267         0       193         0      3074
/
usr/clark/xp.new/pckopr.ms 13355
pck := new(pckClass);

PCKOPR.GENERATE.4722        3266         0       193         0      3073
/
usr/clark/xp.new/pckopr.ms 13448
new(pck.subUnit,0,pck.subUnitCnt);

NODLIB.GETNEXTTOKEN.6954    3177         0         0      3177         0
/
usr/clark/xp.new/nodlib.ms 30373
token := new(tokenClass,processNodeLabelArea);

The entries are separated by a blank line. module.proc.offset shows where the allocations occurred. This point could have directly caused the allocation of a chunk, such as with new, $createRecord, $newRecords, or $structureRead, or indirectly, such as with a call to an unmonitored MODULE that caused chunks to be allocated.

file and filePos indicate the source that corresponds to the statement that caused the allocation. source text is the actual text for the statement (from the start of the statement to the end of the first line of the statement; more of the statement could be on subsequent lines).

proc, file, filePos, and source text are collectively referred to as the trace source information. An intmod for the MODULE must be available in order for the trace source information to be computable; source text also requires the original source file. This information can be suppressed in the trace report by specifying the NOTRACESRC command to MAINPM, e.g., if you know that the intmods or source files are not available. The TRACESRC command undoes the NOTRACESRC command (if you change your mind). IF NOTRACESRC is not in effect, MAINPM leaves out any information it cannot determine; e.g., if the intmod cannot be found, all of the trace source information is omitted; if the source file cannot be open, the source text is omitted.

Only chunks allocated in monitored areas are traced. Use the {NO}MONITORAREA commands to indicate which areas are to be monitored. By default, all areas are monitored.

Only monitored MODULEs are credited with chunk allocations. Use the {NO}MONITORMODULE and {NO}MONITORLIB commands (as described in Chapter 4) to specify which MODULEs are to be monitored. By default, MAINSAIL runtime system MODULEs are not monitored. Whenever a chunk is allocated in a monitored area, the PROCEDURE call stack is traversed to find the first monitored caller, and the chunk allocation is credited to that caller (if there is no monitored caller, the chunk allocation is not traced).

The first line of output in the example shows that 67073 chunks were allocated due to a call at offset 7984 from the start of the MODULE LPIOPR, in the PROCEDURE GENERATE. The source for the statement that allocated the chunks is in the file /usr/clark/xp.new/lpiopr.ms at position 16351. The text for the statement is pi := new(layoutPin);. The MAINED editor front end can be used to view the source by opening the indicated file and using the command V16352 (use 1 greater than the indicated value since MAINED uses 1-origin positions, whereas MAINPM reports 0-origin positions). Alternately, if LPIOPR is compiled debuggable, the source code at this location can be examined by using the MAINSAIL debugger by issuing the commands M LPIOPR (to set the current MODULE context to be LPIOPR) and then O 7984 (to put the cursor at the source code corresponding to the indicated code displacement).

The above debugger O command may put the cursor on the statement after the one that caused the allocation since the offset shown is actually the offset referenced by the return address to the PROCEDURE call that caused the chunks to be allocated, rather than to the call instruction itself. However, it is usually clear from the source which statement is responsible for the allocation. In order to use the debugger this way to view the source at the indicated offsets, the MODULEs must have been compiled debuggable. This approach is useful if the NOTRACESRC command was in effect, or the trace source information could not be obtained when the report was generated.

The new's column indicates how many chunks were allocated (directly or indirectly) due to a call at the location given by the first two columns. The output is sorted by ascending order of this column.

The dispose's column indicates how many of the chunks were explicitly disposed.

The collects column indicates how many of the chunks were reclaimed by the garbage collector. When TRACECHUNKS is in effect, MAINPM triggers a garbage collection (if $collectLock is zero) immediately upon return from the executed program so that this column accurately reflects how many chunks became garbage through the end of program execution.

The $clear/$disposeArea column indicates how many of the chunks were deallocated due to their area being cleared or disposed.

The still allocated column indicates how many of the chunks were still allocated upon return to MAINPM (after the garbage collection forced by MAINPM). This column is just equal to:

new's - dispose's - collects - $clear/$disposeArea

Note that the TRACECHUNKS command attributes to the monitored MODULE all allocations which occurred as a result of the MAINSAIL statement, whether direct or indirect. Therefore, there often appear more allocations in a TRACECHUNKS listing than you might suppose.

In particular, the first call to new for a particular CLASS will allocate the descriptor for that CLASS. If your program calls new(c) ten times and disposes the resulting record ten times, the TRACECHUNKS listing may show 11 chunks allocated, 10 disposed, and 1 still allocated. The still allocated chunk is the CLASS descriptor for the CLASS c.

A sample session with the TRACECHUNKS command based on the module FOO of Figure 7–1 is shown in Example 7–2. Note that FOO is compiled with the DEBUG compiler option, which includes instruction maps in the intmod so that the statement text can be written in the TRACECHUNKS listing.

Figure 7–1. Module FOO to Be Executed under TRACECHUNKS
BEGIN "foo"

CLASS c (INTEGER i);

INITIAL PROCEDURE;
BEGIN
INTEGER i;
FOR i := 1 UPTO 100 DO new(c);
END;

END "foo"

Example 7–2. Sample TRACECHUNKS Session
*compil<eol>

MAINSAIL (R) Compiler
Copyright (c) 1984-1998 by XIDAK, Inc., Point Arena,
 California, USA.


compile (? for help): foo.msl,<eol>
debug<eol>
<eol>
Opening intmod for $SYS...

foo.msl 1
Objmod for FOO stored on foo-mpn.obj
Intmod for FOO stored on foo-mpn.int

compile (? for help): <eol>
*
mainpm<eol>

MAINPM (tm) (type ? for help)
Copyright (c) 1984-1998 by XIDAK, Inc., Point Arena,
 California, USA.

MAINPMtracechunks<eol>
MAINPMexecute foo<eol>
Trace data in z21976.tmp
MAINPMlist tty<eol>
Total real time: 0 seconds
Total CPU time: .000 seconds
Total chunk space allocated: 2088
Total string space used (and not reclaimed): 62
Total static space allocated: 0
Analyzing trace data...
Deleted z21976.tmp
Printing trace data...
module{.proc}.offset                                  $clear/
{
file filePos}                                        $dispose   still
{
source text}            new's   dispose's  collects    Area   allocated
---------------------- --------- --------- --------- --------- ---------
Opening intmod for FOO from foo-mpn.int
Opening intmod for $SYS...

FOO.INITIALPROC.59           100         0       100         0         0
foo.msl 94
new(c);
                       --------- --------- --------- --------- ---------
                             100         0       100         0         0
MAINPMquit<eol>


previous   next   top   contents   index   framed top   this page unframed

MAINPM User's Guide, Chapter 7