Using Valgrind to Detect Memory Defects with CMake

Using Valgrind to Detect Memory Defects with CMakeUsing Valgrind to Detect Memory Defects with CMake

Introduction:

Currently, memory defects such as out-of-bounds writes or reads, or memory leaks (memory that has been allocated but never freed) can produce hard-to-track bugs, so it’s best to check them as early as possible. Valgrind is a general-purpose tool for detecting memory defects and memory leaks. This article will use Valgrind to warn about memory issues during CMake/CTest testing.

Using Valgrind to Detect Memory Defects with CMake

Installing Valgrind

  • Download Valgrind

    wget  https://sourceware.org/pub/valgrind/valgrind-3.21.0.tar.bz2
    
  • Extract

    tar -xjvf valgrind-3.15.0.tar.bz2
    cd valgrind-3.21.0
    
  • Configure

    ./configure
    
  • Compile

    make
    
  • Install

    sudo make install

Project Structure

.
├── CMakeLists.txt
├── leaky_implementation.cpp
├── leaky_implementation.h
└── test.cpp

Project Structure:

https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter4/04

CMakeLists.txt

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

project(test_leaky LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_library(example_library leaky_implementation.cpp)

add_executable(cpp_test test.cpp)
target_link_libraries(cpp_test example_library)

find_program(MEMORYCHECK_COMMAND NAMES valgrind)

set(MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full")
# add memcheck test action

include(CTest)

enable_testing()

add_test(
  NAME cpp_test
  COMMAND $<TARGET_FILE:cpp_test>
)
find_program(MEMORYCHECK_COMMAND NAMES valgrind)

Find valgrind and set MEMORYCHECK_COMMAND to its absolute path.

set(MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full")

Pass relevant parameters to Valgrind. Memory checking will create a log file that can be used to detail memory defect information.

Related Source Code

leaky_implementation.h

#ifndef LEAKY_IMPLEMENTATION_H
#define LEAKY_IMPLEMENTATION_H

int DoSomeWork();
#endif // !LEAKY_IMPLEMENTATION_H

leaky_implementation.cpp

#include "leaky_implementation.h"

int DoSomeWork() {
  // we allocate an array
  double *default_array = new double[1000];
  // do some work
  // ...
  // we forget to deallocate it
  // delete[] default_array;
  return 0;
}

test.cpp

#include "leaky_implementation.h"

int main() {
  int ret = DoSomeWork();
  
  return ret;
}

Output Results

   Site: jiangli-virtual-machine
   Build name: Linux-g++
Memory check project /home/jiangli/repo/tutorials/cmake-tutorial/chapter4/04/build
    Start 1: cpp_test
1/1 MemCheck #1: cpp_test .........................   Passed    1.03 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   1.03 sec
-- Processing memory checking output:
1/1 MemCheck: #1: cpp_test .........................   Defects: 1
MemCheck log files can be found here: ( * corresponds to test number)
/home/jiangli/repo/tutorials/cmake-tutorial/chapter4/04/build/Testing/Temporary/MemoryChecker.*.log
Memory checking results:
Memory Leak - 1

Finally, I wish everyone to become stronger!!!

Using Valgrind to Detect Memory Defects with CMakeUsing Valgrind to Detect Memory Defects with CMake

Leave a Comment