Home » Testing and Debugging » How to use Valgrind to find memory leaks ?

How to use Valgrind to find memory leaks ?

Valgrind is an instrumentation framework for building dynamic analysis tools. There are Valgrind tools that can automatically detect many memory management and threading bugs, and profile your programs in detail. You can also use Valgrind to build new tools.

We will need to install valgrind for ubuntu,

$ sudo apt-get install valgrind

Create a test program which has some memory issues as,

$ vim valgrind_test.c 
#include <stdio.h>
#include <stdlib.h>

int main() {
    char *ptr = (char *) malloc(1024);
    char ch;
    /* Uninitialized read */
    ch = ptr[1024];
    /* Write beyond the block */
    ptr[1024] = 0;
    /* Orphan the block */
    ptr = 0;
    exit(0);
}

Now lets compile the program as,

$ gcc -o valgrind_test valgrind_test.c

Now run the program with valgrind to detect the memory leaks,

$ valgrind --leak-check=yes -v ./valgrind_test

==10092== Memcheck, a memory error detector
==10092== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==10092== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==10092== Command: ./valgrind_test
==10092==
--10092-- Valgrind options:
--10092-- --leak-check=yes
--10092-- -v
--10092-- Contents of /proc/version:
--10092-- Linux version 3.13.0-49-generic (buildd@kissel) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #83-Ubuntu SMP Fri Apr 10 20:14:51 UTC 2015
--10092-- Arch and hwcaps: X86, x86-mmxext-sse1-sse2
--10092-- Page sizes: currently 4096, max supported 4096
--10092-- Valgrind library directory: /usr/lib/valgrind
--10092-- Reading syms from /lib/i386-linux-gnu/ld-2.19.so
--10092-- Considering /lib/i386-linux-gnu/ld-2.19.so ..
--10092-- .. CRC mismatch (computed 19686c0d wanted 131a893d)
--10092-- Considering /usr/lib/debug/lib/i386-linux-gnu/ld-2.19.so ..
--10092-- .. CRC is valid
--10092-- Reading syms from ~/Desktop/devlab/c/linux/valgrind_test
--10092-- Reading syms from /usr/lib/valgrind/memcheck-x86-linux
--10092-- Considering /usr/lib/valgrind/memcheck-x86-linux ..
--10092-- .. CRC mismatch (computed e09cad6a wanted c3463efc)
--10092-- object doesn't have a symbol table
--10092-- object doesn't have a dynamic symbol table
--10092-- Scheduler: using generic scheduler lock implementation.
--10092-- Reading suppressions file: /usr/lib/valgrind/default.supp
==10092== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-10092-by-user-on-???
==10092== embedded gdbserver: writing to /tmp/vgdb-pipe-to-vgdb-from-10092-by-user-on-???
==10092== embedded gdbserver: shared mem /tmp/vgdb-pipe-shared-mem-vgdb-10092-by-user-on-???
==10092==
==10092== TO CONTROL THIS PROCESS USING vgdb (which you probably
==10092== don't want to do, unless you know exactly what you're doing,
==10092== or are doing some strange experiment):
==10092== /usr/lib/valgrind/../../bin/vgdb --pid=10092 ...command...
==10092==
==10092== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==10092== /path/to/gdb ./valgrind_test
==10092== and then give GDB the following command
==10092== target remote | /usr/lib/valgrind/../../bin/vgdb --pid=10092
==10092== --pid is optional if only one valgrind process is running
==10092==
--10092-- REDIR: 0x4017ed0 (strlen) redirected to 0x38066872 (???)
--10092-- REDIR: 0x4017ce0 (index) redirected to 0x3806684d (???)
--10092-- Reading syms from /usr/lib/valgrind/vgpreload_core-x86-linux.so
--10092-- Considering /usr/lib/valgrind/vgpreload_core-x86-linux.so ..
--10092-- .. CRC mismatch (computed da218fa9 wanted d8f40358)
--10092-- object doesn't have a symbol table
--10092-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so
--10092-- Considering /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so ..
--10092-- .. CRC mismatch (computed f1cf8ee0 wanted 71765c70)
--10092-- object doesn't have a symbol table
==10092== WARNING: new redirection conflicts with existing -- ignoring it
--10092-- old: 0x04017ed0 (strlen ) R-> (0000.0) 0x38066872 ???
--10092-- new: 0x04017ed0 (strlen ) R-> (2007.0) 0x0402d480 strlen
--10092-- Reading syms from /lib/i386-linux-gnu/libc-2.19.so
--10092-- Considering /lib/i386-linux-gnu/libc-2.19.so ..
--10092-- .. CRC mismatch (computed da700b2f wanted 551922c7)
--10092-- Considering /usr/lib/debug/lib/i386-linux-gnu/libc-2.19.so ..
--10092-- .. CRC is valid
--10092-- REDIR: 0x40cade0 (strnlen) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--10092-- REDIR: 0x40ccd90 (strncasecmp) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--10092-- REDIR: 0x40d2710 (memrchr) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--10092-- REDIR: 0x40e5750 (wcslen) redirected to 0x4024580 (_vgnU_ifunc_wrapper)
--10092-- REDIR: 0x40caf90 (__GI_strrchr) redirected to 0x402ce50 (__GI_strrchr)
--10092-- REDIR: 0x40c66b0 (malloc) redirected to 0x402a110 (malloc)
==10092== Invalid read of size 1
==10092== at 0x804846A: main (in ~/Desktop/devlab/c/linux/valgrind_test)
==10092== Address 0x4200428 is 0 bytes after a block of size 1,024 alloc'd
==10092== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10092== by 0x8048461: main (in ~/Desktop/devlab/c/linux/valgrind_test)
==10092==
==10092== Invalid write of size 1
==10092== at 0x804847E: main (in ~/Desktop/devlab/c/linux/valgrind_test)
==10092== Address 0x4200428 is 0 bytes after a block of size 1,024 alloc'd
==10092== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10092== by 0x8048461: main (in ~/Desktop/devlab/c/linux/valgrind_test)
==10092==
--10092-- REDIR: 0x40c6c60 (free) redirected to 0x402b370 (free)
==10092==
==10092== HEAP SUMMARY:
==10092== in use at exit: 1,024 bytes in 1 blocks
==10092== total heap usage: 1 allocs, 0 frees, 1,024 bytes allocated
==10092==
==10092== Searching for pointers to 1 not-freed blocks
==10092== Checked 57,232 bytes
==10092==
==10092== 1,024 bytes in 1 blocks are definitely lost in loss record 1 of 1
==10092== at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==10092== by 0x8048461: main (in ~/Desktop/devlab/c/linux/valgrind_test)
==10092==
==10092== LEAK SUMMARY:
==10092== definitely lost: 1,024 bytes in 1 blocks
==10092== indirectly lost: 0 bytes in 0 blocks
==10092== possibly lost: 0 bytes in 0 blocks
==10092== still reachable: 0 bytes in 0 blocks
==10092== suppressed: 0 bytes in 0 blocks
==10092==

Leave a Comment