Previous: Library functions, Up: Using mpatrol
The mpatrol library provides a hash table called a leak table that can be used to record memory allocations and deallocations for the purpose of detecting memory leaks. It can be fully controlled from the source code of a program by calling the appropriate mpatrol library functions, but the mpatrol library can also be instructed to automatically enter the details of each memory event into the leak table by using the LEAKTABLE option.
The leak table records a flat profile of memory allocation behaviour between two points in a program and is keyed by source file location. What that means is, it contains an entry for each source file and line number that allocated memory, and if more than one memory allocation event occurred at that point then the entry will summarise the total events that occurred at that point. In many cases, the source file and line number is not available for a memory allocation event, in which case either the function name or the return address can be used instead.
The following example shows the use of the leak table manipulation functions.
1 /* 2 * Illustrates the explicit and implicit manipulation of the 3 * leak table. 4 */ 7 #include "mpatrol.h" 10 int main(void) 11 { 12 void *p, *q; 13 int r; 15 __mp_clearleaktable(); 16 __mp_addallocentry("file.c", 1, 1); 17 __mp_addfreeentry("file.c", 1, 1); 18 __mp_addallocentry("file.c", 1, 2); 19 __mp_addfreeentry("file.c", 1, 2); 20 __mp_addallocentry("file.c", 1, 3); 21 __mp_addfreeentry("file.c", 1, 3); 22 __mp_addallocentry("function", 0, 8); 23 __mp_addfreeentry("function", 0, 4); 24 __mp_addallocentry("function", 0, 16); 25 __mp_addfreeentry("function", 0, 12); 26 __mp_addallocentry(NULL, 0x40000000, 8); 27 r = __mp_startleaktable(); 28 if (p = malloc(16)) 29 if (q = realloc(p, 32)) 30 free(q); 31 else 32 free(p); 33 if (r == 0) 34 __mp_stopleaktable(); 35 __mp_leaktable(0, MP_LT_ALLOCATED, MP_LT_BOTTOM); 36 __mp_printf("\n"); 37 __mp_leaktable(0, MP_LT_FREED, MP_LT_COUNTS); 38 __mp_printf("\n"); 39 __mp_leaktable(0, MP_LT_UNFREED, 0); 40 __mp_printf("\n"); 41 return EXIT_SUCCESS; 42 }
The output that appears in mpatrol.log should look similar to this.
bottom 5 allocated memory entries in leak table: bytes count location -------- ------ -------- 6 3 file.c line 1 8 1 0x40000000 16 1 test.c line 28 24 2 function 32 1 test.c line 29 86 8 total top 4 freed memory entries in leak table: count bytes location ------ -------- -------- 3 6 file.c line 1 2 16 function 1 32 test.c line 29 1 16 test.c line 28 7 70 total top 2 unfreed memory entries in leak table: bytes count location -------- ------ -------- 8 1 0x40000000 8 0 function 16 1 total
Line 15 of the above program clears the leak table. This can be done as many times as necessary during the execution of the program, but note that there is only one leak table so this will affect the LEAKTABLE option. The following 6 lines then add matching allocation and deallocation entries to the leak table corresponding to a source location of line 1 in a file called file.c. Any deallocation entries must match the source position of the original allocation due to the nature of the leak table. Note that these 6 lines correspond to an allocation of 1 byte, followed by two reallocations of 2 and 3 bytes respectively, followed by a final deallocation.
Lines 22-23 allocate 8 bytes from a function called function()
but only
free 4 bytes, resulting in a memory leak of 4 bytes. Lines 24-25 do the same
but allocate 16 bytes and free 12. The next line allocates 8 bytes from a
code address of `0x40000000' but does not free it, resulting in a memory
leak of 8 bytes. Note that if the line number is specified as `0' then
the filename will be taken as a function name, and if the filename is specified
as `NULL' then the line number will be taken as a return address. If
neither are specified then the number of bytes will be added or subtracted from
the `unknown' location.
Line 27 instructs mpatrol to automatically record any subsequent memory
allocation events in the leak table, while line 34 does the opposite. The
__mp_startleaktable()
function returns `1' if automatic leak table
recording was turned on and `0' otherwise, so we check in line 33 to see if
we should turn off automatic recording by examining the previous state. Lines
28-32 allocate, reallocate and free some memory just to demonstrate this.
Finally, lines 35-40 display the contents of the memory leak table that have
been recorded since the call to __mp_clearleaktable()
. Three different
types of display can be generated: allocated memory allocations, freed memory
allocations and unfreed memory allocations. They can also be sorted by the
total number of calls instead of the total number of bytes (MP_LT_COUNTS
)
or in reverse order with the smallest first (MP_LT_BOTTOM
). The count of
`0' in the last table indicates that there were a matching number of calls
to allocate and free memory within function()
but the number of bytes
freed was less than the number of bytes allocated. This can only happen if
the entries were added by __mp_addallocentry()
and
__mp_addfreeentry()
and is usually an indication that something is wrong
when making these calls.
The leak table is a useful tool to manipulate when debugging your application to check for memory leaks, but it is not as detailed as full memory allocation profiling which is controlled by the PROF option. It is probably better at summarising unfreed allocations than the SHOWUNFREED option but does not show the call stack for each allocation.
In addition, the __mp_iterate()
function can be used within user code to
obtain details about changes in the heap since a certain point in a program's
execution. However, it can only provide details about freed memory allocations
if the NOFREE option is used. The leak table will provide less details
on freed memory allocations but its advantage is that it does not require the
use of the NOFREE option.