Blame doc/leak.html

Packit d28291
Packit d28291
<html lang="en-us">
Packit d28291
<HEAD>
Packit d28291
<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII" >
Packit d28291
<TITLE>Using the Garbage Collector as Leak Detector</title>
Packit d28291
</head>
Packit d28291
<BODY>
Packit d28291

Using the Garbage Collector as Leak Detector

Packit d28291
The garbage collector may be used as a leak detector.
Packit d28291
In this case, the primary function of the collector is to report
Packit d28291
objects that were allocated (typically with <TT>GC_MALLOC</tt>),
Packit d28291
not deallocated (normally with <TT>GC_FREE</tt>), but are
Packit d28291
no longer accessible.  Since the object is no longer accessible,
Packit d28291
there in normally no way to deallocate the object at a later time;
Packit d28291
thus it can safely be assumed that the object has been "leaked".
Packit d28291

Packit d28291
This is substantially different from counting leak detectors,
Packit d28291
which simply verify that all allocated objects are eventually
Packit d28291
deallocated.  A garbage-collector based leak detector can provide
Packit d28291
somewhat more precise information when an object was leaked.
Packit d28291
More importantly, it does not report objects that are never
Packit d28291
deallocated because they are part of "permanent" data structures.
Packit d28291
Thus it does not require all objects to be deallocated at process
Packit d28291
exit time, a potentially useless activity that often triggers
Packit d28291
large amounts of paging.
Packit d28291

