Linux系统中找出并解决程序错误方法( 二 )


内存泄漏(即 malloc() 内存在对应的 free() 调用执行后永不被释放)和缓冲区溢出(例如对以前分配到某数组的内存进行写操作)是一些常见的问题 , 它们可能很难检测到 。这一部分将讨论几个调试工具 , 它们极大地简化了检测和找出内存问题的过程 。
MEMWATCH
MEMWATCH 由 Johan Lindh 编写 , 是一个开放源代码 C 语言内存错误检测工具 , 您可以自己下载它(请参阅本文后面部分的参考资料) 。只要在代码中添加一个头文件并在 gcc 语句中定义了 MEMWATCH 之后 , 您就可以跟踪程序中的内存泄漏和错误了 。MEMWATCH 支持 ANSI C , 它提供结果日志纪录 , 能检测双重释放(double-free)、错误释放(erroneous free)、没有释放的内存(unfreed memory)、溢出和下溢等等 。

CODE:#include "STDLIB.H"
#include "STDIO.H"
#include "memwatch.h"
int main(void)
{
char *ptr1;
char *ptr2;
ptr1 = malloc(512);
ptr2 = malloc(512);
ptr2 = ptr1;
free(ptr2);
free(ptr1);
}

清单 1. 内存样本(test1.c)
清单 1 中的代码将分配两个 512 字节的内存块 , 然后指向第一个内存块的指针被设定为指向第二个内存块 。结果 , 第二个内存块的地址丢失 , 从而产生了内存泄漏 。
现在我们编译清单 1 的 memwatch.c 。下面是一个 makefile 示例:

CODE:test1
gcc -DMEMWATCH -DMW_STDIO test1.c memwatch
c -o test1
当您运行 test1 程序后 , 它会生成一个关于泄漏的内存的报告 。清单 2 展示了示例 memwatch.log 输出文件 。

CODE:MEMWATCH 2.67 Copyright (C) 1992-1999 Johan Lindh
...
double-free: <4> test1.c(15), 0x80517b4 was freed from test1.c(14)
...
unfreed: <2> test1.c(11), 512 bytes at 0x80519e4
{FE FE FE FE FE FE FE FE FE FE FE FE ..............}
Memory usage statistics (global):
N)umber of allocations made: 2
L)argest memory usage : 1024
T)otal of all alloc() calls: 1024
U)nfreed bytes totals : 512

清单 2. test1 memwatch.log 文件
MEMWATCH 为您显示真正导致问题的行 。如果您释放一个已经释放过的指针 , 它会告诉您 。对于没有释放的内存也一样 。日志结尾部分显示统计信息 , 包括泄漏了多少内存 , 使用了多少内存 , 以及总共分配了多少内存 。
YAMD
YAMD 软件包由 Nate Eldredge 编写 , 可以查找 C 和 C中动态的、与内存分配有关的问题 。在撰写本文时 , YAMD 的最新版本为 0.32 。请下载 yamd-0.32.tar.gz(请参阅参考资料) 。执行 make 命令来构建程序;然后执行 make install 命令安装程序并设置工具 。
一旦您下载了 YAMD 之后 , 请在 test1.c 上使用它 。请删除 #include memwatch.h 并对 makefile 进行如下小小的修改:使用 YAMD 的 test1 。

CODE:gcc -g test1.c -o test1
清单 3 展示了来自 test1 上的 YAMD 的输出 。

CODE:YAMD version 0.32
Executable: /usr/src/test/yamd-0.32/test1
...
INFO: Normal allocation of this block
Address 0x40025e00, size 512
...
INFO: Normal allocation of this block
Address 0x40028e00, size 512
...
INFO: Normal deallocation of this block
Address 0x40025e00, size 512
...
ERROR: Multiple freeing At
free of pointer already freed
Address 0x40025e00, size 512
...
WARNING: Memory leak
Address 0x40028e00, size 512
WARNING: Total memory leaks:
1 unfreed allocations totaling 512 bytes
*** Finished at Tue ... 10:07:15 2002
Allocated a grand total of 1024 bytes 2 allocations
Average of 512 bytes per allocation
Max bytes allocated at one time: 1024
24 K alloced internally / 12 K mapped now / 8 K max
Virtual program size is 1416 K
End.

清单 3. 使用 YAMD 的 test1 输出
YAMD 显示我们已经释放了内存 , 而且存在内存泄漏 。让我们在清单 4 中另一个样本程序上试试 YAMD 。

推荐阅读