Noeud « Next »: , Noeud « Previous »: GCC, Noeud « Up »: Tools



5.5 Valgrind, The Ultimate Memory Debugger

Valgrind is an open-source memory debugger for x86-GNU/Linux written by Julian Seward, already known for having committed Bzip2. It is the best news for programmers for years. Unfortunately, due to EPITA's choice of NetBSD using Valgrind will not be convenient for you... Nevertheless, Valgrind is so powerful, so beautifully designed that you definitely should wander on the Valgrind Home Page to learn what you are missing.

In the case of the Tiger Compiler Project correct memory management is a primary goal. To this end, Valgrind is a precious tool, as is dmalloc, but because STL implementations are often keeping some memory for efficiency, you might see “leaks” from your C++ library. See its documentation on how to reclaim this memory. For instance, reading the GCC's C++ Library FAQ, especially the item “memory leaks” in containers is enlightening.

I personally use the following shell script to track memory leaks:

     #! /bin/sh

     exec 3>&1
     export GLIBCPP_FORCE_NEW=1
     export GLIBCXX_FORCE_NEW=1
     exec valgrind --num-callers=20 \
                   --leak-check=yes \
                   --leak-resolution=high \
                   --show-reachable=yes \
                   "$@" 2>&1 1>&3 3>&- |
       sed 's/^==[0-9]*==/==/' >&2 1>&2 3>&-
     File 153: v

For instance on Voir Example 58,

     $ v tc -A 0.tig
     error-->== Memcheck, a memory error detector for x86-linux.
     error-->== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
     error-->== Using valgrind-2.1.0, a program supervision framework for x86-linux.
     error-->== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
     error-->== Estimated CPU clock rate is 1667 MHz
     error-->== For more details, rerun with: -v
     error-->==
     error-->==
     error-->== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
     error-->== malloc/free: in use at exit: 50 bytes in 2 blocks.
     error-->== malloc/free: 656 allocs, 654 frees, 37979 bytes allocated.
     error-->== For counts of detected errors, rerun with: -v
     error-->== searching for pointers to 2 not-freed blocks.
     error-->== checked 5678248 bytes.
     error-->==
     error-->== 18 bytes in 1 blocks are possibly lost in loss record 1 of 2
     error-->==    at 0x4002F226: operator new(unsigned) (vg_replace_malloc.c:162)
     error-->==    by 0x402C5C78: std::__default_alloc_template<true, 0>::allocate(unsigned) (in /usr/lib/libstdc++.so.5.0.5)
     error-->==    by 0x402CB567: std::string::_Rep::_S_create(unsigned, std::allocator<char> const&) (in /usr/lib/libstdc++.so.5.0.5)
     error-->==    by 0x402CC2BF: (within /usr/lib/libstdc++.so.5.0.5)
     error-->==    by 0x402C8AB8: std::string::string(char const*, std::allocator<char> const&) (in /usr/lib/libstdc++.so.5.0.5)
     error-->==    by 0x8060071: parse::tasks::parse() (tasks.cc:30)
     error-->==    by 0x80F8F67: FunctionTask::execute() const (function-task.cc:18)
     error-->==    by 0x80FA728: TaskRegister::execute() (task-register.cc:274)
     error-->==    by 0x804B307: main (tc.cc:27)
     error-->==
     error-->==
     error-->== 32 bytes in 1 blocks are still reachable in loss record 2 of 2
     error-->==    at 0x4002F226: operator new(unsigned) (vg_replace_malloc.c:162)
     error-->==    by 0x80655C7: yy::Parser::parse() (parsetiger.yy:212)
     error-->==    by 0x806025F: parse::parse(std::string const&, bool, bool) (libparse.cc:18)
     error-->==    by 0x806007D: parse::tasks::parse() (tasks.cc:30)
     error-->==    by 0x80F8F67: FunctionTask::execute() const (function-task.cc:18)
     error-->==    by 0x80FA728: TaskRegister::execute() (task-register.cc:274)
     error-->==    by 0x804B307: main (tc.cc:27)
     error-->==
     error-->== LEAK SUMMARY:
     error-->==    definitely lost: 0 bytes in 0 blocks.
     error-->==    possibly lost:   18 bytes in 1 blocks.
     error-->==    still reachable: 32 bytes in 1 blocks.
     error-->==         suppressed: 0 bytes in 0 blocks.
     /* == Abstract Syntax Tree. == */
     0
     Example 154: v tc -A 0.tig
     $ v tc -AD 0.tig
     error-->== Memcheck, a memory error detector for x86-linux.
     error-->== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
     error-->== Using valgrind-2.1.0, a program supervision framework for x86-linux.
     error-->== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
     error-->== Estimated CPU clock rate is 1669 MHz
     error-->== For more details, rerun with: -v
     error-->==
     error-->==
     error-->== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
     error-->== malloc/free: in use at exit: 0 bytes in 0 blocks.
     error-->== malloc/free: 665 allocs, 665 frees, 38209 bytes allocated.
     error-->== For counts of detected errors, rerun with: -v
     error-->== No malloc'd blocks -- no leaks are possible.
     /* == Abstract Syntax Tree. == */
     0
     Example 155: v tc -AD 0.tig

Starting with GCC 3.4, GLIBCPP_FORCE_NEW is spelled GLIBCXX_FORCE_NEW.