现在的位置: 首页 > 综合 > 正文

MemWatch USING

2013年12月04日 ⁄ 综合 ⁄ 共 2312字 ⁄ 字号 评论关闭

MemWatch

What is it?

Memwatch是一款针对C语言的内存检测工具。除了检查泄漏,memwatch还有基于它的一些其他用途。如果你想了解更多信息,可以参阅头文件(memwatch.h),和源码(memwatch.c)

获得最新版本

http://www.linkdata.se/sourcecode.html

ftp://ftp.linkdata.se/pub/memwatch/

工作原理

MemwatchC预处理把你程序中ANSIC内存分配函数替换成memwatch自定义的函数。这样可以记录所有分配的内存。

Memwatch不是很突显。除非定义了MEMWATCH,它会在预处理阶段从代码中移除所有memwatch的跟踪。

Memwatch通常把数据写到memwatch.log文件,但是也可以重写,详见I/O部分。

能在C++代码的中使用?

可以,但是不推荐。C++允许单个类的内存管理,但如果使用不当的话,预处理会引起类声明的破坏。

如果你需要测试这样的类,你可以尝试以下步骤。

首先,在memwatch源码中打开C++支持。如果没找不到C++支持,可能不应该使用。然后,在所有的源码中加上头文件memwatch.h,再加上以下的宏定义:

#definenew mwNew

#definedelete mwDelete

这样代码中调用newdelete的地方就会被mwNewmwDelete替换。确保memwatch.h中有C++支持。

线程安全

版本2.66基本支持多线程。如果需要使用Win32pthreads,需要显式的定义WIN32MW——PTHREADS

这会创建全局的线程锁,而且当memwatch进入全局内存链中会锁定。但这仍旧离公认的线程安全很远。

初始化和清除

为了能及时检测内存泄漏,memwatch需要做一些初始化和清理工作。mwInit()初始化memwatchmwTerm()终止memwatch。如果不调用mwInit()memwatch也会自动初始化。这种情况下,memwatch会调用atexit()mwTerm()放到注册队列。如果调用atexit()清理,memwatch可能会在程序完成前终止。出于安全考虑,请使用mwInit()mwTerm()

mwInit()mwTerm()是成对使用的,所以你可以多次调用mwInit(),但必须以mwTerm()结束。

这样程序会按可控制的方式终止,你也可以调用mwAbort()来代替mwTerm()mwAbort()会立马终止memwatch即使显示的调用mwTerm()

I/O操作

正常的操作,memwatch会生成一个memwatch.log的文件。有时,memwatch.log不会产生,但可能会生成memwatNN.log的文件,NN0199之间的一个数字。除此以外就没有别的日志文件了。

如果不想memwatch生成日志文件,你可以调用带“voidfunc(int
c)”
函数地址的mwSetOutFunc()函数。所有的输出会定向到func

当调用ASSERTVERIFY失败时,memwatch也有Abort/Retry/Ignore函数。默认函数会自动中止程序。你可以使用任何你想用的函数,如把“intfunc(const
char*)”
函数的地址传给mwSetAriFunc()。更多细节参考memwatch.h

TRACE/ASSERT/VERIFY

memwatch定义宏TRACEASSERTVERIFY。如果已经用了这些宏,memwatch2.61及其后续版本不会重写这些宏。Memwatch2.61及其后续版本通常也会定义mwTRACE,mwASSERTmwVERIFY这些宏,所以你可以用这些宏确保告诉memwatch2.61以前的版本可以重写已有的宏TRACEASSERTVERIFY。为了确保宏TRACEASSERTVERIFY被保存,你可以定义MW_NOTRACE,MW_NOASSERTMW_NOVERIFY。这些宏对memwatch所有版本都有效。

Howslow can you go?

memwatch会使程序变慢。大量的分配不会受到影响,但少量的分配会利用编译器small-allocator函数,因此会使程序的速度大大变慢。预计在最坏的情况下会减慢35倍。

如果用memwatch检查很多内存的填充,无论分配多少内存,程序都会减慢57倍。

压力测试

在内存较小的情况下,可以使用mwLimit()mwLimit()会限制分配的最大字节数。当超出限制时,分配就会失败,同时limit信息会写入日志。

当内存分配达到实际内存时,memwatch也会记录到日志。memwatch本身具有一定的保留内存,即使遇到最糟的情况也能继续运行。

捕捉乱写和其他脏的东西

乱写通常是由于指针没有初始化或者指针指向已经释放的内存。避免野指针最好的方法是在初始化的时候把指针赋值为NULL,在指针指向内存释放时,赋值为NULL

为了追踪没有初始化的指针,memwatch把内存填充固定值。最近分配的内存填充为0xFE。最近释放的内存填充成0xFD。所以如果你的程序崩溃了,最大的可能是因为你没有初始化分配的内存或者用了已经释放的内存。

由于野指针会破坏memwatch内部数据结构,memwatch用校验和,一些值的多个副本来修复破坏的数据结构。

如果你是一个偏执的人,可以使用mwIsReadAddr()mwIsSafeAddr()函数检查内存是否能够访问。这些都可以在ANSIC系统和Win32系统中实施。

抱歉!评论已关闭.