文档章节

linux c 内存泄露检测工具valgrind

悬崖
 悬崖
发布于 2014/08/29 10:57
字数 1905
阅读 175
收藏 12

Linux c/c++上常用内存泄露检测工具有valgrind, Rational  purifyValgrind免费。Valgrind 可以在 32 位或 64 PowerPC/Linux 内核上工作。
Valgrind
工具包包含多个工具,如Memcheck,Cachegrind,Helgrind,  CallgrindMassif。下面分别介绍个工具的作用:
Memcheck  
工具主要检查下面的程序错误:
使用未初始化的内存 (Use of uninitialised  memory)
使用已经释放了的内存 (Reading/writing memory  after it has been freed)
使用超过 malloc分配的内存空间(Reading/writing off the  end of mallocd blocks)
对堆栈的非法访问 (Reading/writing  inappropriate areas on the stack)
申请的空间是否有释放 (Memory leaks where pointers to  mallocd blocks are lost  forever)
 malloc/free/new/delete申请和释放内存的匹配(Mismatched use of  malloc/new/new [] vs free/delete/delete [])
srcdst的重叠(Overlapping src and dst  pointers in memcpy() and related functions)
Valgrind
不检查静态分配数组的使用情况。
Valgrind
占用了更多的内存--可达两倍于你程序的正常使用量。如果你用Valgrind来检测使用大量内存的程序就会遇到问题,它可能会用很长的时间来运行测试
2.1.  
下载安装
http://www.valgrind.org
安装
./configure;make;make install
2.2.
编译程序
被检测程序加入 g   -fno-inline  编译选项保留调试信息。

2.3.  
内存泄露检测
$ valgrind --tool=memcheck  --log-file=/home/trunk/valgrind_log_all --leak-check=full --error-limit=no  --show-leak-kinds=all /opt/lim/bin/limserver

其中--leak-check=full  指的是完全检查内存泄漏,--show-reachable=yes是显示内存泄漏的地点,--trace-children=yes是跟入子进程。当程序正常退出的时候valgrind自然会输出内存泄漏的信息。

1.内存泄露:

#include <stdio.h>void function()
{    int *p = (int*)malloc(10*sizeof(int));    p[10] = 0;
}int main()
{    function();    return 0;
}

相关日志:

==20220== Memcheck, a memory error detector
==20220== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==20220== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==20220== Command: ./test
==20220== Parent PID: 20160
==20220==
==20220== Invalid write of size 4
==20220==    at 0x80483FF: function (in /mnt/Documents/Training/valgrind/test)
==20220==    by 0x8048411: main (in /mnt/Documents/Training/valgrind/test)
==20220==  Address 0x41be050 is 0 bytes after a block of size 40 alloc'd
==20220==    at 0x4028876: malloc (vg_replace_malloc.c:236)
==20220==    by 0x80483F5: function (in /mnt/Documents/Training/valgrind/test)
==20220==    by 0x8048411: main (in /mnt/Documents/Training/valgrind/test)
==20220==
==20220==
==20220== HEAP SUMMARY:
==20220==     in use at exit: 40 bytes in 1 blocks
==20220==   total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==20220==
==20220== LEAK SUMMARY:
==20220==    definitely lost: 40 bytes in 1 blocks
==20220==    indirectly lost: 0 bytes in 0 blocks
==20220==      possibly lost: 0 bytes in 0 blocks
==20220==    still reachable: 0 bytes in 0 blocks
==20220==         suppressed: 0 bytes in 0 blocks
==20220== Rerun with --leak-check=full to see details of leaked memory
==20220==
==20220== For counts of detected and suppressed errors, rerun with: -v
==20220== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 6)

2.使用未初始化的内存

#include <stdio.h>int main()
{    int a;    if (a==1)
    {        printf("a==%d\n",a);
    }    return 0;
}

日志分析:

==20345== Memcheck, a memory error detector
==20345== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==20345== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==20345== Command: ./test
==20345==
==20345== Conditional jump or move depends on uninitialised value(s)
==20345==    at 0x80483F2: main (in /mnt/Documents/Training/valgrind/test)

