Dr. Memory
Memory Leaks

Dr. Memory divides all memory that is still allocated at the time it does its leak scan into 3 categories:

  1. Memory that is still reachable by the application. This is NOT considered a leak. It is reported as "still-reachable allocation(s)" in Dr. Memory's summary. Many applications do not explicitly free memory whose lifetime matches the process lifetime and this is not considered an error by Dr. Memory.
  2. Memory that is definitely not reachable by the application (at least, not by an aligned pointer to the start or middle of the allocated block). This is called a "leak" by Dr. Memory, as there is no way for the application to free this memory: it has lost any handle it had to the memory.
  3. Memory that is reachable only via pointers to the middle of the allocation, rather than the head. This is called a "possible leak" by Dr. Memory. These may or may not be legimitate pointers to that allocation. There are several cases of known legitimate pointers that Dr. Memory recognizes using heuristics. None of these are listed as possible leaks unless the corresponding option is turned off:
    • One class of legitimate mid-allocation pointers includes C++ arrays allocated via new[] whose elements have destructors. The new[] operators adds a header but returns to the caller the address past the header. You can suppress Dr. Memory's identification of such mid-allocation pointers, causing them to show up as possible leaks, with the -no_midchunk_new_ok runtime option.
    • Another class, for some C++ compilers, includes instances of a pointer to a class with multiple inheritance that is cast to one of the parents: it can end up pointing to the subobject representation in the middle of the allocation. You can suppress Dr. Memory's identification of such mid-allocation pointers, causing them to show up as possible leaks, with the -no_midchunk_inheritance_ok runtime option.
    • The std::string class places a char[] array in the middle of an allocation and points directly at it. You can suppress Dr. Memory's identification of such mid-allocation pointers, causing them to show up as possible leaks, with the -no_midchunk_string_ok runtime option.
    • A final example is a custom malloc wrapper that uses a header and passes a pointer offset into the result from malloc. The free wrapper subtracts from the passed-in pointer in order to compute the pointer to the head of the allocated block. You can suppress Dr. Memory's identification of such mid-allocation pointers, causing them to show up as possible leaks, with the -no_midchunk_size_ok runtime option.

The two categories of leaks ("leaks" and "possible leaks") are further broken down into direct and indirect leaks. An indirect leak is a heap object that is reachable by a pointer to its start address, but with all such pointers originating in leaked objects. Leaks can be thought of as trees, with the top-level object the direct leaks and all child objects indirect leaks. Dr. Memory reports the size of all the child indirect leaks for each direct leak, but does not report a detailed callstack for indirect leaks. If the direct leak is addressed, the indirect leaks should no longer be leaked, making their details unnecessary.

By default, Dr. Memory performs leak checking at application exit, or when a mid-run check is requested via -nudge (see Applications That Do Not Exit). Nudges can be used to help determine when the last pointer to an allocation was lost, if the callstack of the allocation is not sufficient to pinpoint the error in the source code. Each nudge will perform a full leak scan and by nudging periodically the first instance of a particular leak can be used to identify when the leak occurred.

On Windows, when HeapDestroy is called, any live allocations inside are reported as possible leaks. This can be disabled, since some applications may consider it correct behavior, with the -no_check_leaks_on_destroy option.

Dr. Memory reports the number of leaks, possible leaks, and still-reachable allocations. The callstack for the allocation of each leak and possible leak is gathered by default and listed with other errors in the results file. To also see all of the reachable allocations, use the -show_reachable runtime option. Reachable allocations are labeled as REACHABLE LEAK. By default, without the -show_reachable option, reachable leak callstacks are not compared to suppressions, in order to reduce overhead.

Here are example lines from Dr. Memory's output summary:

~~Dr.M~~ ERRORS FOUND:
~~Dr.M~~ 5 unique, 5 total, 574 byte(s) of leak(s)
~~Dr.M~~ 0 unique, 0 total, 0 byte(s) of possible leak(s)
~~Dr.M~~ ERRORS IGNORED:
~~Dr.M~~ 5 unique, 8 total, 205 byte(s) of still-reachable allocation(s)
~~Dr.M~~ (re-run with "-show_reachable" for details)

And with -show_reachable, where the callstack for each still-reachable allocation will be in results.txt:

~~Dr.M~~ ERRORS FOUND:
~~Dr.M~~ 5 unique, 5 total, 574 byte(s) of leak(s)
~~Dr.M~~ 0 unique, 0 total, 0 byte(s) of possible leak(s)
~~Dr.M~~ 5 unique, 8 total, 205 byte(s) of still-reachable allocation(s)
~~Dr.M~~ NO ERRORS IGNORED

There are known sources of false positives where a memory allocation may actually be reachable by the application, but Dr. Memory's algorithm will determine that it is unreachable. These cases include:

  • The only stored pointers to an allocation are not aligned to 4 bytes.
  • The only stored pointers to an allocation are encrypted.
  • There is some custom mechanism to reach these allocations that does not involve a direct stored pointer into any part of the allocated block.

One known problem comes from using glib's memory allocator. To avoid false positives when using glib, set the following environment variables when running your application:

  • G_SLICE=always-malloc
  • G_DEBUG=gc-friendly