linux程序开发和测试:内存调试和性能分析工具Valgrind详细介绍
目录
一、概述
二、 主要功能
三、 安装 Valgrind
(一)在 Ubuntu 上安装 Valgrind
(二)在 CentOS 上安装 Valgrind
四、 使用 Valgrind
(一) 基本用法
(二) 选项
1. 常用选项
2. 内存泄漏检测
3. 详细报告
4. 性能分析
5. 多线程错误检测
(三)获取帮助
五、 示例
(一)、 示例程序
1、程序代码
2、编译该程序
(二) 使用 Valgrind 检测内存问题
1、运行 Valgrind 并检测内存问题
2、输出示例
六、 工具集
(一)常见工具
1、Memcheck
2、Callgrind
3、Cachegrind
4、Helgrind
5、Massif
(二) 示例:使用 Callgrind 进行性能分析
1. 运行 Callgrind
2. 生成可视化报告
七、 常见问题及解决方法
1. 性能影响
2. 错误报告过多
3. 内存泄漏报告不准确
一、概述
Valgrind是一套开放源代码(GPL V2)的仿真调试工具集合,由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),模拟了一个CPU环境,并提供服务给其他工具;而其他工具则类似于插件(plug-in),利用内核提供的服务完成各种特定的内存调试任务。
Valgrind 是一个强大的内存调试和性能分析工具,广泛用于 Linux 系统上的程序开发和测试。它可以帮助开发者检测内存泄漏、数组越界、未初始化变量等问题,并提供详细的报告。Valgrind 支持多种编程语言,尤其是 C 和 C++。
Valgrind可以帮助开发者检测和修复程序中的内存问题和性能瓶颈。通过合理使用 Valgrind 的各种工具和选项,可以显著提高程序的质量和性能。
二、 主要功能
主要功能包括:
1. 内存泄漏检测:检测程序中未释放的内存分配。
2. 数组越界检测:检测数组访问越界的情况。
3. 未初始化变量检测:检测使用未初始化的变量。
4. 多线程错误检测:检测线程同步问题,如数据竞争。
5. 性能分析:提供详细的性能分析报告,帮助优化程序。
三、 安装 Valgrind
(一)在 Ubuntu 上安装 Valgrind
使用如下命令:
sudo apt update
sudo apt install valgrind
实际操作如下:
root@quinn-ThinkPad-T430s:/studyLinux/performance# valgrind -h
找不到命令 “valgrind”,但可以通过以下软件包安装它:
snap install valgrind # version 3.22.0, or
apt install valgrind # version 1:3.18.1-1ubuntu2
输入 “snap info valgrind” 以查看更多版本。
root@quinn-ThinkPad-T430s:/studyLinux/performance# sudo apt update
获取:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB]
命中:2 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy InRelease
获取:3 http://security.ubuntu.com/ubuntu jammy-security/main amd64 DEP-11 Metadata [43.2 kB]
获取:4 http://security.ubuntu.com/ubuntu jammy-security/restricted amd64 DEP-11 Metadata [208 B]
获取:5 http://security.ubuntu.com/ubuntu jammy-security/universe amd64 DEP-11 Metadata [125 kB]
获取:6 http://security.ubuntu.com/ubuntu jammy-security/multiverse amd64 DEP-11 Metadata [208 B]
获取:7 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-updates InRelease [128 kB]
获取:8 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-updates/main amd64 DEP-11 Metadata [103 kB]
获取:9 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-updates/restricted amd64 DEP-11 Metadata [212 B]
获取:10 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-updates/universe amd64 DEP-11 Metadata [356 kB]
获取:11 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-updates/multiverse amd64 DEP-11 Metadata [940 B]
获取:12 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-backports InRelease [127 kB]
获取:13 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-backports/main amd64 DEP-11 Metadata [5,344 B]
获取:14 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-backports/restricted amd64 DEP-11 Metadata [212 B]
获取:15 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-backports/universe amd64 DEP-11 Metadata [23.1 kB]
获取:16 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-backports/multiverse amd64 DEP-11 Metadata [212 B]
已下载 1,042 kB,耗时 23秒 (45.5 kB/s)
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
有 197 个软件包可以升级。请执行 ‘apt list --upgradable’ 来查看它们。
root@quinn-ThinkPad-T430s:/studyLinux/performance#
root@quinn-ThinkPad-T430s:/studyLinux/performance# sudo apt install valgrind
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
将会同时安装下列软件:
libc6-i386
建议安装:
valgrind-dbg valgrind-mpi kcachegrind alleyoop valkyrie
下列【新】软件包将被安装:
libc6-i386 valgrind
升级了 0 个软件包,新安装了 2 个软件包,要卸载 0 个软件包,有 197 个软件包未被升级。
需要下载 16.9 MB 的归档。
解压缩后会消耗 91.8 MB 的额外空间。
您希望继续执行吗? [Y/n] y
获取:1 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-updates/main amd64 libc6-i386 amd64 2.35-0ubuntu3.8 [2,838 kB]
获取:2 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/main amd64 valgrind amd64 1:3.18.1-1ubuntu2 [14.1 MB]
已下载 16.9 MB,耗时 10秒 (1,639 kB/s)
正在选中未选择的软件包 libc6-i386。
(正在读取数据库 ... 系统当前共安装有 216991 个文件和目录。)
准备解压 .../libc6-i386_2.35-0ubuntu3.8_amd64.deb ...
正在解压 libc6-i386 (2.35-0ubuntu3.8) ...
正在选中未选择的软件包 valgrind。
准备解压 .../valgrind_1%3a3.18.1-1ubuntu2_amd64.deb ...
正在解压 valgrind (1:3.18.1-1ubuntu2) ...
正在设置 libc6-i386 (2.35-0ubuntu3.8) ...
正在设置 valgrind (1:3.18.1-1ubuntu2) ...
正在处理用于 man-db (2.10.2-1) 的触发器 ...
正在处理用于 libc-bin (2.35-0ubuntu3.8) 的触发器 ...
root@quinn-ThinkPad-T430s:/studyLinux/performance# valgrind -h
usage: valgrind [options] prog-and-args
tool-selection option, with default in [ ]:
--tool= use the Valgrind tool named [memcheck]
basic user options for all Valgrind tools, with defaults in [ ]:
(二)在 CentOS 上安装 Valgrind
使用如下命令:
sudo yum install valgrind
四、 使用 Valgrind
(一) 基本用法
Valgrind 的基本用法是:
valgrind [valgrind-options] ./your-program [program-options]
其中,[valgrind-options]表示Valgrind的选项。
(二) 选项
1. 常用选项
包括:
- --tool=tool_name:指定要使用的Valgrind工具,如Memcheck、Callgrind等。
- --leak-check=full:在程序退出时检查内存泄漏,并显示所有的内存泄漏信息。
- --track-origins=yes:跟踪未初始化变量的来源。
- --log-file=<文件>:将Valgrind输出的信息保存至文件中。
2. 内存泄漏检测
使用如下命令:
valgrind --leak-check=yes ./your-program
3. 详细报告
使用如下命令:
valgrind --leak-check=full --show-leak-kinds=all ./your-program
4. 性能分析
使用如下命令:
valgrind --tool=callgrind ./your-program
5. 多线程错误检测
使用如下命令:
valgrind --tool=helgrind ./your-program
(三)获取帮助
可以通过如下命令获取帮助:
valgrind -h
实际操作如下:

