Table of Contents
Link your program against the cstdmf library,
and ensure every source file includes the
cstdmf.hpp
header.
Then, run the program in the DEBUG configuration, and if leaks occur they will be output in the debugger, when the program exits, in the following format:
MemTracker detected the following leaks: Slot: Default, Id: 5007 - 88 bytes Slot: Default, Id: 8695 - 44 bytes Slot: Default, Id: 8883 - 60 bytes Slot: Default, Id: 8884 - 60 bytes Slot: Default, Id: 9435 - 28 bytes Slot: Default, Id: 9436 - 20 bytes Slot: Default, Id: 20975 - 116 bytes Slot: Default, Id: 20976 - 16 bytes Slot: Default, Id: 392363 - 12 bytes
Note MemTracker
can be enabled for any
build configuration by defining preprocessor symbol
ENABLE_MEMTRACKER for that configuration.
To enter the debugger on the first allocation in the example above, add the following line to your program (outside of a function body).
MEMTRACKER_BREAK_ON_ALLOC( Default, 5007 );
Often it is convenient to divide up allocations into slots based
on function scope. To do this, MemTracker
allows
you to define slots.
MEMTRACKER_DECLARE( Foo, "Foo's allocations", 0 ); void Foo() { MEMTRACKER_SCOPED( Foo ); DoFooStuff(); DoOtherStuff(); }
This will mark any allocations in Foo()
,
DoFooStuff()
and
DoOtherStuff()
as belonging to the
"Foo" slot, and each allocation will be numbered
uniquely within the "Foo" slot. Slots are organised
into a stack, so DoFooStuff()
may contain its own
definition for a slot, and its own leaks could be reported there.
If you do not supply any slots, then the top level slot called Default is used.
Sometimes it isn't convenient to fix leaks as soon as they are found. If this is the case, you can prevent leaks from being reported by declaring a slot with the FLAG_DONT_REPORT flag. In the example above, if we wished to ignore all leaks in the Foo slot, we would declare the slot like so:
MEMTRACKER_DECLARE( Foo, "Foo's allocations", FLAG_DONT_REPORT );
If you require a stack trace for a leak, you should define the
ENABLE_CALLSTACK symbol as 1 in
memory_tracker.h
and add the
FLAG_CALLSTACK flag to the definition. Use of this
flag requires a large amount of overhead per allocation, so it is
recommended for use within a small scope (for example, do not enable it
in a slot that contains more than a few hundred allocations).
Here is an example stack trace from a leak, reading from bottom to
top, the offending function is the one that calls
bw_malloc()
, in this case
foo()
:
e:\mf_19_0\src\lib\cstdmf\memory_tracker.cpp (514): bw_malloc e:\mf_19_0\src\lib\cstdmf\unit_test\test_memory_tracker.cpp (73): foo e:\mf_19_0\src\lib\cstdmf\unit_test\test_memory_tracker.cpp (79): bar e:\mf_19_0\src\lib\cstdmf\unit_test\test_memory_tracker.cpp (84): wuu e:\mf_19_0\src\lib\cstdmf\unit_test\test_memory_tracker.cpp (90): MemoryTracker_testCallstackTest::RunTest e:\mf\src\lib\third_party\cppunitlite2\src\test.cpp (40): Test::Run e:\mf\src\lib\third_party\cppunitlite2\src\testregistry.cpp (37): TestRegistry::Run e:\mf\src\lib\unit_test_lib\unit_test.cpp (59): BWUnitTest::runTest e:\mf\src\lib\cstdmf\unit_test\main.cpp (12): main f:\sp\vctools\crt_bld\self_x86\crt\src\crtexe.c (597): __tmainCRTStartup f:\sp\vctools\crt_bld\self_x86\crt\src\crtexe.c (414): mainCRTStartup ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 76CE4911) 76CE4911 (kernel32): (filename not available): BaseThreadInitThunk ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 7743E4B6) 7743E4B6 (ntdll): (filename not available): RtlInitializeExceptionChain ERROR: SymGetLineFromAddr64, GetLastError: 487 (Address: 7743E489) 7743E489 (ntdll): (filename not available): RtlInitializeExceptionChain