linux分析内存泄露,linuxc编程mtrace分析内存泄露md

1.内存泄露介绍

在工作中,动态内存调配是常有的事,而随同动态内存调配而来的最大的问题就是“内存泄露”。所谓“内存泄露”的意思就是申请了内存,但遗记归还给零碎,长此以往,零碎的可分配内存越来越少,这种问题一旦呈现必然很难查找。起因很简略,程序是人写的,写的人都遗记本人已经在哪里调配了而没有开释,那零碎就更不能轻易帮忙回收内存了。一旦“内存泄露”产生,特地是放生在一些生命周期较长的程序中,从零碎的角度来说,可用内存莫名其妙地越来越少,形象地就比喻零碎上如同真的呈现了一个洞,内存从这个洞里被“漏掉”不见了。

2.mtrace应用介绍

一旦发现零碎有这个“苗头”,事不宜迟就是要找到代码里哪里遗记偿还了动态分配的内存。而“内存调配跟踪(malloctracing)”机制则是帮忙查看“内存泄露”的好帮手,本文就来给大家介绍一下这个工具的应用,习惯上这个工具简称为mtrace,下文也间接用mtrace指称这个工具。

mtrace工具的次要思路是在的调用内存调配和开释的函数中装载“钩子(hook)”函数,通过钩子函数打印的日志来帮忙剖析对内存的应用是否存在问题。对该工具的应用包含两局部内容,一个是要批改源码,装载hook函数,另一个是通过运行批改后的程序,生成非凡的log文件,而后利用mtrace工具剖析日志,判断是否存在内存泄露以及定位可能产生内存泄露的代码地位。

mtrace是Glibc的一部分,毋庸非凡装置。mtrace钩子函数定义如下:

#include

void mtrace(void);

void muntrace(void);

其中mtrace()用于开启内存调配跟踪,muntrace()用于勾销内存调配跟踪。

具体的做法是mtrace()函数中会为那些和动态内存调配无关的函数(如malloc、realloc、memalign以及free)装置“钩子(hook)”函数,这些hook函数会为记录所有无关内存调配和开释的跟踪信息,而muntrace()则会卸载相应的hook函数。基于这些hook函数生成的调试跟踪信息,就能够剖析是否存在“内存泄露”这类问题了。

2.1. 示例代码

示例代码如下:

demo_mtrace_memleak.c

/* gcc demo_mtrace_memleak.c -o demo_mtrace_memleak -g -Wall */

#include

#include

#include

int main(int argc, char **argv)

{

mtrace();

char *p = malloc(16);

free(p);

p = malloc(32);

muntrace();

return 0;

}

如上,进行了两次malloc申请内存的操作,但只开释一次,因而会导致“内存透露”。看看mtrace是否能的到雷同的论断。

2.2. mtrace命令行应用

mtrace机制须要理论运行一下程序,而后能力生成跟踪的日志,但在运行程序前还须要定义并导出一个环境变量MALLOC_TRACE用于记录剖析日志,如下所示。

export MALLOC_TRACE=./memleak.log

上述的后果就是通知mtrace在生成日志信息时,在以后门路下创立一个名为memleak.log的文件,并将日志输入到这个文件中去。

运行程序后,查看memleak.log内容如下:

= Start

@ ./demo_mtrace_memleak:[0x7f6ca1400738] + 0x7fffc93796a0 0x10

@ ./demo_mtrace_memleak:[0x7f6ca1400748] - 0x7fffc93796a0

@ ./demo_mtrace_memleak:[0x7f6ca1400752] + 0x7fffc93796c0 0x20

= End

这个文件的内容有三行“无效”记录(除去第一行=Start和最初一行=End),别离对应源码的malloc->free->malloc操作。

具体格局以第一行@ ./demo_mtrace_memleak:[0x7f6ca1400738] + 0x7fffc93796a0 0x10为例。./demo_mtrace_memleak显然指的是运行的可执行程序的名字。[0x7f6ca1400738]这里的数值是对应代码中第一次调用地址,但留神这是机器码的地址,恰好在编译可执行程序的时候利用-g带上了调试信息,所以齐全能够利用addr2line这个工具,反推出源文件的行数。具体做法如下:

# addr2line -f -e ./demo_mtrace_memleak 0x00748

main

/mnt/d/MingruiZhou/tinylab/demo_mtrace_memleak.c:11

确实在第11行。

接着前面的是一个符号+,表明这一行对应的是分配内存,反之-示意是开释。再往后是一个数值0x7fffc93796a0,是malloc()函数调配的内存的首地址。最初是0x10,换算成十进制就是16,正是调配的内存的大小。

理解了具体格局后从三行无效日志中能够得出,因为第一行是调配,其调配的内存首地址是0x7fffc93796a0,而第二行开释的内存的首地址也是0x7fffc93796a0,天然阐明是一对,互相对消,不存在内存泄露。第三行调配的内存首地址是0x7fffc93796c0,前面没有匹配的开释日志,则阐明这里呈现了“内存泄露”。

在理论工作中的场景代码相对不会就这么几行的,零碎提供了一个叫做mtrace的命令行工具能够帮忙实现对日志的剖析。

连忙来试一下。输出如下命令:

# mtrace ./demo_mtrace_memleak $MALLOC_TRACE

Memory not freed:

-----------------

Address Size Caller

0x00007fffc93796c0 0x20 at 0x7f6ca1400752

输入的后果曾经通知了所有。mtrace这个工具须要至多两个参数,一个是生成的可执行程序文件的门路,还有一个是日志文件的门路。

mtrace还能帮忙查找“反复开释”问题。示例如下:

/* gcc demo_mtrace_double_free.c -o demo_mtrace_double_free -g -Wall */

#include

#include

#include

int main(int argc,char **argv)

{

char *s = NULL;

mtrace();

s = malloc(32);

free(s);

free(s); //

muntrace();

return 0;

}

后果如下:

# gcc demo_mtrace_double_free.c -o demo_mtrace_double_free -g -Wall

#

# export MALLOC_TRACE=./double_free.log

# ./demo_mtrace_double_free

# mtrace ./demo_mtrace_double_free $MALLOC_TRACE

- 0x00007fffd74056a0 Free 4 was never alloc'd 0x7f07ff60075c

No memory leaks.

# addr2line -f -e ./demo_mtrace_double_free 0x75c

main

/mnt/d/MingruiZhou/tinylab/demo_mtrace_double_free.c:19

尽管最终并没有精确找到出错行,但也靠近谬误行。

email: MingruiZhou@outlook.com

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值