Packit d28291
All non-ancient versions of the garbage collector provide
Packit d28291
leak detection support.  Version 5.3 adds the following
Packit d28291
features:
Packit d28291
    Packit d28291
  1. Leak detection mode can be initiated at run-time by
  2. Packit d28291
    setting <TT>GC_find_leak</tt> instead of building the
    Packit d28291
    collector with <TT>FIND_LEAK</tt>
    Packit d28291
    defined.  This variable should be set to a nonzero value
    Packit d28291
    at program startup.
    Packit d28291
  3. Leaked objects should be reported and then correctly garbage collected.
  4. Packit d28291
    Prior versions either reported leaks or functioned as a garbage collector.
    Packit d28291
    Packit d28291
    For the rest of this description we will give instructions that work
    Packit d28291
    with any reasonable version of the collector.
    Packit d28291

    Packit d28291
    To use the collector as a leak detector, follow the following steps:
    Packit d28291
      Packit d28291
    1. Build the collector with <TT>-DFIND_LEAK</tt>. Otherwise use default
    2. Packit d28291
      build options.
      Packit d28291
    3. Change the program so that all allocation and deallocation goes
    4. Packit d28291
      through the garbage collector.
      Packit d28291
    5. Arrange to call <TT>GC_gcollect</tt> at appropriate points to check
    6. Packit d28291
      for leaks.
      Packit d28291
      (For sufficiently long running programs, this will happen implicitly,
      Packit d28291
      but probably not with sufficient frequency.)
      Packit d28291
      Packit d28291
      The second step can usually be accomplished with the
      Packit d28291
      <TT>-DREDIRECT_MALLOC=GC_malloc</tt> option when the collector is built,
      Packit d28291
      or by defining <TT>malloc</tt>, <TT>calloc</tt>,
      Packit d28291
      <TT>realloc</tt> and <TT>free</tt>
      Packit d28291
      to call the corresponding garbage collector functions.
      Packit d28291
      But this, by itself, will not yield very informative diagnostics,
      Packit d28291
      since the collector does not keep track of information about
      Packit d28291
      how objects were allocated.  The error reports will include
      Packit d28291
      only object addresses.
      Packit d28291

      Packit d28291
      For more precise error reports, as much of the program as possible
      Packit d28291
      should use the all uppercase variants of these functions, after
      Packit d28291
      defining <TT>GC_DEBUG</tt>, and then including <TT>gc.h</tt>.
      Packit d28291
      In this environment <TT>GC_MALLOC</tt> is a macro which causes
      Packit d28291
      at least the file name and line number at the allocation point to
      Packit d28291
      be saved as part of the object.  Leak reports will then also include
      Packit d28291
      this information.
      Packit d28291

      Packit d28291
      Many collector features (e.g. stubborn objects, finalization,
      Packit d28291
      and disappearing links) are less useful in this context, and are not
      Packit d28291
      fully supported.  Their use will usually generate additional bogus
      Packit d28291
      leak reports, since the collector itself drops some associated objects.
      Packit d28291

      Packit d28291
      The same is generally true of thread support.  However, as of 6.0alpha4,
      Packit d28291
      correct leak reports should be generated with linuxthreads.
      Packit d28291

      Packit d28291
      On a few platforms (currently Solaris/SPARC, Irix, and, with -DSAVE_CALL_CHAIN,
      Packit d28291
      Linux/X86), <TT>GC_MALLOC</tt>
      Packit d28291
      also causes some more information about its call stack to be saved
      Packit d28291
      in the object.  Such information is reproduced in the error
      Packit d28291
      reports in very non-symbolic form, but it can be very useful with the
      Packit d28291
      aid of a debugger.
      Packit d28291

      An Example

      Packit d28291
      The following header file <TT>leak_detector.h</tt> is included in the
      Packit d28291
      "include" subdirectory of the distribution:
      Packit d28291
      Packit d28291
      #define GC_DEBUG
      Packit d28291
      #include "gc.h"
      Packit d28291
      #define malloc(n) GC_MALLOC(n)
      Packit d28291
      #define calloc(m,n) GC_MALLOC((m)*(n))
      Packit d28291
      #define free(p) GC_FREE(p)
      Packit d28291
      #define realloc(p,n) GC_REALLOC((p),(n))
      Packit d28291
      #define CHECK_LEAKS() GC_gcollect()
      Packit d28291
      Packit d28291

      Packit d28291
      Assume the collector has been built with <TT>-DFIND_LEAK</tt>.  (For
      Packit d28291
      newer versions of the collector, we could instead add the statement
      Packit d28291
      <TT>GC_find_leak = 1</tt> as the first statement in <TT>main()</tt>.
      Packit d28291

      Packit d28291
      The program to be tested for leaks can then look like:
      Packit d28291
      Packit d28291
      #include "leak_detector.h"
      Packit d28291
      Packit d28291
      main() {
      Packit d28291
          int *p[10];
      Packit d28291
          int i;
      Packit d28291
          /* GC_find_leak = 1; for new collector versions not         */
      Packit d28291
          /* compiled with -DFIND_LEAK.                               */
      Packit d28291
          for (i = 0; i < 10; ++i) {
      Packit d28291
              p[i] = malloc(sizeof(int)+i);
      Packit d28291
          }
      Packit d28291
          for (i = 1; i < 10; ++i) {
      Packit d28291
              free(p[i]);
      Packit d28291
          }
      Packit d28291
          for (i = 0; i < 9; ++i) {
      Packit d28291
              p[i] = malloc(sizeof(int)+i);
      Packit d28291
          }
      Packit d28291
          CHECK_LEAKS();
      Packit d28291
      }
      Packit d28291
      Packit d28291

      Packit d28291
      On an Intel X86 Linux system this produces on the stderr stream:
      Packit d28291
      Packit d28291
      Leaked composite object at 0x806dff0 (leak_test.c:8, sz=4)
      Packit d28291
      Packit d28291
      (On most unmentioned operating systems, the output is similar to this.
      Packit d28291
      If the collector had been built on Linux/X86 with -DSAVE_CALL_CHAIN,
      Packit d28291
      the output would be closer to the Solaris example. For this to work,
      Packit d28291
      the program should not be compiled with -fomit_frame_pointer.)
      Packit d28291

      Packit d28291
      On Irix it reports
      Packit d28291
      Packit d28291
      Leaked composite object at 0x10040fe0 (leak_test.c:8, sz=4)
      Packit d28291
              Caller at allocation:
      Packit d28291
                      ##PC##= 0x10004910
      Packit d28291
      Packit d28291
      and on Solaris the error report is
      Packit d28291
      Packit d28291
      Leaked composite object at 0xef621fc8 (leak_test.c:8, sz=4)
      Packit d28291
              Call chain at allocation:
      Packit d28291
                      args: 4 (0x4), 200656 (0x30FD0)
      Packit d28291
                      ##PC##= 0x14ADC
      Packit d28291
                      args: 1 (0x1), -268436012 (0xEFFFFDD4)
      Packit d28291
                      ##PC##= 0x14A64
      Packit d28291
      Packit d28291
      In the latter two cases some additional information is given about
      Packit d28291
      how malloc was called when the leaked object was allocated.  For
      Packit d28291
      Solaris, the first line specifies the arguments to <TT>GC_debug_malloc</tt>
      Packit d28291
      (the actual allocation routine), The second the program counter inside
      Packit d28291
      main, the third the arguments to <TT>main</tt>, and finally the program
      Packit d28291
      counter inside the caller to main (i.e. in the C startup code).
      Packit d28291

      Packit d28291
      In the Irix case, only the address inside the caller to main is given.
      Packit d28291

      Packit d28291
      In many cases, a debugger is needed to interpret the additional information.
      Packit d28291
      On systems supporting the "adb" debugger, the <TT>tools/callprocs.sh</tt>
      Packit d28291
      script can be used to replace program counter values with symbolic names.
      Packit d28291
      As of version 6.1, the collector tries to generate symbolic names for
      Packit d28291
      call stacks if it knows how to do so on the platform.  This is true on
      Packit d28291
      Linux/X86, but not on most other platforms.
      Packit d28291

      Simplified leak detection under Linux

      Packit d28291
      Since version 6.1, it should be possible to run the collector in leak
      Packit d28291
      detection mode on a program a.out under Linux/X86 as follows:
      Packit d28291
        Packit d28291
      1. Ensure that a.out is a single-threaded executable, or you are using
      2. Packit d28291
        a very recent (7.0alpha7+) collector version on Linux.
        Packit d28291
        On most platforms this does not work at all for the multi-threaded programs.
        Packit d28291
      3. If possible, ensure that the <TT>addr2line</tt> program is installed in
      4. Packit d28291
        <TT>/usr/bin</tt>.  (It comes with most Linux distributions.)
        Packit d28291
      5. If possible, compile your program, which we'll call <TT>a.out</tt>,
      6. Packit d28291
        with full debug information.
        Packit d28291
        This will improve the quality of the leak reports.  With this approach, it is
        Packit d28291
        no longer necessary to call <TT>GC_</tt> routines explicitly,
        Packit d28291
        though that can also
        Packit d28291
        improve the quality of the leak reports.
        Packit d28291
      7. Build the collector and install it in directory foo as follows:
      8. Packit d28291
          Packit d28291
        • <TT>configure --prefix=foo --enable-gc-debug --enable-redirect-malloc
        • Packit d28291
          --disable-threads</tt>
          Packit d28291
        • <TT>make</tt>
        • Packit d28291
        • <TT>make install</tt>
        • Packit d28291
          Packit d28291
          With a very recent collector on Linux, it may sometimes be safe to omit
          Packit d28291
          the <TT>--disable-threads</tt>.  But the combination of thread support
          Packit d28291
          and <TT>malloc</tt> replacement is not yet rock solid.
          Packit d28291
        • Set environment variables as follows:
        • Packit d28291
            Packit d28291
          • <TT>LD_PRELOAD=</tt>foo<TT>/lib/libgc.so</tt>
          • Packit d28291
          • <TT>GC_FIND_LEAK</tt>
          • Packit d28291
          • You may also want to set <TT>GC_PRINT_STATS</tt>
          • Packit d28291
            (to confirm that the collector is running) and/or
            Packit d28291
            <TT>GC_LOOP_ON_ABORT</tt> (to facilitate debugging from another
            Packit d28291
            window if something goes wrong).
            Packit d28291
            Packit d28291
          • Simply run <TT>a.out</tt> as you normally would. Note that if you run anything
          • Packit d28291
            else (e.g. your editor) with those environment variables set,
            Packit d28291
            it will also be leak tested.  This may or may not be useful and/or
            Packit d28291
            embarrassing.  It can generate
            Packit d28291
            mountains of leak reports if the application wasn't designed to avoid leaks,
            Packit d28291
            e.g. because it's always short-lived.
            Packit d28291
            Packit d28291
            This has not yet been thoroughly tested on large applications, but it's known
            Packit d28291
            to do the right thing on at least some small ones.
            Packit d28291
            </body>
            Packit d28291
            </html>