I've previously mentionned Valgrind in a post I wrote in 2010. I'm still as much a fan of Valgrind now as I was then. In each of my development VMs, I normally have a simple shell script to start Valgrind with all of the command-line parms I want. Having a script prevents me having to look it up in the documentation every time.

The script

The script is written so I don't have to try and remember all the possible Valgrind command-line arguments. The parameters typically used to hunt memory issues are listed individually, making it easy to add new ones or comment out as necessary.

#!/bin/bash # stephanecharette@gmail.com # http://charette.no-ip.com:81/programming/2013-12-01_Valgrind/ # last updated 2014-09-18 log_filename=valgrind_output_$$.txt # setup the parms we want to use with valgrind; easy to comment out or modify tool="memcheck" # look for memory leaks, overwrites, etc. #tool="massif" # heap profiler #tool="exp-dhat" # experimental dynamic heap analysis #tool="exp-sgcheck" # experimental basic block vector generation parms="" parms="${parms} --tool=${tool}" # set to memcheck, massif, etc. parms="${parms} --db-attach=no" # set to "yes" to start gdb when an error is found (also see vgdb) parms="${parms} --demangle=yes" # demangle C++ names parms="${parms} --fullpath-after=$HOME" # strip /home/USERNAME from filenames parms="${parms} --gen-suppressions=no" # yes|no|all parms="${parms} --log-file=${log_filename}" parms="${parms} --num-callers=30" # number of entries to save from the call stack parms="${parms} --read-var-info=yes" # more precise error messages (but valgrind runs slower) parms="${parms} --show-below-main=no" # show stack traces before main() parms="${parms} --time-stamp=yes" # include a timestamp in the log parms="${parms} --trace-children=no" # valgrind into children processes as well parms="${parms} --track-fds=yes" # track open file/socket handles #parms="${parms} --verbose" # be extremely verbose when generating output parms="${parms} --vgdb=no" # gdb functionality (incurs significant performance overhead) parms="${parms} --xml=no" # should Valgrind output be in XML format # tool-specific options: if [ "${tool}" = "memcheck" ]; then parms="${parms} --free-fill=88" # fill freed blocks with the specified value parms="${parms} --keep-stacktraces=alloc-and-free" # what stack traces to keep with heach memory allocation parms="${parms} --leak-check=full" # display details of each memory leak parms="${parms} --leak-resolution=high" # all names on call stack must match #parms="${parms} --leak-resolution=low" # most recent 2 names on call stack must match parms="${parms} --malloc-fill=ff" # fill allocated blocks with the specified value parms="${parms} --show-leak-kinds=all" # comma-delimited list: "all,definite,indirect,possible,reachable" #parms="${parms} --show-mismatched-frees=yes" # looks for delete/free and delete[] errors #parms="${parms} --show-possibly-lost=yes" # replaced with show-leak-kinds #parms="${parms} --show-reachable=yes" # replaced with show-leak-kinds parms="${parms} --track-origins=yes" # track where memory was allocated fi if [ "${tool}" = "exp-dhat" ]; then parms="${parms} --show-top-n=100" # number of entries to show fi # see if we have a custom .supp file in the same place as this script supp_filename=$(dirname $0)/valgrind.supp if [ -e ${supp_filename} ]; then parms="${parms} --suppressions=${supp_filename}" fi # include the default valgrind suppression files if we can find them if [ -f /usr/lib/valgrind/default.supp ]; then for name in /usr/lib/valgrind/*.supp ; do parms="${parms} --suppressions=${name}" done fi cmd="valgrind ${parms} $@" echo "Starting: ${cmd}" echo "" ${cmd} if [ -e ${log_filename} ]; then more ${log_filename} echo "Log saved to ${log_filename}" fi if [ "${tool}" = "massif" ]; then echo "" echo "This should have generated a massif.out.* file." echo "Run \"ms_print massif.out.X\" to generate the heap profilling information." fi

Suppression files

The default Valgrind suppression files are automatically loaded from /usr/lib/valgrind/*.supp if they exist.

In addition, if you create a file named valgrind.supp in the same directory as v.sh, it also will be loaded as a suppression file. The valgrind.supp I use is the following:

{ openssl_1 Memcheck:Leak ... fun:_Z41__static_initialization_and_destruction_0ii } { openssl_2 Memcheck:Leak ... fun:SSL_library_init } { openssl_3 Memcheck:Leak ... fun:SSL_load_error_strings }
Last modified: 2015-03-01
Stéphane Charette, stephanecharette@gmail.com