【转】 memwatch使用说明书
memwatch使用说明书
1.memwatch是什么?
memwatch是C语言的内存检测器。除了检测内存的功能外,它同样可以做其它的一些事情,而我们主要还是在于讲述它的基本功能。如果你真的想要知道所有相关的具体细节,可详细查看头文件memwatch.h以及源代码。那里面有具体且详细的注释说明。
2.如何获取最新的版本?
http://www.linkdata.se/sourcecode.html
ftp://ftp.linkdata.se/pub/memwatch/
3.它是如何工作的?
它使用C于处理器的功能,memwatch使用它自己定义的功能函数取代所有在你的程序中用ANSI C定义的内存分配函数,memwatch的内存分配函数包含了了所有的分配记录信息。
memwatch功能默认不是开启的,除非定义了MEMWATCH,否则在代码中不会跟踪相关的内存使用情况。
memwatch通常将它的数据写入到memwatch.log文件中,但它也可以被重定向。稍后,看I/O部分。
4.我们是否能在C++源码中使用?
答案是可以的,但是我们并不推荐使用。C++允许私有的类去管理自己的内存。如果处理器使用memwatch功能不恰当的话,可能会引起一些意想不到的结果。
如果你没有这样的类,或者你有但还是想测试一下memwatch的话,你可以尝试一下。
首先,在memwatch中启用支持C++的代码。如果你不能找到,可能是不应该使用。然后,在你的源代码中,在所有的头文件中包含以下的定义:
#define new mwNew
#define delete mwDelete
如此,在调用new及delete函数的时候,会被定向到memwatch中。同时,也请务必阅读所有在memwatch.h中关于支持C++的文本。
5.使用它,线程安全吗?
对此,我表示怀疑。在2.66版本中,有初步支持线程。如果你碰巧使用了Win32或者拥有线程,请定义WIN32或MW_PTHREADS来声明。
6.初始化及清除
为了能够及时的工作,memwatch需要做一些启动及初始化的工作。mwInit()初始化memwatch,而mwTerm()终止它。如果你没有自己调用mwInit()的话,memwatch也可以自动初始化。这样的话,memwatch就要使用atexit()注册mwTerm()到atexit队列中。
如果你自己使用了atexit()去作清除工作,自动初始化技术会有一个警告。memwatch可能会在程序完成前已经终止。处于安全的考虑,请使用mwInit()和mwTerm()。
在一个程序终止可控的方式下,你可能要使用mwAbort()来替代mwTerm()。mwAbort()将会停止memwatch,即使还有未处理的mwTerm()。
7.I/O操作
在正常操作的情况下,memwatch会创建一个名叫memwatch.log的文件。但有的时候,memwatch.log文件并不能被创建。此时,memwatch会尝试创建命名类似memwatNN.log的文件,其中NN是01到99之间的数字。如果还是失败,则没有log文件。
如果你不能使用log文件,或者不希望使用,不用担心,可以使用参数为“int
func(const char*)”的mwSetOutFunc()函数,这样所有的输出都会以字符的形式重定向到那里。
当使用 ASSERT或VERIFY失败时,memwatch同样拥有中止/重试/忽略处理功能。默认的处理程序没有I/O相关的操作,但会自动终止程序。你可以使用你希望的任何处理函数,仅需要将"int
func(const char*)"的地址传递给mwSetAriFunc()。更多的细节,请参考memwatch.h。
8.中止/重试/忽略宏定义
memwatch定义了中止/重试/忽略相关的宏。如果你已经使用了这些宏,memwatch2.61及以上版本也会定义宏mwTRACE,mwASSERT和mwVERIFY,所以你可以放心的使用这些。
为了确保现有这些宏定义是被保留的,你可以定义MW_NOTRACE,MW_NOASSERT和
MW_NOVERIFY。所有的memwatch版本都会遵循这些原则。
9.系统会如何变慢?
memwatch会使系统速度减慢。大的内存分配不会影响到,你可以作一些测试,但小的内存分配将使用编译器的分配功能。最坏的情况,速度变慢3-5倍。
释放的时候,更糟糕。memwatch在释放内存的时候,将会检测更多的东西。速度变慢为5-7倍,不管内存是多大。
10.应用程序的压力测试
在模拟低内存使用环境的时候可以使用mwLimit()。mwLimit()使用最大数量的字节分配,当限制被击穿的时候,分配请求将会失败,相关限制的信息将会被记录。
如果碰到一个真正的低内存情况,memwatch log文件会记录这一切。memwatch本身有一些保留内存,这样即使是在最恶劣的条件下,它也可以正常运行。
11.追踪野指针写入和其它令人讨厌的事情
野指针写入通常是使用没有初始化的指针引起的,或者是已经初始化,但指针所指向的内存已改变或者已被释放。避免该类情况最好的办法就是始终将指针初始化为NULL,在释放完内存的时候,将指针同样指向NULL。
为了帮助追踪未初始化的指针,memwatch将所有的内存赋予了一些确定的值。当分配内存的时候包含0xFE,当释放内存的时候包含0xFD。所以如果你的程序崩溃时使用memwatch而不是没有memwatch,这很可能是你没有初始化你所分配的内存,或者使用了已经被释放掉的内存区。
在这种情况下,野指针会破坏memwatch的内部数据结构。memwatch采用校验,某些数据多次备份的方式,这样也可以修复它自己的数据结构。
如果你是一个偏执的人,作为一个程序员你应该这样,你可以使用memwatch的mwIsReadAddr()和mwIsSafeAddr()两个函数来检测可访问的内存。在ANSI C系统及Win32系统下,都是可执行的。仅需要把mwASSERT()放在需要测试的地方,然后忘记它。
12.我可以帮忙吗?
好的,可以。例如,我喜欢memwatch编译时没有任何的警告及错误。如果你使用的是兼容ANSI C的编译器,且有警告或错误,如果可以的话,请给我发邮件,告诉我细节及解决这些问题的方法。
其它的事情你也可以做,如果你决定使用memwatch,请发邮件告诉我你项目的名字或URL(如果可以的话),硬件,操作系统,编译器,及使用者。接着,我会在memwatch使用者列表中更新信息。
(http://www.linkdata.se/memwatchusers.html)
13.使用memwatch的五大问题
a.当编译的时候没有使用MEMWATCH。症状:memwatch尽职尽责地禁用本身。治愈:尝试在命令行中加入-DMEMWATCH。
b.在当前目录下没有写的权限。症状:好似memwatch不能正常工作。治愈:使用mwSetOutFunc()重定向输出。
c.在所有的头文件中忘记添加memwatch.h。症状:会有"WILD free"和"unfreed"信息。治愈:确保包括了memwatch.h。
d.当使用atexit()时依靠自动初始化。症状:导致有"unfreed"和"WILD free"信息。治愈:使用Use mwInit()和mwTerm()。
e.将一个不是使用memwatch分配的指针传递给memwatch的free函数。症状:导致一个"WILD free"的错误信息。治愈:包括memwatch.h到相应的文件中,或者使用mwFree_()来释放。
作者:txgcwm
时间:2012-2-25 17:59
备注:转载请说明出处
原文链接:http://blog.chinaunix.net/uid-25885064-id-3082686.html