3代码检测工具
介绍几个动态和静态代码检测工具,可以帮助发现代码BUG。
3.1 MEMWATCH
MEMWATCH 由 Johan Lindh 编写,是一个开放源代码 C 语言内存错误检测工具,您可以自己下载它(请参阅本文后面部分的 参考资料)。只要在代码中添加一个头文件并在 gcc 语句中定义了 MEMWATCH 之后,您就可以跟踪程序中的内存泄漏和错误了。MEMWATCH 支持 ANSI C,它提供结果日志纪录,能检测双重释放(double-free)、错误释放(erroneous free)、没有释放的内存(unfreed memory)、溢出和下溢等等。
清单 1. 内存样本(test1.c)
#include
#include
#include "memwatch.h"
int main(void)
{
char *ptr1;
char *ptr2;
ptr1 = malloc(512);
ptr2 = malloc(512);
ptr2 = ptr1;
free(ptr2);
free(ptr1);
}
清单 1 中的代码将分配两个 512 字节的内存块,然后指向第一个内存块的指针被设定为指向第二个内存块。结果,第二个内存块的地址丢失,从而产生了内存泄漏。
现在我们编译清单 1 的 memwatch.c。下面是一个 makefile 示例:
test1 gcc -DMEMWATCH -DMW_STDIO test1.c memwatch.c -o test1
当您运行 test1 程序后,它会生成一个关于泄漏的内存的报告。清单 2 展示了示例 memwatch.log 输出文件。
清单 2. test1 memwatch.log 文件 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
MEMWATCH 为您显示真正导致问题的行。如果您释放一个已经释放过的指针,它会告诉您。对于没有释放的内存也一样。日志结尾部分显示统计信息,包括泄漏了多少内存,使用了多少内存,以及总共分配了多少内存。
注意:我发现我们写的程序在使用这个工具时,必须要捕捉异常信号,比如“ctrl+c”,”killall”,内存异常等,并且捕捉后在main函数中return,才能够参数内存日志文件memwatch.log。
另外由于malloc函数我们进行过封装,所以,这个工具必须和我们的lib_base动态库配合使用。
同样可以调试内存的工具如:YAMD,valgrind,可以参考培训文件夹中相关内容。Valgrind功能相对来说强大一些,可以查看内存越界等。但是好像所有的工具都无法检查局部变量(局部数组)的越界问题。
3.2 resourcewatch
资源检测工具是我们公司自己开发的一个工具。所谓的资源,就是计算机中数量有限、有用的东西:包括内存、socket套接字、文件句柄、二叉树句柄、数据库连接句柄、数据库数据集、fifo列表等。
资源基本的思想和memwatch一样。为每种资源类型申请一个二叉树,然后将资源申请和函数用资源检测资源申请和释放函数替换:
int socket(int port);
int rw_socket(int port, const char *file, int line);
#define socket(port) rw_socket(port, __FILE__, __LINE__)
这样在申请资源的时候,添加一个二叉树的节点,记录申请的资源值,以及文件名,行号。之后在资源释放的时候根据资源的值,删除二叉树的节点。在程序结束的时候,调用资源使用情况的打印函数,打印出未释放,多重释放的资源的文件名和行号,便于定位问题。
系列文章: