内存泄漏检测工具
文章目录
- 内存泄漏检测工具
- 一、valgrind介绍
- 1. memcheck
- 2. cachegrind
- 3. helgrind
- 二、源码下载
- 三、命令操作
- 1.memcheck 工具
- 四、虚拟机下使用
- 1. x86编译
- 2. 正常程序测试
- 3. 申请内存不释放测试
- 4. 内存越界的测试
- 5. 读写已经释放的内存
- 五、ARM平台使用
- 1.交叉编译
- 2. 内存泄漏测试
- 六、总结
一、valgrind介绍
valgrind包含几个标准的工具,它们是:
- memcheck
- cachegrind
- helgrind
1. memcheck
memcheck探测程序中内存管理存在的问题。它检查所有对内存的读/写操作,并截取所有的malloc/new/free/delete调用。因此memcheck工具能够探测到以下问题:
- 使用未初始化的内存
- 读/写已经被释放的内存
- 读/写内存越界
- 读/写不恰当的内存栈空间
- 内存泄漏
- 使用malloc/new/new[]和free/delete/delete[]不匹配
2. cachegrind
cachegrind是一个cache剖析器。它模拟执行CPU中的L1, D1和L2 cache,因此它能很精确的指出代码中的cache未命中。如果你需要,它可以打印出cache未命中的次数,内存引用和发生cache未命中的每一行代码,每一个函数,每一个模块和整个程序的摘要。如果你要求更细致的信息,它可以打印出每一行机器码的未命中次数。在x86和amd64上,cachegrind通过CPUID自动探测机器的cache配置,所以在多数情况下它不再需要更多的配置信息了。
3. helgrind
helgrind查找多线程程序中的竞争数据。helgrind查找内存地址,那些被多于一条线程访问的内存地址,但是没有使用一致的锁就会被查出。这表示这些地址在多线程间访问的时候没有进行同步,很可能会引起很难查找的时序问题。
二、源码下载
1. 官网下载地址
2. 蓝秦云下载地址
三、命令操作
1.memcheck 工具
valgrind命令行使用–tool=memcheck选项使用memcheck
memcheck命令行选项:
–leak-check= :默认为summary,用于内存泄漏检查
–leak-resolution=:默认为high,
–show-leaks-kind= [definite, possible, reachable, indirect]
–errors-for-leak-kinds= [definite, possible]
–leak-check-heuristics= [default : all]
–show-reachable=, --show-possible-lost=
–xtree-leak=
–xtree-leak-file= [default: xleak.kcg.%p] :指定valgrind生成报告文件名称
–undef-value-error= :valgrind是否报告未定义值错误
–track-origin= :是否跟踪未初始化值
–partial-loads-ok= :memcache处理32-,64-,128-和256-字节类型数据地址对齐;
–expensive-definedness-checks= :
–keep-stacktrace=alloc|free|alloc-and-free|alloc-then-free|none : 跟踪栈上malloc和free数据块
–freelist-vol= :客户程序调用free或者delete释放内存,释放的内存无法立即变为可用内存。队列中块的最大值,
–freelist-big-blocks= :0意味着所有数据库可被重新使用
–workaroud-gcc296-bugs=
–ignore-range-below-sp:
–show-mismatched-frees= :检查堆中块释放有对应的释放函数调用。
–ignore-ranges=0xPP-0xQQ
–malloc-fill= :填充的16进制内容
–free-fill=
: 调用free,delete指定内存填充内容
四、虚拟机下使用
1. x86编译
- 解压
tar -jxvf valgrind-3.20.0.tar.bz2 valgrind-3.20.0/
- 进入到目录
cd valgrind-3.20.0
- 检查环境生成Makefile
./configure
- 编译
make
- 安装到虚拟机
sudo make install
没有指定目录,默认安装到虚拟机到 /usr/local/
2. 正常程序测试
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char * p = (char*) malloc(10);
free(p);
return 0;
}
3. 申请内存不释放测试
//malloc.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
char * p = (char*) malloc(10);
return 0;
}
编译
gcc malloc.c -g -o malloc
用valgrind执行命令
valgrind --tool=memcheck --leak-check=yes ./malloc
生成报告
4. 内存越界的测试
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char * p = (char*) malloc(10);
strcpy(p, "12345678901");
free(p);
return 0;
}
报告
5. 读写已经释放的内存
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char * p = (char*) malloc(10);
free(p);
strcpy(p, "123");
return 0;
}
报告
五、ARM平台使用
1.交叉编译
测试环境在米尔的6ull板子进行测试
- 下载源码
- 解压
tar -jxvf valgrind-3.12.0.tar.bz2
- 执行脚本
./autogen.sh
- 修改configure
找到armv7修改为 armv7*|arm* 6022行,修改如下,否则会报错
checking host system type… arm-unknown-linux-gnu checking for a supported CPU… no (arm) configure: error: Unsupported host architecture. Sorry
修改如下
armv7*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok (${host_cpu})" >&5
$as_echo "ok (${host_cpu})" >&6; }
ARCH_MAX="arm"
;;
armv7*|arm*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok (${host_cpu})" >&5
$as_echo "ok (${host_cpu})" >&6; }
ARCH_MAX="arm"
;;
-
进入root模式
sudo -s
-
环境配置
加载编译器的环境变量
source /opt/full/environment-setup-cortexa7t2hf-neon-poky-linux-gnueabi
检查 安装目录在虚拟机的/opt/valgrind-3.20.0
./configure --host=arm-linux --prefix=/opt/valgrind-3.20.0
-
编译
make -j
make install
2. 内存泄漏测试
- 创建目录
mkdir -p /opt/valgrind-3.20.0/
- 挂载虚拟机的工具目录
mount -t nfs 192.168.1.4:/opt/valgrind-3.20.0/ /opt/valgrind-3.20.0/
- 加载环境变量(可选)
export PATH=/opt/valgrind-3.20.0/bin/:$PATH
- 测试代码
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p = malloc(20);
return 0;
}
- 测试报告
六、总结
ARM平台下采集采用nfs挂载的方式进行测试,避免找不到库,所以虚拟机编译安装的路径和设备上运行的路径保持一致