Table of Contents
memwatch
Memwatch简介
在三种检测工具当中,设置最简单的算是memwatch,和dmalloc一样,
它能检测未释放的内存、同一段内存被释放多次、位址存取错误及不当使用未分配之内存区域。
请往
http://www.linkdata.se/sourcecode.html
下载最新版本的Memwatch。
MemWatch的内存处理
MemWatch将所有分配的内存用0xFE填充,所以,如果你看到错误的数据是用0xFE填充的,那就是你没有初始化数据。
例外是calloc(),它会直接把分配的内存用0填充。
MemWatch将所有已释放的内存用0xFD填充(zapped with 0xFD).
如果你发现你使用的数据是用0xFD填充的,那你就使用的是已释放的内存。
在这种情况,注意MemWatch会立即把一个”释放了的块信息” 填在释放了的数据前。
这个块包括关于内存在哪儿释放的信息,以可读的文本形式存放,格式 为”FBI<counter>filename(line)”。
如:”FBI<267>test.c(12)”.使用FBI会降 低free()的速度,所以默认是关闭的。使用mwFreeBufferInfo(1)开启。
初始化和结束处理
一般来说,在程序中使用MemWatch的功能,可以手动添加mwInit()进行初始化,并用对应的mwTerm ()进行结束处理。
一般不需要手动添加,memwatch会在第一个malloc的时候自动初始化,并在atexit中添加mwTerm。
如果自动初始化不合适或者程序比较特殊,请显式调用mwInit()和mwTerm().
比如,有的时候明明程序没有问题,而memwatch显示内存泄漏,这时就需要手动调用初始化和结束。
涉及的函数主要有:
mwInit() mwTerm() mwAbort()
MemWatch的I/O 操作
对于一般的操作,MemWatch创建memwatch.log文件。有时,该文件不能被创建;
MemWatch会试图创建memwatNN.log文件,NN在01~99之间。
如果你不能使用日志,或者不想使用,也没有问题。
只要使用类型为”void func(int c)”的参数调用mwSetOutFunc(),然后所有的输出都会按字节定向到该函数.
当ASSERT或者VERIFY失败时,MemWatch也有Abort/Retry/Ignore处理机制。
默认的处理机制没有I/O操作,但是会自动中断程序。
你可以使用任何其他Abort/Retry/Ignore的处理机制,只要以参数”void func(int c)”调用mwSetAriFunc()。
涉及的函数主要有:
mwTrace() mwPuts() mwSetOutFunc() mwSetAriFunc()
mwSetAriAction() mwAriHandler() mwBreakOut()
使用
在要使用MemWatch的.c文件中包含头文件”memwatch.h”
使用GCC编译(注意:不是链接)自己的程序时,加入-DMEMWATCH -DMW_STDIO
如:gcc -DMEMWATCH -DMW_STDIO –o test.o –c test1.c memwatch.c
使用MemWatch提供的功能
- mwTRACE,mwASSERT,mwVERIFY和mwPuts
- ARI机制即程序设置的“Abort, Retry, Ignore选择陷阱
- mwSetOutFunc
将输出转向调用者给出的函数(参数即函数地址)。参数为NULL,表示把输出写入日志文件memwatch.log.
- mwIsReadAddr
检查内存是否有读取的权限
- mwIsSafeAddr
检查内存是否有读、写的权限
- mwStatistics
设置状态搜集器的行为。对应的参数采用宏定义。
#define MW_STAT_GLOBAL 0 * 仅搜集全局状态信息 *
#define MW_STAT_MODULE 1 * 搜集模块级的状态信息 *
#define MW_STAT_LINE 2 * 搜集代码行级的状态信息 *
#define MW_STAT_DEFAULT 0 * 默认状态设置 *
Memwatch使用注意
Memwatch 的优点是无需特別配置,不需安装便能使用,但缺点是它会拖慢程序的运行速度,尤其是释放内存时它会作大量检查。
但它比mtrace和dmalloc多了 一项功能,就是能模拟系统内存不足的情況,
使用者只需用mwLimit(long num_of_byte)函数来限制程式的heap memory大小(以byte单位)。
最详细的使用说明(包括优点缺点,运行原理等)已在README中列出,本人强烈建议各位读者参考该文件。