StupidBeauty
Read times:687Posted at:Wed Jul 4 17:40:39 2012
- no title specified

LeakTracer文档翻译

内容目录

介绍

要求

安装

用LeakTracer来运行程序

可检测的错误

分析输出内容

共享库和目标文件

许可证

荣誉

开发历史

介绍

LeakTracer是我在检查一个C++程序的内存泄漏问题时编写的一个小工具。我无法用dmalloc 找到我要找的问题,又碰巧发现有人提到咯__builtin_return_address这个gcc 扩展。

使用LeakTracer 的方法就是,用软件包中提供的LeakCheck 脚本来启动妳的程序。它利用LD_PRELOAD 功能来用某些函数“覆盖”(无需重新编译)掉妳的函数。如果妳的平台不支持LD_PRELOAD 的话,那么妳还可以将LeakTracer.o 这个目标文件添加到妳的Makefile 的目标中去,再运行妳的程序。

LeakTracer使用gdb来输出那些已经分配却没有释放的内存所发生的代码行号 - 这也意味着妳必须将所有动态分配的数据都释放掉。LeakTracer还会重载全局的new 和delete操作符 - 如果妳也重载咯这些操作符那么就会产生问题。

LeakTracer只跟踪new/new[]和 delete - 它不关注malloc/free/realloc。

输出内容的示例:

Gathered 8 (8 unique) points of data.

(gdb)

Allocations: 1 / Size: 36

0x80608e6 is in NullArcableInstance::NullArcableInstance(void) (Machine.cc:40).

39 public:

40 NullArcableInstance() : ArcableInstance(new NullArcable) {}

Allocations: 1 / Size: 8

0x8055b02 is in init_types(void) (Type.cc:119).

118 void init_types() {

119 Type::Integer = new IntegerType;

Allocations: 1 / Size: 132 (new[])

0x805f4ab is in Hashtable::Hashtable(unsigned int) (ea/h/Hashtable.h:15).

14 Hashtable (uint _size = 32) : size(_size), count(0) {

15 table = new List [size];

[...]

要求

妳需要安装Perl5 和gdb,才能运行leak-analyzer。妳需要gcc -- 我目前用的是2.95 版本,但是也用过一些旧版本,没有问题。

妳还需要在一个支持大于0的__builtin_return_address参数的架构上运行这个工具 - 在MIPS 架构上可能会有问题。

目前为止,这个工具在Linux 2.2、x86系统、Solaris 和HP-UX上测试过。

安装

直接执行make。没有install 这个目标;妳应当把LeakTracer放到一个妳能记住的地方。

从版本2.0 开始,可以在那些支持LD_PRELOAD 的架构(至少是Linux,其它系统可能也支持 -- 请报告在妳的系统上是否成功)上预载入LeakTracer 目标。这就意味着这个工具更易于使用咯:妳不需要将自己的程序与LeakTracer.o 重新链接在一起。

万一妳的平台不支持LD_PRELOAD 的话,妳还可以按照2.0 之前的老方法来使用LeakTracer:将LeakTracer.o 添加到妳的目标文件中 -- 要添加到它们的末尾(注意还要在-llibrary之后)。

另外妳的程序还必须以调试模式编译(也就是说:-g)。

用LeakTracer来运行程序

如果妳使用的是共享库方式,则运行LeakCheck 脚本。这个脚本应当一直放在妳安装LeakCheck 的目录中 -- 它会在其中寻找LeakTracer.so文件并且载入它。例如:

~/src/LeakTracer/LeakCheck 妳的程序

(这里假设妳将LeakTracer 放在~/src/LeakTracer/)

照常运行妳的程序,去做那些妳想检测其内存泄漏现象的操作。在程序运行的过程中,LeakTracer会在当前目录中写入信息到"leak.out"文件,其中记录的是关于内存分配的数据。妳可以设置LEAKTRACE_FILE 环境变量,以使用一个不同的文件名。

如果妳无法使用LD_PRELOAD,那么重新链接妳的程序,再直接运行它。当它结束时也会产生一个"leak.out"文件。

可检测的错误

LeakTracer可检测到程序中的这些错误

1) 已分配却没有释放的内存

2) (有限地支持) 写入操作越过咯某块已分配的内存的末尾( 原因 = 1 )

3) 尝试释放一块并没有分配的内存(可能是一个野指针,也可能是内存被释放两次)

(原因 = 2)

4) 内存是以new[]分配的,却是以delete释放的;或者相反的情形(原因 = 4)

对于后面三种情形,如果妳要求的话,LeakTracer 可以终止(abort())妳的程序;由此产生的内存转储文件就可以用来调试对应的问题。默认设置下,只有写内存越界的情况会导致终止程序,因为它本来就是严重错误。另外两种情况并不是严重错误。

