当前位置:嗨网首页>书籍在线阅读

14-mtrace

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

13.4.6 mtrace

mtrace是一个简单的实用程序,能够分析应用程序调用 malloc()realloc()free() 的情况,并输出报告。它便于使用,而且很可能会帮助你找出应用程序中的问题。和我们在本章前面介绍的其他用户空间工具一样,mtrace必须针对嵌入式架构进行配置和编译。mtrace安装在你的目标板上,是一个替换 malloc的程序库。应用程序通过一个特殊的函数调用来开启它的功能。你的嵌入式Linux发行版中应该包含mtrace软件包。

为了说明这个工具的使用,我们编写了一个简单的程序,它能够在一个简单的链表上创建动态数据。每个链表项目都是动态创建的,而且链表项目中的数据项目也是动态创建的。代码清单13-11显示了这个简单的链表结构:

代码清单13-11 简单的线性链表

353.png 每个链表项都是像下面这样通过调用 malloc() 动态创建的,之后被放置在链表的末尾:

354.png 每个链表项中的数据项(结构体中的 data_item ,大小不定)也是动态生成的,链表项在设置了这个数据项后才会被放置到链表的末尾。这样的话,每个链表项的创建调用了两次 malloc() ——一次是创建链表项本身(由刚刚显示的结构体 struct blist_s 所代表),一次是创建大小不定的数据项。编写程序时,我们在链表中创建了10000个项,而每个项中包含一个变长的字符串数据,结果是调用了20000次 malloc()

要使用mtrace,应用程序必须满足3个条件:

  • 源码文件中必须包含一个名为mcheck.h的头文件;
  • 应用程序必须调用函数 mtrace() 以安装处理程序;
  • 环境变量 MALLOC_TRACE 必须指定一个可写文件的名称,追踪数据会被写入这个文件中。

当这些条件都满足后,每当应用程序调用被追踪的某个函数( malloc()realloc()free() )时,都会在原始的追踪文件(由 MALLOC_TRACE 指定)中生成一行信息。这个文件中的追踪数据看上去像是这样:

355.png @ 标志表示这行追踪数据中包含一个地址或函数名。程序的执行地址显示在方括号中,值为0x80486ec。使用一个二进制工具或调试器,很容易就能将这个地址和某个函数关联起来。加号( + )表示调用了分配内存的函数。如果调用的是 free() 函数,则会显示一个减号。下一个字段是分配或释放的内存块虚拟地址。最后一个字段是内存块的大小,在调用内存分配函数时会包含这个参数。

这个数据格式对于用户来说并不十分友好。因此,mtrace软件包中包含了一个实用程序,它能够分析原始的追踪数据,并报告程序中前后不一致的地方。这个分析工具实际上是一个Perl脚本(文件名也是mtrace)。在最简单的情况下,这个Perl脚本只会打印一行消息:No memory leaks。代码清单13-12显示了当mtrace检测到内存泄漏时产生的输出信息。

代码清单13-12 mtrace 错误报告

356.png 可以看到,这个简单的工具可以帮助我在问题出现之前发现它们,或是在问题出现时找到它们。注意一下,该Perl脚本显示出了每次调用 malloc() 时的文件名和行号,但它们分配的内存却没有相应地调用 free() 来释放。要想释放分配的内存,则需要在可执行程序中包含调试信息,这些信息是在编译程序时通过传递 -g 标志给编译器生成的。如果脚本没有找到调试信息,它只会打印出调用 malloc() 的函数的地址。