LeakTracer使用教程

2019-06-18 15:43:49 浏览数 (1)

LeakTracer使用教程

在进行评测工具的开发时,发现最终跑出来的内存曲线如下图所示。呈缓慢的增长趋势,但是在代码review的时候,并未发现有明显的内存泄漏问题,为排查这个问题,决定在评测工具中引入基于NDK的C 内存检查工具LeakTracer(其实还有其他的同类型检测工具如Valgrind等),在这里介绍下这个工具的基本使用方法。

工具的下载

工具的下载:

说明网站:

http://www.andreasen.org/LeakTracer/

下载地址:https://github.com/fredericgermain/LeakTracer

下载后结构如下:

1. helpers中封装的是helper工具,在其中评测项目中用到了leak-analyze-addr2line脚本用于解析产生的内存泄漏文件。

2. test中提供辅助了解代码的测试文件

3. libleaktracer中存放主要的lib文件

工具的使用

有两种方法可以将LeakTracer引入项目中:

1. 将自己的程序与libleaktracer进行链接,也就是将自己的程序一个静态链接库libleaktracer进行链接,静态链接是会将库的代码揉进我们自己项目的目标代码so中的。

2. 利用项目中提供的makefile文件,将自己的程序与libleaktracer.so进行链接。需要将-lleaktracer选项做为链接命令的第一个选项。

在内核评测工具中,使用的是第一种方法,把LeakTracer拷贝到项目中,并在cmake文件中添加以下说明:

sync并且build项目成功,证明LeakTracer已经成功引入到项目中。想要使用这个工具,需要以下两个步骤:

  1. 在运行时启动trace记录
  1. 在程序结束时,关闭trace,并且将memory leak写入指定文件。

这个时候发现我们的手机中已经有了内存泄漏文件。

内部文件的格式如下所示:

文件的解析

既然有了没被正确释放的内存分配时候的栈信息,那就将它们转换到代码文件的行数吧。LeakTracer/helpers下的leak-analyze-addr2line工具就可以帮我们完成这些。

执行命令:

perl leak-analyze-addr2line /Users/apple/Downloads/A8.28/core_project/test/android/rt_launcher/app/build/intermediates/cmake/debug/obj/armeabi-v7a/libCoreTest.so leaks.out

此处需注意leak-analyze-addr2line是perl脚本,一直以为是sh脚本,一直在报错,直到看了原文件, 需配置perl环境,并将perl添加进环境目录。

命令执行完毕后发现地址解析异常如下:

found166 leak(s)

252 bytes lost in 9 blocks (one of them allocated at 9084.533162), from following call stack:

??:0

??:0

??:0

??:0

??:0

排查原因,说明内存地址都是进程地址空间的绝对地址,动态链接库在每次加载是都可能被映射在进程内存地址空间的不同位置,因而addr2line无法根据符号的地址空间绝对地址转换到代码行数。

如果手动转换的话,需要先通过/proc/[pid]/maps找到我们的动态链接库映射的内存基地址,然后算出backtrace每个地址对应的动态链接库内部的偏移地址,再通过addr2line来将内存地址转换到代码文件的行号,比较繁琐;在网上找到了解决方案,在记录时地址信息时,同时获取library映射到的内存的基地址即可。

在MemoryTrace::init_no_alloc_allowed()中添加以下句子:

再次执行命令,文件解析成功,内存问题展示如下:

需要注意的是,不是全部输出的问题都是内存泄漏问题,有可能代码封装好在程序结束时自动释放,这种现象也会被当成是内存泄漏问题而被指出;并且使用LeakTracer,会使程序变慢,不建议与其他评测程序共同执行。

0 人点赞