Google Performance Tool: Leaks Checking
Automatic Leaks Checking Support
This document describes how to check the heap usage of a C++ program. This
facility can be useful for automatically detecting memory leaks.
Linking in the Heap Checker
You can heap-check any program that has the tcmalloc library linked in. No
recompilation is necessary to use the heap checker.
In order to catch all heap leaks, tcmalloc must be linked last into your
executable. The heap checker may mischaracterize some memory accesses in
libraries listed after it on the link line. For instance, it may report these
libraries as leaking memory when they're not. (See the source code for more
details.)
It's safe to link in tcmalloc even if you don't expect to heap-check your
program. Your programs will not run any slower as long as you don't use any of
the heap-checker features.
You can run the heap checker on applications you didn't compile yourself, by
using LD_PRELOAD:
$ LD_PRELOAD="/usr/lib/libtcmalloc.so" HEAPCHECK=normal
We don't necessarily recommend this mode of usage.
Turning On Heap Checking
There are two alternatives to actually turn on heap checking for a given run
of an executable.
* For whole-program heap-checking, define the environment variable HEAPCHECK
to the type of heap checking you want: normal, strict, or draconian. For
instance, to heap-check /bin/ls:
$ HEAPCHECK=normal /bin/ls
% setenv HEAPCHECK normal; /bin/ls # csh
OR
* For partial-code heap-checking, you need to modify your code. For each piece
of code you want heap-checked, bracket the code by creating a HeapLeakChecker
object (which takes a descriptive label as an argument), and calling
check.NoLeaks() at the end of the code you want checked. This will verify no
more memory is allocated at the end of the code segment than was allocated in
the beginning. To actually turn on the heap-checking, set the environment
variable HEAPCHECK to local.
Here is an example of the second usage. The following code will die if Foo()
leaks any memory (i.e. it allocates memory that is not freed by the time it
returns):
HeapProfileLeakChecker checker("foo");
Foo();
assert(checker.NoLeaks());
When the checker object is allocated, it creates one heap profile. When
checker.NoLeaks() is invoked, it creates another heap profile and compares it to
the previously created profile. If the new profile indicates memory growth (or
any memory allocation change if one uses checker.SameHeap() instead), NoLeaks()
will return false and the program will abort. An error message will also be
printed out saying how pprof command can be run to get a detailed analysis of
the actual leaks.
See the comments for HeapProfileLeakChecker class in heap-checker.h and the
code in heap-checker_unittest.cc for more information and examples.
IMPORTANT NOTE: pthreads handling is currently incomplete. Heap leak checks
will fail with bogus leaks if there are pthreads live at construction or leak
checking time. One solution, for global heap-checking, is to make sure all
threads but the main thread have exited at program-end time. We hope (as of
March 2005) to have a fix soon.
Disabling Heap-checking of Known Leaks
Sometimes your code has leaks that you know about and are willing to accept.
You would like the heap checker to ignore them when checking your program. You
can do this by bracketing the code in question with an appropriate heap-checking
object:
#include
...
void *mark = HeapLeakChecker::GetDisableChecksStart();
<leaky code>
HeapLeakChecker::DisableChecksToHereFrom(mark);
Some libc routines allocate memory, and may need to be 'disabled' in this
way. As time goes on, we hope to encode proper handling of these routines into
the heap-checker library code, so applications needn't worry about them, but
that process is not yet complete.
Maxim Lifantsev
Last modified: Thu Mar 3 05:51:40 PST 2005
|