==20345==
==20345==
==20345== HEAP SUMMARY:
==20345==     in use at exit: 0 bytes in 0 blocks
==20345==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==20345==
==20345== All heap blocks were freed -- no leaks are possible
==20345==
==20345== For counts of detected and suppressed errors, rerun with: -v
==20345== Use --track-origins=yes to see where uninitialised values come from
==20345== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 6)

可以使用--track-origins=yes 得到更多的信息

3.内存读写越界

#include <stdio.h>int main()
{    int *a = (int*)malloc(5*sizeof(int));    a[5] = 1;    return 0;
}

==20368== Memcheck, a memory error detector
==20368== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==20368== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==20368== Command: ./test
==20368==
==20368== Invalid write of size 4
==20368==    at 0x8048404: main (in /mnt/Documents/Training/valgrind/test)
==20368==  Address 0x41be03c is 0 bytes after a block of size 20 alloc'd
==20368==    at 0x4028876: malloc (vg_replace_malloc.c:236)
==20368==    by 0x80483F8: main (in /mnt/Documents/Training/valgrind/test)

==20368==
==20368==
==20368== HEAP SUMMARY:
==20368==     in use at exit: 20 bytes in 1 blocks
==20368==   total heap usage: 1 allocs, 0 frees, 20 bytes allocated
==20368==
==20368== LEAK SUMMARY:
==20368==    definitely lost: 20 bytes in 1 blocks
==20368==    indirectly lost: 0 bytes in 0 blocks
==20368==      possibly lost: 0 bytes in 0 blocks
==20368==    still reachable: 0 bytes in 0 blocks
==20368==         suppressed: 0 bytes in 0 blocks
==20368== Rerun with --leak-check=full to see details of leaked memory
==20368==
==20368== For counts of detected and suppressed errors, rerun with: -v
==20368== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 6)

4.内存申请释放管理错误

#include <stdio.h>int main()
{    int *a = new int[5];    /*free(a);*/    delete a;    return 0;
}

==20387== Memcheck, a memory error detector
==20387== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==20387== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==20387== Command: ./test
==20387==
==20387== Mismatched free() / delete / delete []
==20387==    at 0x4027919: operator delete(void*) (vg_replace_malloc.c:387)
==20387==    by 0x8048498: main (in /mnt/Documents/Training/valgrind/test)
==20387==  Address 0x42f2028 is 0 bytes inside a block of size 20 alloc'd
==20387==    at 0x4027F65: operator new[](unsigned int) (vg_replace_malloc.c:299)
==20387==    by 0x8048488: main (in /mnt/Documents/Training/valgrind/test)

==20387==
==20387==
==20387== HEAP SUMMARY:
==20387==     in use at exit: 0 bytes in 0 blocks
==20387==   total heap usage: 1 allocs, 1 frees, 20 bytes allocated
==20387==
==20387== All heap blocks were freed -- no leaks are possible
==20387==
==20387== For counts of detected and suppressed errors, rerun with: -v
==20387== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 6)

内存泄露

问题描述:

内存泄露(Memory leak)指的是,在程序中动态申请的内存,在使用完后既没有释放,又无法被程序的其他部分访问。内存泄露是在开发大型程序中最令人头疼的问题,以至于有人说,内存泄露是无法避免的。其实不然,防止内存泄露要从良好的编程习惯做起,另外重要的一点就是要加强单元测试(Unit Test),而memcheck就是这样一款优秀的工具。

下面是一个比较典型的内存泄露案例。main函数调用了mk函数生成树结点,可是在调用完成之后,却没有相应的函数:nodefr释放内存,这样内存中的这个树结构就无法被其他部分访问,造成了内存泄露。

在一个单独的函数中,每个人的内存泄露意识都是比较强的。但很多情况下,我们都会对malloc/free 或new/delete做一些包装,以符合我们特定的需要,无法做到在一个函数中既使用又释放。这个例子也说明了内存泄露最容易发生的地方:即两个部分的接口部分,一个函数申请内存,一个函数释放内存。并且这些函数由不同的人开发、使用,这样造成内存泄露的可能性就比较大了。这需要养成良好的单元测试习惯,将内存泄露消灭在初始阶段。

清单 11

清单 1

清单 11.2

清单 11.2