五、 示例
(一)、 示例程序
1、程序代码
假设我们有一个简单的 C 程序 example.c:
include
int main() {
int ptr = malloc(10 sizeof(int));
ptr[10] = 0; // 数组越界
free(ptr);
return 0;
}
2、编译该程序
gcc -o example example.c
(二) 使用 Valgrind 检测内存问题
1、运行 Valgrind 并检测内存问题
valgrind --leak-check=full --show-leak-kinds=all ./example
2、输出示例
==12345== Memcheck, a memory error detector
==12345== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12345== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==12345== Command: ./example
==12345==
==12345== Invalid write of size 4
==12345== at 0x4005B4: main (example.c:6)
==12345== Address 0x5204040 is 0 bytes after a block of size 40 alloc'd
==12345== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12345== by 0x40059B: main (example.c:5)
==12345==
==12345==
==12345== HEAP SUMMARY:
==12345== in use at exit: 0 bytes in 0 blocks
==12345== total heap usage: 1 allocs, 1 frees, 40 bytes allocated
==12345==
==12345== All heap blocks were freed -- no leaks are possible
==12345==
==12345== For lists of detected and suppressed errors, rerun with: -s
==12345== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
六、 工具集
(一)常见工具
Valgrind工具集中包含了多个实用的工具,每个工具都有其特定的功能:
1、Memcheck
内存错误检测器,能够发现开发中绝大多数内存错误使用情况,比如使用未初始化的内存、使用已经释放了的内存、内存访问越界等。它还可以分析热点函数和函数调用流程,帮助优化程序性能。
2、Callgrind
用于分析程序的函数调用关系,收集程序运行时的一些数据,建立函数调用关系图。它还可以有选择地进行cache模拟,并在运行结束时将分析数据写入一个文件。
3、Cachegrind
分析程序的缓存使用情况和缓存命中率,通过模拟处理器缓存的访问情况来统计程序的缓存行使用情况、缓存命中率和缓存失效次数等信息。
4、Helgrind
线程错误检测器,用于检查多线程程序中出现的竞争问题。它寻找内存中被多个线程访问而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,容易导致难以发现的错误。
5、Massif
堆栈分析器,主要用来检查程序中堆栈使用中出现的问题。它能测量程序在堆栈中使用了多少内存,帮助开发者了解块寿命、块利用率和布局效率低下的问题。
此外,Valgrind还提供了其他工具,如DHAT(用于检测堆内存分配和使用情况)等,以满足不同开发者的需求。
(二) 示例:使用 Callgrind 进行性能分析
1. 运行 Callgrind
valgrind --tool=callgrind ./your-program
2. 生成可视化报告
使用 kcachegrind 工具查看生成的性能报告:
kcachegrind callgrind.out.
七、 常见问题及解决方法
1. 性能影响
Valgrind 会使程序运行变慢,通常比原生运行慢几倍到几十倍。因此,建议在开发和测试阶段使用 Valgrind,而不是在生产环境中。
2. 错误报告过多
如果程序中有大量的第三方库或系统库,可能会产生很多错误报告。可以使用 --gen-suppressions=all 选项生成抑制文件,然后在后续运行中使用 --suppressions=
3. 内存泄漏报告不准确
确保程序在退出前释放所有分配的内存。如果某些内存是故意不释放的(如全局静态变量),可以使用抑制文件来忽略这些报告。
文章正下方可以看到我的联系方式:鼠标“点击” 下面的 “威迪斯特-就是video system 微信名片”字样,就会出现我的二维码,欢迎沟通探讨。