Valgrind内存调试和性能分析工具使用教程

Valgrind 是一款 内存调试和性能分析工具,主要功能:

  1. 内存泄漏检测
    • 检测程序中的内存泄漏,即分配的内存没有被正确释放。
  2. 内存错误检测
    • 检测 未初始化的内存读取越界访问释放后访问 等内存错误。
  3. 线程错误检测
    • 检测线程中的 数据竞争 和其他线程错误。
  4. 性能分析
    • 缓存使用分析程序的性能瓶颈,帮助开发者优化程序。
  5. 堆栈溢出检测
    • 检测栈的 溢出 或访问未分配的内存区域。

1. 安装 Valgrind

sudo apt update
sudo apt install valgrind -y

2. 编译程序

假设有一个 C 程序 test.c

#include <stdio.h>
#include <stdlib.h>

void leak_memory() {
    int *p = (int *)malloc(10 * sizeof(int)); // 分配了内存但未释放
}

int main() {
    leak_memory();
    printf("Hello, Valgrind!\n");
    return 0;
}

编译时添加调试信息 -g

gcc -g test.c -o test

CMake项目编译时添加调试信息的方法

  1. 在CMakeLists.txt中添加 set(CMAKE_BUILD_TYPE debug)
  2. 构建项目时添加 -DCMAKE_BUILD_TYPE=Debug
  • 直接在CMakeLists.txt文件中添加add_compile_options(-g)

使用 Valgrind 检测内存问题:

valgrind --leak-check=full --show-leak-kinds=all ./test

输出示例:

==12345== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12345==    at 0x4C2DB8F: malloc (vg_replace_malloc.c:299)
==12345==    by 0x4005E7: leak_memory (test.c:5)
==12345==    by 0x4005F5: main (test.c:10)

分析:

  • definitely lost 说明内存泄漏。

  • test.c:5 指示问题代码行。

Valgrind 常用参数

  • --leak-check=yes / --leak-check=full:开启内存泄漏检查,full 提供更详细的报告。

  • --track-origins=yes:跟踪未初始化内存的来源。帮助查找未初始化的内存访问来源。

  • --show-leak-kinds=all:显示所有类型的内存泄漏。

  • --max-stackframe=128:显示堆栈溢出的信息,限制栈帧的大小。

  • --verbose:显示更多的调试信息。

使用 Valgrind 的基本步骤

  1. 编译程序
  • 在使用 Valgrind 分析程序之前,确保程序是 以调试模式 编译的(开启调试符号)。可以通过以下编译选项来启用:
g++ -g -o your_program your_program.cpp
  1. 运行程序并进行分析
    使用 Valgrind 跟踪和分析你的程序,以下是一个简单的例子:
valgrind --leak-check=full --track-origins=yes ./your_program
  • 这将会检测程序的 内存泄漏,并显示每个未初始化内存访问的来源。
  1. 查看报告
  • Valgrind 会在终端输出分析报告,你可以根据这些信息来定位内存问题。
  1. 修复问题
  • 根据 Valgrind 的报告,找到代码中的问题(比如内存泄漏、越界访问等),并修复它们。

示例:使用 Memcheck 查找内存泄漏

valgrind --leak-check=full --show-leak-kinds=all ./your_program 2> valgrind_log.txt

输出示例:

==12345== Memcheck, a memory error detector
==12345== Command: ./your_program
==12345==
==12345== 1 bytes in 1 blocks are definitely lost in loss record 1 of 2
==12345==    at 0x4C29A4A: malloc (vg_replace_malloc.c:309)
==12345==    by 0x4E6E9D9: main (your_program.cpp:10)
==12345==
==12345== LEAK SUMMARY:
==12345==    definitely lost: 1 byte in 1 block
==12345==    indirectly lost: 0 bytes in 0 blocks
==12345==    possibly lost: 0 bytes in 0 blocks
==12345==    still reachable: 0 bytes in 0 blocks
==12345==    suppressed: 0 bytes in 0 blocks

该报告指出程序在 main 函数中有 1 字节的内存泄漏,并给出了泄漏的调用堆栈信息。


posted @ 2025-03-28 16:32  江海余生  阅读(162)  评论(0)    收藏  举报