C:使用mtrace、memwatch、dmalloc检测内存泄漏

转载链接:https://my.oschina.net/letiantian/blog/754506

linux默认没有mtrace命令,mtrace是glibc内置命令,需要安装glibc工具集,安装命令:yum install glibc-utils.x86_64。只能分析出malloc、free。

#include <iostream>
#include <mcheck.h>
#include <stdlib.h>
using namespace std;

int main()
{
    setenv("MALLOC_TRACE","output",1);   // stdlib.h ,指定输出文件名
    mtrace();
    int *p1=new int;
    int *p2=new int;   // line 11
    int *p3=(int*)malloc(sizeof(int));
    int *p4=(int*)malloc(sizeof(int));   // line 13

    delete p1;
    free(p3);
    return 0;
}

编译运行:

$ g++ -Wall -g example06.cpp   # -g一定要加
$ ./a.out

output文件内容:

= Start
@ /usr/lib/x86_64-linux-gnu/libstdc++.so.6:(_Znwm+0x1d)[0x7f9a862b2dad] + 0x19e8730 0x4
@ /usr/lib/x86_64-linux-gnu/libstdc++.so.6:(_Znwm+0x1d)[0x7f9a862b2dad] + 0x19e8750 0x4
@ ./a.out:[0x4008c4] + 0x19e8770 0x4
@ ./a.out:[0x4008d2] + 0x19e8790 0x4
@ ./a.out:[0x4008e2] - 0x19e8730
@ ./a.out:[0x4008ee] - 0x19e8770
@ /lib/x86_64-linux-gnu/libc.so.6:(clearenv+0x7a)[0x7f9a85ecafaa] - 0x19e8010
@ /lib/x86_64-linux-gnu/libc.so.6:(tdestroy+0x5d)[0x7f9a85f85a6d] - 0x19e8290
@ /lib/x86_64-linux-gnu/libc.so.6:[0x7f9a85ff400c] - 0x19e82b0

使用mtrace命令分析:

mtrace ./a.out ./output     
- 0x00000000019e8010 Free 8 was never alloc'd 0x7f9a85ecafaa
- 0x00000000019e8290 Free 9 was never alloc'd 0x7f9a85f85a6d
- 0x00000000019e82b0 Free 10 was never alloc'd 0x7f9a85ff400c

Memory not freed:
-----------------
           Address     Size     Caller
0x00000000019e8750      0x4  at 0x7f9a862b2dad
0x00000000019e8790      0x4  at /path/to/example06.cpp:13

指出了有两个地方出现了问题。第一个信息应该是line 11的p2,但并未分析出来。第二处是第13行的变量未被free。目前对网络程序,即有阻塞的程序会自动,还不清楚具体原因。

2、memwatch


下载地址: http://www.linkdata.se/sourcecode/memwatch/

参考:http://brantc.blog.51cto.com/410705/116677/

也是针对free、malloc,对new、delete不起作用。

示例代码:

#include <iostream>
#include <mcheck.h>
#include <stdlib.h>
#include "memwatch/memwatch.h"
using namespace std;

int main()
{
    int *p1=new int;
    int *p2=new int;
    int *p3=(int*)malloc(sizeof(int));
    int *p4=(int*)malloc(sizeof(int));  // line 12

    delete p1;
    free(p3);
    return 0;
}

编译运行:

$ g++ -g -DMEMWATCH -DMW_STDIO  memwatch/memwatch.c example07.cpp
$ ./a.out

-D用来定义宏。

当前目录下出现memwatch.log文件,内容如下:


============= MEMWATCH 2.71 Copyright (C) 1992-1999 Johan Lindh =============

Started at Tue Oct  4 23:09:23 2016

Modes: __STDC__ 64-bit mwDWORD==(unsigned int)
mwROUNDALLOC==8 sizeof(mwData)==56 mwDataSize==56


Stopped at Tue Oct  4 23:09:23 2016

unfreed: <2> example07.cpp(12), 4 bytes at 0x13063b0  	{FE FE FE FE .. .. .. .. .. .. .. .. .. .. .. .. ....}

