HOWTO use Valgrind to debug memory problems

From Nsnam
Revision as of 20:27, 22 May 2012 by Tommaso (Talk | contribs) (Common errors)

Jump to: navigation, search

Main Page - Current Development - Developer FAQ - Tools - Related Projects - Project Ideas - Summer Projects

Installation - Troubleshooting - User FAQ - HOWTOs - Samples - Models - Education - Contributed Code - Papers

Memory leaks or errors can be found with Valgrind. Support for valgrind is built into the ./waf system by typing:

 ./waf --command-template="valgrind [options] %s" --run ns-3-program-name

for example:

 ./waf --command-template="valgrind --leak-check=full --show-reachable=yes %s" -- run main-propagation-loss

Common errors

Please list hints here as to what kind of errors have known resolution.

Failure to call Simulator::Destroy()

Simulator::Destroy() will free memory that is created with the ns-3 object system. Forgetting to call Simulator::Destroy () when you are done will lead to reachable memory being reported by valgrind, such as this trace of the main-propagation-loss example:

 ==16325== 88 bytes in 1 blocks are still reachable in loss record 4 of 4
 ==16325==    at 0x4A069D5: operator new(unsigned long) (vg_replace_malloc.c:261)
 ==16325==    by 0x4C87A6B: ns3::TypeId ns3::TypeId::AddConstructor<ns3::DefaultSimulatorImpl>()::Maker::Create() (type-id.h:429)
 ==16325==    by 0x4C778A3: ns3::FunctorCallbackImpl<ns3::ObjectBase* (*)(), ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty>::operator()() (callback.h:166)
 ==16325==    by 0x4CBF22C: ns3::Callback<ns3::ObjectBase*, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty>::operator()() const (callback.h:407)
 ==16325==    by 0x4CBE05E: ns3::ObjectFactory::Create() const (
 ==16325==    by 0x4C8569E: ns3::Ptr<ns3::SimulatorImpl> ns3::ObjectFactory::Create<ns3::SimulatorImpl>() const (object-factory.h:110)
 ==16325==    by 0x4C823FB: ns3::GetImpl() (
 ==16325==    by 0x4C831B1: ns3::Simulator::Stop(ns3::Time const&) (
 ==16325==    by 0x404157: TestDeterministic(ns3::Ptr<ns3::PropagationLossModel>) (
 ==16325==    by 0x405CC1: main (
 ==16325== LEAK SUMMARY:
 ==16325==    definitely lost: 0 bytes in 0 blocks
 ==16325==    indirectly lost: 0 bytes in 0 blocks
 ==16325==      possibly lost: 0 bytes in 0 blocks
 ==16325==    still reachable: 200 bytes in 4 blocks
 ==16325==         suppressed: 0 bytes in 0 blocks
 ==16325== For counts of detected and suppressed errors, rerun with: -v
 ==16325== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 7 from 7)

Here, the clue is the line that says "ns3::Ptr<ns3::SimulatorImpl> ns3::ObjectFactory::Create<ns3::SimulatorImpl>() const (object-factory.h:110)" and the lines above it. If you see an error such as that reporting "still reachable" blocks, it is often the case that you forgot to call Simulator::Destroy() to free objects that have been created as factory objects. memory leaks

Sometimes a memory leak pop up on a test program (the ones enabled by "configure --enable-tests" and launched with "./ -g something"). That's ok, the test programs are there with this precise purpose: to show memory leaks and to check the correct ns-3 behavior.

The trick, however, is to *not* search for the memory leak using the test program. Write an equivalent ns-3 simulation, the simple, the better. Then use valgrind on that one, find the leak and exterminate it. The rationale is: the test programs are launched by a slightly different system than the usual waf launcher (built to run a lot of different tests sequentially). Hence, you could find in the valgrind report a lot of obscure data that (probably) will point you in the wrong direction.

If, however, you can not replicate the memory leak in a "normal" ns-3 simulation, remember that the memory leak might be as well in the test program... in that case: good luck.