CMake 笔记 | [21] 利用Valgrind来检测内存缺陷

注意
本文最后更新于 2024-01-31,文中内容可能已过时。

一、导言

导言
*目前,内存缺陷:写入或读取越界,或者内存泄漏(已分配但从未释放的内存),会生产难以跟踪的*bug*,最好尽早将它们检查出来。**Valgrind*是一个通用的工具,用来检测内存缺陷和内存泄漏。本篇将在使用*CMake/CTest*测试时使用*Valgrind*对内存问题进行警告。

二、Valgrind安装

  • 下载Valgrind

    1
    
    wget  https://sourceware.org/pub/valgrind/valgrind-3.21.0.tar.bz2
  • 解压

    1
    2
    
    tar -xjvf valgrind-3.15.0.tar.bz2
    cd valgrind-3.21.0
  • 配置

    1
    
    ./configure
  • 编译

    1
    
    make
  • 安装

    1
    
    sudo make install

三、项目结构

1
2
3
4
5
.
├── CMakeLists.txt
├── leaky_implementation.cpp
├── leaky_implementation.h
└── test.cpp

项目结构:

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

CMakeLists.txt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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>
)
引用
1
find_program(MEMORYCHECK_COMMAND NAMES valgrind)

查找valgrind,并将MEMORYCHECK_COMMAND设置为其绝对路径。

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

将相关参数传递给Valgrind。内存检查会创建一个日志文件,该文件可用于详细记录内存缺陷信息。

相关源码

leaky_implementation.h

1
2
3
4
5
#ifndef LEAKY_IMPLEMENTATION_H
#define LEAKY_IMPLEMENTATION_H

int DoSomeWork();
#endif // !LEAKY_IMPLEMENTATION_H

leaky_implementation.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#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

1
2
3
4
5
6
7
#include "leaky_implementation.h"

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

  return ret;
}
输出结果
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
   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
Buy me a coffee~
支付宝
微信
0%