A good programmer has a variety of tools to help him in developing good applications. We talked about gdb in an article at the beginning of April. Now, it is time for a crash introduction to Valgrind.

This program is a collection of different tools. For example, it offers a heap profiler, a thread error detector or a cache profiler. However, the tool which gave Valgrind’s fame is Memcheck, a memory error detector. Because of its popularity, this tool is the default one (to use other Valgrind tools you have to use the --tool=option command line argument). In this article, we will concentrate on Memcheck only.

Detecting memory leaks Mainly, one would use Valgrind to detect memory leaks in his application. By this, we mean memory which was allocated but wasn’t released back. For example, take this program: void f() f() { int *a = calloc( 1024 , sizeof (a[ 0 ])); *a = calloc((a[])); } int main() main() { int i; i; for (i = 0 ; i < 1024 ; i++) (i =; i f(); return 0 ; } This program allocates sizeof(int) MB of memory and doesn’t free them. Of course, at the end of the execution, the operating systems takes care of releasing this memory. However, suppose that the f function was instead called from a server executable which shouldn’t be stopped. In this case, each invocation of f will eat away sizeof(int) KB memory (depending on architecture, 4KB or 8KB). The example is simple, the problem could be observed with naked eyes. However, let’s see what Valgrind tells us: ==11418== Memcheck, a memory error detector ==11418== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. ==11418== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info ==11418== Command: ./a.out ==11418== ==11418== ==11418== HEAP SUMMARY: ==11418== in use at exit: 4,194,304 bytes in 1,024 blocks ==11418== total heap usage: 1,024 allocs, 0 frees, 4,194,304 bytes allocated ==11418== ==11418== LEAK SUMMARY: ==11418== definitely lost: 4,194,304 bytes in 1,024 blocks ==11418== indirectly lost: 0 bytes in 0 blocks ==11418== possibly lost: 0 bytes in 0 blocks ==11418== still reachable: 0 bytes in 0 blocks ==11418== suppressed: 0 bytes in 0 blocks ==11418== Rerun with --leak-check=full to see details of leaked memory ==11418== ==11418== For counts of detected and suppressed errors, rerun with: -v ==11418== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 3 from 3) The number that gets repeated on each line of the output is the PID of our executable. At the end of the run, we are offered a heap summary (from where we can see that our program allocated 4MB of memory) and a leak summary. Let’s see what happens after we take into account the suggestion to run with --leak-check=full . First, we compile the program adding debugging information, using the -g GCC flag. And, then, we run the executable under Valgrind: mihai@keldon:/tmp/mm/valgrind$ valgrind --leak-check=full ./a.out ==11527== Memcheck, a memory error detector ==11527== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. ==11527== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info ==11527== Command: ./a.out ==11527== ==11527== ==11527== HEAP SUMMARY: ==11527== in use at exit: 4,194,304 bytes in 1,024 blocks ==11527== total heap usage: 1,024 allocs, 0 frees, 4,194,304 bytes allocated ==11527== ==11527== 4,194,304 bytes in 1,024 blocks are definitely lost in loss record 1 of 1 ==11527== at 0x4C29024: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==11527== by 0x4004F2: f (1.c:6) ==11527== by 0x400513: main (1.c:14) ==11527== ==11527== LEAK SUMMARY: ==11527== definitely lost: 4,194,304 bytes in 1,024 blocks ==11527== indirectly lost: 0 bytes in 0 blocks ==11527== possibly lost: 0 bytes in 0 blocks ==11527== still reachable: 0 bytes in 0 blocks ==11527== suppressed: 0 bytes in 0 blocks ==11527== ==11527== For counts of detected and suppressed errors, rerun with: -v ==11527== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 3 from 3) This time, we see that the memory was allocated in line 6 in function f . This allows us to insert the needed free at the correct spot. Quick question: what would have happened if our program was compiled with optimizations on (try -O3 for example)?

Wrong cases of memory release What happens when we free the same memory address twice? Let’s use this program: void *f() *f() { int *a = calloc( 16 , sizeof (a[ 0 ])); *a = calloc((a[])); free(a); return a; a; } int main() main() { int *a = f(); *a = f(); free(a); return 0 ; } Running it with Valgrind yields: mihai@keldon:/tmp/mm/valgrind$ valgrind ./a.out ==11734== Memcheck, a memory error detector ==11734== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. ==11734== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info ==11734== Command: ./a.out ==11734== ==11734== Invalid free() / delete / delete[] / realloc() ==11734== at 0x4C29A9E: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==11734== by 0x40057A: main (1.c:14) ==11734== Address 0x51d2040 is 0 bytes inside a block of size 64 free'd ==11734== at 0x4C29A9E: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==11734== by 0x400552: f (1.c:7) ==11734== by 0x40056A: main (1.c:13) ==11734== ==11734== ==11734== HEAP SUMMARY: ==11734== in use at exit: 0 bytes in 0 blocks ==11734== total heap usage: 1 allocs, 2 frees, 64 bytes allocated ==11734== ==11734== All heap blocks were freed -- no leaks are possible ==11734== ==11734== For counts of detected and suppressed errors, rerun with: -v ==11734== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 3 from 3) We can see both locations where the memory was released. Now, consider this C++ code, a tweaked version of the above: int *f() *f() { int *a = ( int *)calloc( 16 , sizeof (a[ 0 ])); *a = (*)calloc((a[])); return a; a; } int main() main() { int *a = f(); *a = f(); delete a; a; return 0 ; } Running under Valgrind, we receive the following output (we will use -q to show only the errors reported by Valgrind – no header and no statistics at the end): mihai@keldon:/tmp/mm/valgrind$ valgrind -q ./a.out ==11757== Mismatched free() / delete / delete [] ==11757== at 0x4C2972C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==11757== by 0x400659: main (1.c:13) ==11757== Address 0x59e0040 is 0 bytes inside a block of size 64 alloc'd ==11757== at 0x4C29024: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==11757== by 0x400632: f() (1.c:6) ==11757== by 0x400649: main (1.c:12) Before finishing this section, let’s consider the case of freeing from inside an allocated block. See this code: void *f() *f() { int *a = calloc( 16 , sizeof (a[ 0 ])); *a = calloc((a[])); return a + 4 ; a + } int main() main() { int *a = f(); *a = f(); free(a); return 0 ; } Valgrind gives the following output: mihai@keldon:/tmp/mm/valgrind$ valgrind -q ./a.out ==11765== Invalid free() / delete / delete[] / realloc() ==11765== at 0x4C29A9E: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==11765== by 0x400572: main (1.c:13) ==11765== Address 0x51d2050 is 16 bytes inside a block of size 64 alloc'd ==11765== at 0x4C29024: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==11765== by 0x400542: f (1.c:6) ==11765== by 0x400562: main (1.c:12) From this we can easily see that we tried to free from inside an allocated block instead of using the block’s address. Moreover, we find where the block was allocated and we can fix our program now.