Linux下几款C++程序中的内存泄露检查工具
2016-07-19 21:56
1551 查看
Linux下编写C或者C++程序,有很多工具,但是主要编译器仍然是gcc和g++。最近用到STL中的List编程,为了检测写的代码是否会发现内存泄漏,了解了一下相关的知识。
所有使用动态内存分配(dynamic memory allocation)的程序都有机会遇上内存泄露(memory leakage)问题,在Linux里有三种常用工具来检测内存泄露的情況,包括:
参见 http://elinux.org/Memory_Debuggers
Memcheck。这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。这也是本文将重点介绍的部分。
Callgrind。它主要用来检查程序中函数调用过程中出现的问题。
Cachegrind。它主要用来检查程序中缓存使用出现的问题。
Helgrind。它主要用来检查多线程程序中出现的竞争问题。
Massif。它主要用来检查程序中堆栈使用中出现的问题。
Extension。可以利用core提供的功能,自己编写特定的内存调试工具
参照
Valgrind简单用法
Unix下C程序内存泄漏检测工具Valgrind安装与使用
valgrind 的使用简介
应用 Valgrind 发现 Linux 程序的内存问题
如何使用Valgrind memcheck工具进行C/C++的内存泄漏检测
到下载地址)下载最新版的valgrind,按照里面的README提示,安装后就可以使用这个工具来检测内存泄露和内存越界等
当然也可以使用发行版的自带的源中安装
这是一个没有界面的内存检测工具,安装后,输入 valgrind ls -l 验证一下该工具是否工作正常(这是README里面的方法,实际上是验证一下对ls -l命令的内存检测),如果你看到一堆的信息说明你的工具可以使用了。
Memcheck
最常用的工具,用来检测程序中出现的内存问题,所有对内存的读写都会被检测到,一切对malloc()/free()/new/delete的调用都会被捕获。所以,Memcheck 工具主要检查下面的程序错误
这些问题往往是C/C++程序员最头疼的问题,Memcheck在这里帮上了大忙。
Callgrind
和gprof类似的分析工具,但它对程序的运行观察更是入微,能给我们提供更多的信息。和gprof不同,它不需要在编译源代码时附加特殊选项,但加上调试选项是推荐的。Callgrind收集程序运行时的一些数据,建立函数调用关系图,还可以有选择地进行cache模拟。在运行结束时,它会把分析数据写入一个文件。callgrind_annotate可以把这个文件的内容转化成可读的形式。
Cachegrind
Cache分析器,它模拟CPU中的一级缓存I1,Dl和二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。
Helgrind
它主要用来检查多线程程序中出现的竞争问题。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。Helgrind实现了名为“Eraser”的竞争检测算法,并做了进一步改进,减少了报告错误的次数。不过,Helgrind仍然处于实验阶段。
Massif
堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。
此外,lackey和nulgrind也会提供。Lackey是小型工具,很少用到;Nulgrind只是为开发者展示如何创建一个工具
注意
Valgrind不检查静态分配数组的使用情况
Valgrind占用了更多的内存–可达两倍于你程序的正常使用量
如果你用Valgrind来检测使用大量内存的程序就会遇到问题,它可能会用很长的时间来运行测试
被检测程序加入 –g -fno-inline 编译选项保留调试信息, 否则后面的valgrind不能显示到出错行号。
valgrind被设计成非侵入式的,它直接工作于可执行文件上,因此在检查前不需要重新编译、连接和修改你的程序。要检查一个程序很简单,只需要执行下面的命令就可以了。
比如我们要对ls -l命令做内存检查,只需要执行下面的命令就可以了
小提示
如果不知道有哪些参数, 可以先输入valgrind –tool=, 然后狂按两次tab, 会输出linux系统的只能提示, 同样,如果你输入了valgrind –tool=mem再狂按两次tab,linux系统会为你自动补全
其中–leak-check=full 指的是完全检查内存泄漏,
–show-reachable=yes是显示内存泄漏的地点,
–trace-children=yes是跟入子进程。
当程序正常退出的时候valgrind自然会输出内存泄漏的信息原理:
mtrace其实是GNU扩展函数,用来跟踪malloc。
mtrace为内存分配函数(malloc, realloc, memalign, free)安装hook函数。这些hook函数记录内存的申请和释放的trace信息。
在程序中,这些trace信息可以被用来发现内存泄漏和释放不是申请的内存。
当调用mtrace,mtrace会检查环境变量MALLOC_TRACE。该环境变量应该包含记录trace信息的文件路径。如果文件可以被成功打开,它的大小被截断为0。
如果MALLOC_TRACE没有设置,或者设置的文件不可用或者不可写,那么将不会安装hook函数,mtrace不生效。
详细说明可参考man page:man 3 mtrace
在程序的起始处包含头文件
更改环境变量:export MALLOC_TRACE=”mtrace.out”可以加入如下代码
调用函数mtrace()
编译程序带上 -g 选项
运行程序一次,尽量调用所有程序内的函数。这时调试信息就已经被写入我们指定的mtrace.out文件中
mtrace a.out mtrace.out查看内存监测情况
所有使用动态内存分配(dynamic memory allocation)的程序都有机会遇上内存泄露(memory leakage)问题,在Linux里有三种常用工具来检测内存泄露的情況,包括:
参见 http://elinux.org/Memory_Debuggers
工具 | 描述 |
---|---|
valgrind | 一个强大开源的程序检测工具 |
mtrace | GNU扩展, 用来跟踪malloc, mtrace为内存分配函数(malloc, realloc, memalign, free)安装hook函数 |
dmalloc | 用于检查C/C++内存泄露(leak)的工具,即检查是否存在直到程序运行结束还没有释放的内存,以一个运行库的方式发布 |
memwatch | 和dmalloc一样,它能检测未释放的内存、同一段内存被释放多次、位址存取错误及不当使用未分配之内存区域 |
mpatrol | 一个跨平台的 C++ 内存泄漏检测器 |
dbgmem | |
Electric Fence |
1 被测程序
为了方便测试,,我们编写了一个简单的程序, 循环10次每次申请了一个100个字节的单元, 但是却不释放2 valgrind
2.1 valgrind介绍
是不是说没有一种内存检查工具能够在Linux使用呢,也不是,像开源的valgrind工具还是相当不错的Memcheck。这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。这也是本文将重点介绍的部分。
Callgrind。它主要用来检查程序中函数调用过程中出现的问题。
Cachegrind。它主要用来检查程序中缓存使用出现的问题。
Helgrind。它主要用来检查多线程程序中出现的竞争问题。
Massif。它主要用来检查程序中堆栈使用中出现的问题。
Extension。可以利用core提供的功能,自己编写特定的内存调试工具
主页 | 下载 |
---|---|
valgrind | downloads |
参照
Valgrind简单用法
Unix下C程序内存泄漏检测工具Valgrind安装与使用
valgrind 的使用简介
应用 Valgrind 发现 Linux 程序的内存问题
如何使用Valgrind memcheck工具进行C/C++的内存泄漏检测
2.2 安装
源码安装到下载地址)下载最新版的valgrind,按照里面的README提示,安装后就可以使用这个工具来检测内存泄露和内存越界等
/configure make sudo make install
当然也可以使用发行版的自带的源中安装
sudo apt install valgrind
这是一个没有界面的内存检测工具,安装后,输入 valgrind ls -l 验证一下该工具是否工作正常(这是README里面的方法,实际上是验证一下对ls -l命令的内存检测),如果你看到一堆的信息说明你的工具可以使用了。
2.3 使用说明
Valgrind工具包包含多个工具,如Memcheck,Cachegrind,Helgrind, Callgrind,Massif。Memcheck
最常用的工具,用来检测程序中出现的内存问题,所有对内存的读写都会被检测到,一切对malloc()/free()/new/delete的调用都会被捕获。所以,Memcheck 工具主要检查下面的程序错误
内容 | 描述 |
---|---|
使用未初始化的内存 | Use of uninitialised memory |
使用已经释放了的内存 | Reading/writing memory after it has been free’d |
使用超过 malloc分配的内存空间 | Reading/writing off the end of malloc’d blocks |
对堆栈的非法访问 | Reading/writing inappropriate areas on the stack |
申请的空间是否有释放 | Memory leaks – where pointers to malloc’d blocks are lost forever |
malloc/free/new/delete申请和释放内存的匹配 | Mismatched use of malloc/new/new [] vs free/delete/delete [] |
src和dst的重叠 | Overlapping src and dst pointers in memcpy() and related functions |
Callgrind
和gprof类似的分析工具,但它对程序的运行观察更是入微,能给我们提供更多的信息。和gprof不同,它不需要在编译源代码时附加特殊选项,但加上调试选项是推荐的。Callgrind收集程序运行时的一些数据,建立函数调用关系图,还可以有选择地进行cache模拟。在运行结束时,它会把分析数据写入一个文件。callgrind_annotate可以把这个文件的内容转化成可读的形式。
Cachegrind
Cache分析器,它模拟CPU中的一级缓存I1,Dl和二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。
Helgrind
它主要用来检查多线程程序中出现的竞争问题。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。Helgrind实现了名为“Eraser”的竞争检测算法,并做了进一步改进,减少了报告错误的次数。不过,Helgrind仍然处于实验阶段。
Massif
堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。
此外,lackey和nulgrind也会提供。Lackey是小型工具,很少用到;Nulgrind只是为开发者展示如何创建一个工具
注意
Valgrind不检查静态分配数组的使用情况
Valgrind占用了更多的内存–可达两倍于你程序的正常使用量
如果你用Valgrind来检测使用大量内存的程序就会遇到问题,它可能会用很长的时间来运行测试
2.4 使用说明
编译程序g++ -g -o leak leak.c
被检测程序加入 –g -fno-inline 编译选项保留调试信息, 否则后面的valgrind不能显示到出错行号。
valgrind被设计成非侵入式的,它直接工作于可执行文件上,因此在检查前不需要重新编译、连接和修改你的程序。要检查一个程序很简单,只需要执行下面的命令就可以了。
valgrind --tool=tool_name program_name
比如我们要对ls -l命令做内存检查,只需要执行下面的命令就可以了
valgrind --tool=memcheck ls -l
小提示
如果不知道有哪些参数, 可以先输入valgrind –tool=, 然后狂按两次tab, 会输出linux系统的只能提示, 同样,如果你输入了valgrind –tool=mem再狂按两次tab,linux系统会为你自动补全
2.5 使用valgrind检测Memcheck
下面我们就可以用valgrind对我们的程序检测leakvalgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes ./leak
其中–leak-check=full 指的是完全检查内存泄漏,
–show-reachable=yes是显示内存泄漏的地点,
–trace-children=yes是跟入子进程。
当程序正常退出的时候valgrind自然会输出内存泄漏的信息原理:
3 mtrace检测内存泄露
3.1 mtrace简介
在一般的linux发行版中,有一个自带的工具可以很方便的替你完成这些事,这个工具就是mtrace.mtrace其实是GNU扩展函数,用来跟踪malloc。
mtrace为内存分配函数(malloc, realloc, memalign, free)安装hook函数。这些hook函数记录内存的申请和释放的trace信息。
在程序中,这些trace信息可以被用来发现内存泄漏和释放不是申请的内存。
当调用mtrace,mtrace会检查环境变量MALLOC_TRACE。该环境变量应该包含记录trace信息的文件路径。如果文件可以被成功打开,它的大小被截断为0。
如果MALLOC_TRACE没有设置,或者设置的文件不可用或者不可写,那么将不会安装hook函数,mtrace不生效。
详细说明可参考man page:man 3 mtrace
3.2 mtrace使用
mtrace能监测程序是否内存泄露在程序的起始处包含头文件
#include <mcheck.h>
更改环境变量:export MALLOC_TRACE=”mtrace.out”可以加入如下代码
setenv("MALLOC_TRACE", "mtrace.out", 1);
调用函数mtrace()
mtrace()
编译程序带上 -g 选项
gcc -g -c leak_mtrace.c -o leak_mtrace.o -std=gnu9x -Wall
运行程序一次,尽量调用所有程序内的函数。这时调试信息就已经被写入我们指定的mtrace.out文件中
./leak_mtrace
mtrace a.out mtrace.out查看内存监测情况
mtrace a.out mtrace.out
4 dmalloc
dmalloc是一种用于检查C/C++内存泄露(leak)的工具,即检查是否存在直到程序运行结束还没有释放的内存,并且能够精确指出在哪个源文件的第几行。相关文章推荐
- linux centOS7安装mysql出现的一些问题和解决方法
- LINUX-内核-中断分析-中断向量表(2)-mips
- Centos6.5下虚拟机Linux 关于g++,gdb,ctags安装以及vim的配置
- CentOS中安装JDK与Intellij idea
- 使用WinSCP完成Windows与Linux之间的文件传输
- centos 7 下的python psutil模块
- Linux VMnet Adapter无法启动的解决办法
- Centos7.2配置yum源
- centos下espeak文本转语音的代码实现
- centos 7安装配置bind
- linux下进度条的简单实现
- 每天一个linux命令(56)--crontab命令
- Linux ldconfig 查看动态库连接
- Linux ldconfig 查看动态库连接
- Linux ldconfig 查看动态库连接
- Linux LAMP环境搭建
- tuxedo linux 安装
- linux常用的一些命令(二)
- SODBASE运维----Linux下SODBASE CEP集群命令
- linux常用的一些命令(一)