妳可以使用环境变量LT_ABORTREASON来改变LeakTracer 在这三种情况下的行为,只需将它的值设置成上面枚举情况中括号里的“原因”值的和。例如,要想在三种情况下都终止程序,则应当将LT_ABORTREASON 设置成7.

分析输出内容

接下来,妳应当运行leak-analyze,因为直接去看leak.out 文件的话得不到多少有用信息。要想运行leak-analyze,妳需要安装Perl 和gdb(gdb不限版本)。例如:

leak-analyze 我的程序 leak.out

如果妳使用的是默认的文件名,就不用指定leak.out。leak-analyze会在那个文件上运行gdb,向它发送一些命令,那样就会显示出内存泄漏的源代码行。

Leak-analyze应当显示出这样的东西:

Gathered 2 (2 unique) points of data.

#-- Alloc: Different allocation schemes

alloc here :0x80485b7 is in main (test.cc:6).

5

6 int *wrong = new int[10];

..free here :0x80485d9 is in main (test.cc:11).

11 delete wrong;

#-- Leak: Allocations: 1 / Size: 168

0x8048593 is in main (test.cc:3).

2 int main() {

3 int *array = new int [42] ;

#-- Leak: Allocations: 1 / Size: 4

0x80485a5 is in main (test.cc:4).

3 int *array = new int [42] ;

4 int *foo = new int;

这表示发生咯两次内存分配,位于两个不同地方。

首先是一个释放错误:妳使用new[]分配咯一些内存,却用 delete 来释放它们。leak-analyze会显示出妳在哪里分配,在哪里释放的。

然后就会显示出每次内存分配的情况。在这一行(test.cc:3)有一次内存分配,分配咯168 字节。注意,这里显示咯两行代码,下面一行才是进行内存分配的那一行。

就是这样用咯 - 现在妳应当找到那些内存泄漏,修复它们,再重新运行Leak tracer。

共享库和目标文件

如果妳想要分析妳的文件中的共享库的内存泄漏情况,那么就需要让leak-analyze 运行妳的程序以载入那些共享库,再搜索内存地址。

妳想那样做的话,就运行leak-analyze,提供程序名字、泄漏数据文件名另一个参数,最后这个参数指的是在哪里设置断点。例如:

leak-analyze 我的程序 leak.out main

这会使得leak-analyze 告诉gdb 在"main"上设置一个断点,然后运行程序。当分析结束之后,程序会被杀死。

如果妳想要载入某些共享库,那么妳可以在别的地方设置断点。例如,如果妳知道一旦运行到第42行就已经载入所有共享库的话,就可以将断点设置成main.cc:42。

如果妳的程序需要提供命令行参数,就把它们写在"main"后面。

许可证

LeakTracer是公有的(也就是说妳想用它做什么都可以)。

荣誉

LeakTracer 的最初版本是由Erwin Andreasen 编写的。Henner Zeller

(H.Zeller@acm.org)将代码重写咯,加入咯的动态载入LeakTracer 的功能及其它功能。

开发历史

1999.2.21 v1.0 - 内部测试用

1999.2.23 v1.1 - 添加咯new[] / delete[]操作符

1999.2.23 v1.2 - 搞个鸟,忘记释放(free())内存咯……

1999.2.26 v1.3 - 允许delete 0

1999.3.27 v1.4 - 对于非GNU libc 的情况,允许不带前置0x 的%p格式。加入选项,用 leak-analyze 来运行程序。

1999.7.21 v1.5 - 按照Alan Gonzalez的建议,修复上文的问题

2000.8.21 v1.6 - 使用一个析构函数(destructor),而不是__attribute__(destructor)

2000.11.19 v2.0 - 由Henner Zeller 重写,加入LD_PRELOAD和其它功能

2001.2.27 v2.1 - Henner 进一步更新:可选的线程安全选项,选择哪些条件会导致LeakTracer 终止(abort())程序,更好地跟踪对那些并非是分配出来的指针的释放动作

2001.3.2 v2.2 - Henner 更新:使用散列表来提升在大量分配内存时的性能

2001.6.13 v2.3 - 使得LT 更稳腚,在初始化(init)之前和销毁(destruction)之后被调用

2003.8.28 v2.4 - 在不允许“未对齐访问”的平台上提升魔力(MAGIC)

作者: Erwin Andreasen

Henner Zeller

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

Your opinions
Your name:Email:Website url:Opinion content:
- no title specified

HxLauncher: Launch Android applications by voice commands

 
Recent comments
2017年4月~2019年4月垃圾短信排行榜Posted at:Thu Sep 26 04:51:48 2024
Qt5.7文档翻译:QWebEngineCookieStore类,QWebEngineCookieStore ClassPosted at:Fri Aug 11 06:50:35 2023盲盒kill -9 18289 Grebe.20230517.211749.552.mp4