Memory usage statistics (global):
 N)umber of allocations made: 2
 L)argest memory usage      : 8
 T)otal of all alloc() calls: 8
 U)nfreed bytes totals      : 4

至于memwatch的原理,从memwatch.h中的这两行代码可以看出:

#define malloc(n)       mwMalloc(n,__FILE__,__LINE__)
// ...
#define free(p)         mwFree(p,__FILE__,__LINE__)

我们看下预编译的效果:

$ g++ -E -DMEMWATCH -DMW_STDIO   example07.cpp -o example07.pre.cpp

example07.pre.cpp中main函数如下:

int main()
{
    int *p1=new int;
    int *p2=new int;
    int *p3=(int*)mwMalloc(sizeof(int),"example07.cpp",11);
    int *p4=(int*)mwMalloc(sizeof(int),"example07.cpp",12);

    delete p1;
    mwFree(p3,"example07.cpp",15);
    return 0;
}

用malloc hook应该也能实现。

3、dmalloc


到 http://dmalloc.com/ 下载,解压、编译、安装:

$ ./configure
$ make
$ sudo make install

编辑~/.bashrc 或者一个新文件 加入:

function dmalloc { eval `command dmalloc -b $*`; }
$ source ~/.bashrc

源码:

#include <iostream>
#include <mcheck.h>
#include <stdlib.h>

#ifdef DMALLOC
#include <dmalloc.h>
#endif

using namespace std;

int main()
{
    int *p1=new int;
    int *p2=new int;
    int *p3=(int*)malloc(sizeof(int));
    int *p4=(int*)malloc(sizeof(int));  // line 16

    delete p1;
    free(p3);
    return 0;
}
$ dmalloc -b -l logfile -i 100 low
$ g++ -Iinclude -Llib -DDMALLOC -DDMALLOC_FUNC_CHECK example08.cpp -ldmalloc 
$ ./a.out

运行a.out,当前目录下生成logfile文件,内容如下:

1475635014: 6: Dmalloc version '5.5.2' from 'http://dmalloc.com/'
1475635014: 6: flags = 0x4e48503, logfile 'logfile'
1475635014: 6: interval = 100, addr = 0, seen # = 0, limit = 0
1475635014: 6: starting time = 1475635014
1475635014: 6: process pid = 11053
1475635014: 6: Dumping Chunk Statistics:
1475635014: 6: basic-block 4096 bytes, alignment 8 bytes
1475635014: 6: heap address range: 0x7ff352638000 to 0x7ff352643000, 45056 bytes
1475635014: 6:     user blocks: 1 blocks, 4072 bytes (9%)
1475635014: 6:    admin blocks: 10 blocks, 40960 bytes (91%)
1475635014: 6:    total blocks: 11 blocks, 45056 bytes
1475635014: 6: heap checked 1
1475635014: 6: alloc calls: malloc 4, calloc 0, realloc 0, free 2
1475635014: 6: alloc calls: recalloc 0, memalign 0, valloc 0
1475635014: 6: alloc calls: new 0, delete 0
1475635014: 6:   current memory in use: 8 bytes (2 pnts)
1475635014: 6:  total memory allocated: 16 bytes (4 pnts)
1475635014: 6:  max in use at one time: 16 bytes (4 pnts)
1475635014: 6: max alloced with 1 call: 4 bytes
1475635014: 6: max unused memory space: 48 bytes (75%)
1475635014: 6: top 10 allocations:
1475635014: 6:  total-size  count in-use-size  count  source
1475635014: 6:           4      1           4      1  example08.cpp:16
1475635014: 6:           4      1           0      0  example08.cpp:15
1475635014: 6:           8      2           4      1  Total of 2
1475635014: 6: Dumping Not-Freed Pointers Changed Since Start:
1475635014: 6:  not freed: '0x7ff352642fc8|s1' (4 bytes) from 'example08.cpp:16'
1475635014: 6:  not freed: '0x7ff352642fe8|s1' (4 bytes) from 'unknown'
1475635014: 6:  total-size  count  source
1475635014: 6:           4      1  example08.cpp:16
1475635014: 6:           4      1  Total of 1
1475635014: 6: ending time = 1475635014, elapsed since start = 0:00:00

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值