清单 11.3

清单 11.3

结果分析:

假设上述文件名位tree.h, tree.cpp, badleak.cpp,生成的可执行程序为badleak,用memcheck对其进行测试,输出如下。

清单 12

清单 12

该示例程序是生成一棵树的过程,每个树节点的大小为12(考虑内存对齐),共8个节点。从上述输出可以看出,所有的内存泄露都被发现。Memcheck将内存泄露分为两种,一种是可能的内存泄露(Possibly lost),另外一种是确定的内存泄露(Definitely lost)。Possibly lost 是指仍然存在某个指针能够访问某块内存,但该指针指向的已经不是该内存首地址。Definitely lost 是指已经不能够访问这块内存。而Definitely lost又分为两种:直接的(direct)和间接的(indirect)。直接和间接的区别就是,直接是没有任何指针指向该内存,间接是指指向该内存的指针都位于内存泄露处。在上述的例子中,根节点是directly lost,而其他节点是indirectly lost。





© 著作权归作者所有

悬崖
粉丝 3
博文 54
码字总数 22549
作品 0
海淀
程序员
私信 提问
Linux下几款C++程序中的内存泄露检查工具

Linux下几款C++程序中的内存泄露检查工具 Linux下编写C或者C++程序,有很多工具,但是主要编译器仍然是gcc和g++。最近用到STL中的List编程,为了检测写的代码是否会发现内存泄漏,了解了一下...

优惠券发放
2018/08/25
0
0
应用 Valgrind 发现 Linux 程序的内存问题

Valgrind 概述 体系结构 Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它...

mjrao
2012/05/01
0
0
Linux内存泄漏检测

如题,就工具而言主要包括valgrind、mtrace、dmalloc和memwatch等,具体使用请参照以下连接 Linux C内存泄露检测工具 http://blog.sina.com.cn/s/blog_4b9216f50100e6o7.html Linux C/C++ 内...

zongquanliu
2014/12/11
0
0
几个C++内存泄漏和越界检测工具简介

一、BoundsChecker 或许你还不知道大名顶顶的Nu-Mega,但一定听说过他们的产品SoftICE,BoundsChecker也是这家公司的产品。与Visual C++配合使用,据说威力强大。本人和没有实际用过,在此复...

江河海流
2014/05/14
0
0
Centos下Valgrind使用与安装

第一步: 获取Valgrind 包 可以先使用浏览器访问http://valgrind.org/downloads/查看当前版本 wget http://valgrind.org/downloads/valgrind-3.10.1.tar.bz2 第二步: 将下载的文件解压 tar ...

shzwork
05/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

MySql双主架构原理

在企业中,一般系统架构的瓶颈会出现在数据库这一部分,mysql主从架构在很大程度上解决了这部分瓶颈,但是在mysql主从同步的架构也存在很多问题;比如:1.关于数据写入部分(也就是主库)往往很难做...

xiaomin0322
33分钟前
1
0
分布式系统中一致性哈希

问题场景 近年来B2C、O2O等商业概念的提出和移动端的发展,使得分布式系统流行了起来。分布式系统相对于单系统,解决了流量大、系统高可用和高容错等问题。功能强大也意味着实现起来需要更多...

Java领航员
34分钟前
1
0
接口限流算法:漏桶算法和令牌桶算法

漏桶算法 漏桶可以看作是一个带有常量服务时间的单服务器队列,如果漏桶(包缓存)溢出,那么数据包会被丢弃。这一点和线程池原理是很相似的。 把请求比作是水,水来了都先放进桶里,并以限定...

铁骨铮铮
41分钟前
6
0
Android 生成二维码工具类

/** * 生成条形码和二维码的工具 */public class ZXingUtils { /** * 生成二维码 要转换的地址或字符串,可以是中文 * * @param url * @param width ...

lanyu96
46分钟前
2
0
谈谈lucene的DocValues特性之SortedNumericDocValuesField

前面已经介绍过NumericDocValuesField,这里想强调一下SortedNumericDocValuesField是针对同一篇文档中一键多值的情况进行排序的,换句话说不同文档的同一字段值可以乱序。核心的写入流程与谈...

FAT_mt
54分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部