For Developers‎ > ‎How-Tos‎ > ‎

Using the heap leak checker

The heap leak checker has been deprecated in favor of LeakSanitizer.

Heap leak checker is a part of perftools that allows to find memory leaks in C++ programs on Linux. For more details see http://google-perftools.googlecode.com/svn/trunk/doc/heap_checker.html.

To use heap checker, make sure it's enabled in your binaries (i.e. "linux_use_heapchecker" GYP variable is set to 1). You may also need to set linux_keep_shadow_stacks to 1.

You can check the Heapchecker bots on the waterfall to see what flags they use. As of May 2012, the Linux Heapchecker bot uses:
GYP_DEFINES=use_allocator=tcmalloc linux_use_heapchecker=1 linux_keep_shadow_stacks=1 werror= component=static_library

Be sure to run with a Debug build. Several people have reported Release builds do not work.

Then run the binary with the HEAPCHECK environment variable set to "strict" (see the documentation for other possible values of this variable).
After the program exits, heapchecker prints the allocation stack traces of all memory chunks that haven't been deallocated (i.e. possible memory leaks).
For example:

Leak of 512 bytes in 1 objects allocated from:
    @ 0xab5cdf __gnu_cxx::new_allocator::allocate
    @ 0xab5d0c std::_Deque_base::_M_allocate_node
    @ 0xab5d35 std::_Deque_base::_M_create_nodes
    @ 0xab5e0f std::_Deque_base::_M_initialize_map
    @ 0xab5eb2 std::_Deque_base::_Deque_base
    @ 0xab5f1f std::deque::deque
    @ 0xab5ff7 std::queue::queue
    @ 0xefd4da IPC::Channel::ChannelImpl::ChannelImpl
    @ 0xefd66f IPC::Channel::Channel
    @ 0xeff42b IPC::ChannelProxy::Context::CreateChannel
    @ 0xeff493 IPC::ChannelProxy::Init
    @ 0xeff64c IPC::ChannelProxy::ChannelProxy
    @ 0xf079c8 IPC::SyncChannel::SyncChannel
    @ 0xddeeb8 ChildThread::Init
    @ 0xddf0eb ChildThread::ChildThread
    @ 0xe44ac6 RenderThread::RenderThread
    @ 0x7c63ba ::RenderThreadTest::SetUp
    @ 0xfbd9df testing::Test::Run
    @ 0xfc1188 testing::internal::TestInfoImpl::Run
    @ 0xfc12be testing::TestCase::Run
    @ 0xfc1d1d testing::internal::UnitTestImpl::RunAllTests
    @ 0xfc1e6d testing::UnitTest::Run
    @ 0xec8135 TestSuite::Run
    @ 0xec6d31 main
    @ 0x2b10a1c851c4 __libc_start_main

The output also contains a command line for pprof invocation:

pprof src/sconsbuild/Debug/unit_tests "/tmp/unit_tests.16295._main_-end.heap" --inuse_objects --lines --heapcheck  --edgefraction=1e-10 --nodefraction=1e-10 --gv

This is used to visualize the found leaks.

Using heapchecker with the Chromium test suite


For Chromium tests there's a wrapper that is capable of running the tests with heap checker enabled and applying suppressions to them (it's almost similar to Valgrind test wrapper)
To run a test binary you can just type:
        tools/heapcheck/chrome_tests.sh -t unit

(--gtest_filter option also works)

The suppressions file is located at tools/heapcheck/suppressions.txt
A suppression stanza for the given report looks like the following one:

{
   bug_12345
   Heapcheck:Leak
   ...
   fun:
IPC::Channel::ChannelImpl::ChannelImpl
   fun:
IPC::Channel::Channel
   fun:
IPC::ChannelProxy::Context::CreateChannel
   fun:IPC::ChannelProxy::Init
   fun:IPC::ChannelProxy::ChannelProxy
   fun:IPC::SyncChannel::SyncChannel

}

Note that a suppression should not necessarily contain the whole leak stack -- a suppression applies if it matches the stack's top.
The ellipsis ("...") stands for a wildcard matching zero or more stack lines. It's also possible to use an asterisk ("*") as a wildcard matching zero or more symbols in a line.

A buildbot executing heapcheck-enabled tests is up at the Memory waterfall.

Adding a new test

When you add a new test to the Chromium test suite or a third party project, make sure the test binary depends on base/allocator/allocator.gyp:allocator
You anyway need it in order for tcmalloc to work.

Known issues

Short stacks

For some of the leaks only the top function in the stack is reported. For example:

Leak of 57664 bytes in 1802 objects allocated from:

    @ 0x2b10a073afce FcPatternObjectAddWithBinding

This usually means that this function is called from a library built without frame pointers. To fix this issue, try to replace the corresponding library with its debug version.

Not enough memory

For large binaries pprof may die reporting that it cannot allocate memory. It may help to increase the swap size on the
machine running the tests.

version GLIBCXX_3.4.5 not defined in file libstdc++.so.6 with link time reference

On some systems heapcheck won't run due to the relocation errors. That means that for some reason ld.so can't preload the debug version of libstdc++.so.6
To make sure it's so, run

   
LD_PRELOAD=/usr/lib/debug/libstdc++.so <path to your test>

 – the same error should be reported.

To work around this problem, you can locally disable pre-loading libstdc++.so.6 in src/tools/heapcheck/heapcheck_test.py

Note that disabling LD_PRELOAD may break some report stacks (see Short Stacks above), so some existing suppressions may not apply.

Alternatively, you can obtain a newer debug version of libstdc++. ("apt-get install libstdc++6-4.2-dbg" on goobuntu).
This will add a file /usr/lib/debug/libstdc++.so.6.0.9. To check that the version is up to date: "strings libstdc++.so | grep GLIBCXX" should return the missing version. 
Now, "ln -s /usr/lib/debug/libstdc++.so.6.0.9 /usr/lib/debug/libstdc++.so".

Comments