Heap debugging functionality.

This document describes the HEAPTRC unit for Free Pascal. It was written by Pierre Muller. It is system independent, and works on all supported systems.

The HEAPTRC unit can be used to debug your memory allocation/deallocation. It keeps track of the calls to getmem/freemem, and, implicitly, of New/Dispose statements.

When the program exits, or when you request it explicitly. It displays the total memory used, and then dumps a list of blocks that were allocated but not freed. It also displays where the memory was allocated.

If there are any inconsistencies, such as memory blocks being allocated or freed twice, or a memory block that is released but with wrong size, this will be displayed also.

The information that is stored/displayed can be customized using some constants.

HeapTrc Usage

All that you need to do is to include heaptrc in the uses clause of your program. Make sure that it is the first unit in the clause, otherwise memory allocated in initialization code of units that precede the heaptrc unit will not be accounted for, causing an incorrect memory usage report.

If you use the -gh switch, the compiler will insert the unit by itself, so you don't have to include it in your uses clause.

The below example shows how to use the heaptrc unit.

This is the memory dump shown when running this program in a standard way:

Marked memory at 0040FA50 invalid Wrong size : 128 allocated 64 freed 0x00408708 0x0040CB49 0x0040C481 Call trace for block 0x0040FA50 size 128 0x0040CB3D 0x0040C481

If you use the lineinfo unit (or use the -gl switch) as well, then heaptrc will also give you the filenames and line-numbers of the procedures in the backtrace:

Marked memory at 00410DA0 invalid Wrong size : 128 allocated 64 freed 0x004094B8 0x0040D8F9 main, line 25 of heapex.pp 0x0040D231 Call trace for block 0x00410DA0 size 128 0x0040D8ED main, line 23 of heapex.pp 0x0040D231

If lines without filename/line-number occur, this means there is a unit which has no debug info included.

Controlling HeapTrc with environment variables

The HeapTrc unit can be controlled with the HEAPTRC environment variable. The contents of this variable controls the initial setting of some constants in the unit. HEAPTRC consists of one or more of the following strings, separated by spaces:

keepreleased
  If this string occurs, then the variable is set to True
disabled
  If this string occurs, then the variable is set to False and the heap trace is disabled. It does not make sense to combine this value with other values.
nohalt
  If this string occurs, then the variable is set to False, so the program continues executing even in case of a heap error.
log=filename
  If this string occurs, then the output of heaptrc is sent to the specified Filename. (see also )

The following are valid values for the HEAPTRC variable:

HEAPTRC=disabled HEAPTRC="keepreleased log=heap.log" HEAPTRC="log=myheap.log nohalt"

Note that these strings are case sensitive, and the name of the variable too.

The FillExtraInfoProc is a procedural type used in the call.
The TFillExtraInfoProc is a procedural type used in the call to fill a memory location with extra data for displaying.
The TDisplayExtraInfoProc is a procedural type used in the call.
The TDisplayExtraInfoType is a procedural type used in the call to display a memory location which was previously filled with
Specify size of callback trace
Tracesize
specifies how many levels of calls are displayed of the call stack during the memory dump. If you specify keepreleased:=True then half the TraceSize is reserved for the GetMem call stack, and the other half is reserved for the FreeMem call stack. For example, the default value of 8 will cause eight levels of call frames to be dumped for the getmem call if keepreleased is False. If KeepReleased is true, then 4 levels of call frames will be dumped for the GetMem call and 4 frames wil be dumped for the FreeMem call. If you want to change this value, you must recode the heaptrc unit.
Do quick trace or extensive trace
Quicktrace
determines whether the memory manager checks whether a block that is about to be released is allocated correctly. This is a rather time consuming search, and slows program execution significantly, so by default it is set to True.
If set to false, the heap trace will be disabled.
This variable must be set at program startup, through the help of an environment variable.
Halt program on memory fault
If HaltOnError is set to True then an illegal call to FreeMem will cause the memory manager to execute a halt(1) instruction, causing a memory dump. By Default it is set to True.
Keep released blocks in memory
If keepreleased is set to true, then a list of freed memory blocks is kept. This is useful if you suspect that the same memory block is released twice. However, this option is very memory intensive, so use it sparingly, and only when it's really necessary.
Check for memory overwrites
If add\_tail is True (the default) then a check is also performed on the memory location just behind the allocated memory.
Use CRC check on allocated memory
If usecrc is True (the default) then a crc check is performed on locations before and after the allocated memory. This is useful to detect memory overwrites.
Dump memory usage report to stderr.
DumpHeap
dumps to standard output a summary of memory usage. It is called automatically by the heaptrc unit when your program exits (by installing an exit procedure), but it can be called at any time.
None.
Mark memory blocks with a signature.
MarkHeap
marks all memory blocks with a special signature. You can use this if you think that you corruped the memory.
None.
Store extra information in blocks.

You can use SetHeapExtraInfo to store extra info in the blocks that the heaptrc unit reserves when tracing getmem calls. Size indicates the size (in bytes) that the trace mechanism should reserve for your extra information. For each call to getmem, FillProc will be called, and passed a pointer to the memory reserved.

When dumping the memory summary, the extra info is shown by calling displayproc and passing it the memory location which was filled by fillproc. It should write the information in readable form to the text file provided in the call to displayproc

You can only call SetHeapExtraInfo if no memroy has been allocated yet. If memory was already allocated prior to the call to SetHeapExtraInfo, then an error will be displayed on standard error output, and a is executed.
Specify filename for heap trace output.
SetHeapTraceOutput
sets the filename into which heap trace info will be written. By default information is written to standard output, this function allows you to redirect the information to a file with full filename name.
If the file cannot be written to, errors will occur when writing the trace.