Next: , Previous: dmalloc, Up: Tools


8.3 Determining heap differences

This file defines heapdiffstart() and heapdiffend(), which must be called in matching pairs. They both take a heapdiff object as their first parameter, which must still be in scope when the matching call to heapdiffend() is made. The heapdiff object is initialised at the call to heapdiffstart() and is finalised when heapdiffend() is called. It must not be modified in between and should be treated as an opaque type. heapdiffend() can only be called once per heapdiff object before requiring that the heapdiff object be reinitialised through a call to heapdiffstart().

The second parameter to heapdiffstart() specifies a set of flags that can be used to control what is written to the mpatrol log. A list of all unfreed memory allocations can be logged with the HD_UNFREED flag and a list of all freed memory allocations can be logged with the HD_FREED flag, although the latter makes use of the NOFREE option and can incur a large performance and space penalty, and also relies on the NOFREE option being unmodified between the calls to heapdiffstart() and heapdiffend(). Note that marked allocations are not normally logged but this can be changed by adding the HD_MARKED flag.

By default, only a minimal amount of detail is logged for each allocation, but this can be changed with the HD_FULL flag to log full details for each allocation. If the filename and line number for an allocation is known and the EDIT or LIST option is being used then using HD_VIEW will edit or list the relevant source file at the correct line number, but only if the EDIT or LIST options are supported.

If the HD_CONTENTS flag is specified then the contents of all current memory allocations will be written to files and then compared with their subsequent contents when heapdiffend() is called. If the heap is large then this option can require a substantial amount of disk space. All of the allocation contents files will be deleted when the matching call to heapdiffend() is made.

      1  /*
      2   * Illustrates the use of mpatrol's heap difference tool.
      3   */
     
     
      6  #include "mpatrol/heapdiff.h"
     
     
      9  int main(void)
     10  {
     11      char *p, *q;
     12      heapdiff h;
     
     14      p = (char *) calloc(8, 1);
     15      q = (char *) calloc(8, 1);
     16      heapdiffstart(h, HD_FREED | HD_UNFREED | HD_FULL | HD_CONTENTS);
     17      p = (char *) realloc(p, 16);
     18      q[4] = ' ';
     19      heapdiffend(h);
     20      return EXIT_SUCCESS;
     21  }

Running with the LOGALL option should produce something similar to the following in the mpatrol log file.

     ALLOC: calloc (23, 8 bytes, 8 bytes) [main|test.c|14]
             0x00012BD4 main+56
             0x00012A68 _start+100
     
     returns 0x0002A570
     
     ALLOC: calloc (24, 8 bytes, 8 bytes) [main|test.c|15]
             0x00012C0C main+112
             0x00012A68 _start+100
     
     returns 0x0002A578
     
     > HEAPDIFF 1 STARTING at test.c line 16 {
             0x00012C30 main+148
             0x00012A68 _start+100
     
     REALLOC: realloc (0x0002A570, 16 bytes, 8 bytes) [main|test.c|17]
             0x00012C6C main+208
             0x00012A68 _start+100
     
         0x0002A570 (8 bytes) {calloc:23:0} [main|test.c|14]
             0x00012BD4 main
             0x00012A68 _start
     
     returns 0x0002E590
     
     > } HEAPDIFF 1 ENDING at test.c line 19
             0x00012CA0 main+260
             0x00012A68 _start+100
     
     > allocation differences:
     
     allocation 24 (0x0002A578) differences:
             0x0002A57C  00 -> 20 (offset 4)
     
         0x0002A578 (8 bytes) {calloc:24:0} [main|test.c|15]
             0x00012C0C main
             0x00012A68 _start
     
     allocation 23 (0x0002E590) has increased in size
     
         0x0002E590 (16 bytes) {realloc:23:1} [main|test.c|17]
             0x00012C6C main
             0x00012A68 _start
     
     > total differences: 2 (2 allocations)
     
     > freed allocations:
     
         0x0002A570 (8 bytes) {realloc:23:0} [main|test.c|17]
             0x00012C6C main
             0x00012A68 _start
     
     > total freed: 1 (8 bytes)
     
     > unfreed allocations:
     
         0x0002E590 (16 bytes) {realloc:23:1} [main|test.c|17]
             0x00012C6C main
             0x00012A68 _start
     
     > total unfreed: 1 (16 bytes)