(Fedora Core 5 was used while issuing the commands listed in this post)
Valgrind is an award-winning suite of tools for debugging and profiling Linux programs. With the tools that come with Valgrind, you can automatically detect many memory management and threading bugs, avoiding hours of frustrating bug-hunting, making your programs more stable.
The Valgrind distribution currently includes three tools: a memory error detector, a cache (time) profiler and a heap (space) profiler. It runs on the following platforms: x86/Linux, AMD64/Linux, PPC32/Linux.
Valgrind's Tool Suite
The Valgrind distribution includes four useful debugging and profiling tools:
- Memcheck
- Cachegrind
- Massif
- Helgrind
Memcheck
Memcheck can detect if your program:
- Accesses memory it shouldn't (areas not yet allocated, areas that have been freed, areas past the end of heap blocks, inaccessible areas of the stack)
- Uses uninitialised values in dangerous ways.
- Leaks memory.
- Does bad frees of heap blocks (double frees, mismatched frees).
- Passes overlapping source and destination memory blocks to memcpy() and related functions.
Memcheck reports these errors as soon as they occur, giving the source line number at which it occurred, and also a stack trace of the functions called to reach that line.
Cachegrind
Cachegrind is a cache profiler. It performs detailed simulation of the I1, D1 and L2 caches in your CPU and so can accurately pinpoint the sources of cache misses in your code. It identifies the number of cache misses, memory references and instructions executed for each line of source code, with per-function, per-module and whole-program summaries.
Massif
Massif is a heap profiler. It performs detailed heap profiling by taking regular snapshots of a program's heap. It produces a graph showing heap usage over time, including information about which parts of the program are responsible for the most memory allocations.
Helgrind
Helgrind is a thread debugger which finds data races in multithreaded programs. It looks for memory locations which are accessed by more than one (POSIX p-)thread, but for which no consistently used (pthread_mutex_) lock can be found. Such locations are indicative of missing synchronisation between threads, and could cause hard-to-find timing-dependent problems. It is useful for any program that uses pthreads.
It is a somewhat experimental tool, so your feedback is especially welcome here.
So, just to see how this works, I wrote one of the smallest programs I have written:
int main () {
int *n, *p;
printf ("Before allocating first time\n");
n = (int*) malloc(4*sizeof(int));
printf ("After allocating first time\n");
p = (int*) malloc(4*sizeof(int));
printf ("After allocating final time\n");
}
and compiled it and ran with valgrind:
bash-3.1$ gcc Test.c
bash-3.1$ valgrind -v --leak-check=yes --show-reachable=yes ./a.out
...
--3119-- Arch and subarch: X86, x86-sse2
...
--3119-- REDIR: 0x8F0360 (rindex) redirected to 0x4005D60 (rindex)
--3119-- REDIR: 0x869820 (_dl_sysinfo_int80) redirected to 0xB002129F (???)
Before allocating first time
--3119-- REDIR: 0x8EBC08 (malloc) redirected to 0x4005177 (malloc)
After allocating first time
After allocating final time
--3119-- REDIR: 0x8ED3A4 (free) redirected to 0x4004DBF (free)
--3119-- REDIR: 0x8F11E0 (memset) redirected to 0x40061C0 (memset)
==3119==
==3119== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 1)
--3119--
--3119-- supp: 12 Fedora-Core-5-hack2
==3119== malloc/free: in use at exit: 32 bytes in 2 blocks.
==3119== malloc/free: 2 allocs, 0 frees, 32 bytes allocated.
==3119==
==3119== searching for pointers to 2 not-freed blocks.
==3119== checked 46,664 bytes.
==3119==
==3119== 16 bytes in 1 blocks are definitely lost in loss record 1 of 2
==3119== at 0x40051F9: malloc (vg_replace_malloc.c:149)
==3119== by 0x80483F7: main (in /home/kvarun/a.out)
==3119== 16 bytes in 1 blocks are definitely lost in loss record 2 of 2
==3119== at 0x40051F9: malloc (vg_replace_malloc.c:149)
==3119== by 0x80483DC: main (in /home/kvarun/a.out)
==3119==
==3119== LEAK SUMMARY:
==3119== definitely lost: 32 bytes in 2 blocks.
==3119== possibly lost: 0 bytes in 0 blocks.
==3119== still reachable: 0 bytes in 0 blocks.
==3119== suppressed: 0 bytes in 0 blocks.
...
Then, I compiled the program with -g flag on to give valgrind some more valuable information:
bash-3.1$ gcc Test.c -g
bash-3.1$ valgrind -v --leak-check=yes --show-reachable=yes ./a.out
...
--3180-- Arch and subarch: X86, x86-sse2
...
--3180-- REDIR: 0x8F0360 (rindex) redirected to 0x4005D60 (rindex)
--3180-- REDIR: 0x869820 (_dl_sysinfo_int80) redirected to 0xB002129F (???)
Before allocating first time
--3180-- REDIR: 0x8EBC08 (malloc) redirected to 0x4005177 (malloc)
After allocating first time
After allocating final time
--3180-- REDIR: 0x8ED3A4 (free) redirected to 0x4004DBF (free)
--3180-- REDIR: 0x8F11E0 (memset) redirected to 0x40061C0 (memset)
==3180==
==3180== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 1)
--3180--
--3180-- supp: 12 Fedora-Core-5-hack2
==3180== malloc/free: in use at exit: 32 bytes in 2 blocks.
==3180== malloc/free: 2 allocs, 0 frees, 32 bytes allocated.
==3180==
==3180== searching for pointers to 2 not-freed blocks.
==3180== checked 46,664 bytes.
==3180==
==3180== 16 bytes in 1 blocks are definitely lost in loss record 1 of 2
==3180== at 0x40051F9: malloc (vg_replace_malloc.c:149)
==3180== by 0x80483F7: main (Test.c:8)
==3180== 16 bytes in 1 blocks are definitely lost in loss record 2 of 2
==3180== at 0x40051F9: malloc (vg_replace_malloc.c:149)
==3180== by 0x80483DC: main (Test.c:6)
==3180==
==3180== LEAK SUMMARY:
==3180== definitely lost: 32 bytes in 2 blocks.
==3180== possibly lost: 0 bytes in 0 blocks.
==3180== still reachable: 0 bytes in 0 blocks.
==3180== suppressed: 0 bytes in 0 blocks.
...
A nice tool, it seems, it is. If anyone uses it and finds it useful, please let Ciju or me know, we'll put it here with acknowledgement. Thanks to
Mausoom and
Surendra for telling me about this interesting and useful tool.
Labels: _ALL_, Linux, screen