博主的新Blog地址:http://www.brantchen.com

欢迎訪问:)

linux下的測试工具真是少之又少,还不好用,近期试用了memwatch,感觉网上的介绍不太好,所以放在这里跟大家分享 。事实上大部分都是看的帮助,非常多地方翻译得不好还有错,请原谅指出最好看原文。假设转载或引用,请注明我的博客地址,谢谢。

1介绍

MemWatch由 Johan Lindh
编写,是一个开放源码 C 语言内存错误检測工具。MemWatch支持 ANSI C,它提供结果日志纪录,能检測双重释放(double-free)、错误释放(erroneous
free)、内存泄漏(unfreed memory)、溢出(Overflow)、下溢(Underflow)等等。

1.1 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能提供no-mans-land(NML)内存填充。no-mans-land将使用0xFC填充.当no-mans-land开启时,MemWatch转变释放的内存为NML填充状态。

1.2初始化和结束处理

一般来说,在程序中使用MemWatch的功能,须要手动加入mwInit()进行初始化,并用相应的mwTerm
()进行结束处理。

当然,假设没有手动调用mwInit(),MemWatch能自己主动初始化.假设是这样的情形,memwatch会使用atext()注冊mwTerm()用于atexit-queue.对于使用自己主动初始化技术有一个告诫;假设你手动调用atexit()以进行清理工作,memwatch可能在你的程序结束前就终止。为了安全起见,请显式使用mwInit()和mwTerm().

涉及的函数主要有:

mwInit()   mwTerm()   
mwAbort()

1.3 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()。后面在1.2使用一节会具体解说。

涉及的函数主要有:

mwTrace()         
mwPuts()        mwSetOutFunc() mwSetAriFunc()

mwSetAriAction()   mwAriHandler() 
mwBreakOut()

1.4 MemWatch对C++的支持

能够将MemWatch用于C++,可是不推荐这么做。请具体阅读memwatch.h中关于对C++的支持。

2使用

2.1为自己的程序提供MemWatch功能

Ø       在要使用MemWatch的.c文件里包括头文件"memwatch.h"

Ø       使用GCC编译(注意:不是链接)自己的程序时,增加-DMEMWATCH
-DMW_STDIO

如:gcc -DMEMWATCH -DMW_STDIO –o test.o–c test1.c

 

2.2使用MemWatch提供的功能

1)在程序中经常使用的MemWatch功能有:

Ø        mwTRACE(
const char* format_string, ... );

或TRACE( const char* format_string, ... );

Ø        mwASSERT(
int, const char*, const char*, int )

或ASSERT( int, const char*, const char*, int )

Ø        mwVERIFY(
int, const char*, const char*, int )

或VERIFY( int, const char*, const char*, int )

Ø        mwPuts(
const char* text )

Ø        ARI机制(mwSetAriFunc(int
(*func)(const char *)),

          mwSetAriAction(int action),

          mwAriHandler( const char* cause
))

Ø        mwSetOutFunc(void
(*func)(int))

Ø        mwIsReadAddr(const
void *p, unsigned len )

Ø        mwIsSafeAddr(void
*p, unsigned len )

Ø        mwStatistics(
int level )

Ø        mwBreakOut(
const char* cause)

2)mwTRACE,mwASSERT,mwVERIFY和mwPuts顾名思义,就不再赘述。仅须要注意的是,Memwatch定义了宏TRACE,   ASSERT
和 VERIFY.假设你已使用同名的宏,memwatch2.61及更高版本号的memwatch不会覆盖你的定义。MemWatch2.61及以后,定义了mwTRACE, mwASSERT和 mwVERIFY宏,这样,你就能确定使用的是memwatch的宏定义。2.61版本号前的memwatch会覆盖已存在的同名的TRACE,
ASSERT和 VERIFY定义。

当然,假设你不想使用MemWatch的这几个宏定义,能够定义MW_NOTRACE, MW_NOASSERT和
MW_NOVERIFY宏,这样MemWatch的宏定义就不起作用了。全部版本号的memwatch都遵照这个规则。

3)ARI机制即程序设置的“Abort,
Retry, Ignore选择陷阱。

mwSetAriFunc:

设置“Abort, Retry, Ignore”发生时的MemWatch调用的函数.当这样设置调用的函数地址时,实际的错误消息不会打印出来,但会作为一个參数进行传递。

假设參数传递NULL,ARI处理函数会被再次关闭。当ARI处理函数关闭后,
meewatch会自己主动调用有mwSetAriAction()指定的操作。

正常情况下,失败的ASSERT() or VERIFY()会中断你的程序。但这能够通过mwSetAriFunc()改变,即通过将函数"int
myAriFunc(const char *)"传给它实现。你的程序必须询问用户是否中断,重试或者忽略这个陷阱。返回2用于Abort, 1用于Retry,或者0对于Ignore。注意retry时,会导致表达式又一次求值.

MemWatch有个默认的ARI处理器。默认是关闭的,但你能通过调用mwDefaultAri()开启。注意这仍然会中止你的程序除非你定义MEMWATCH_STDIO同意MemWatch使用标准C的I/O流。

同一时候,设置ARI函数也会导致MemWatch不将ARI的错误信息写向标准错误输出,错误字符串而是作为'const
char *'參数传递到ARI函数.

mwSetAriAction:

假设没有ARI处理器被指定,设置默认的ARI返回值。默认是MW_ARI_ABORT

mwAriHandler:

这是个标准的ARI处理器,假设你喜欢就虽然用。它将错误输出到标准错误输出,并从标准输入获得输入。

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      /*
默认状态设置 */

mwBreakOut:

当某些情况MemWatch认为中断(break into)编译器更好时,就调用这个函数.假设你喜欢使用MemWatch,那么能够在这个函数上设置运行断点。

其它功能的使用,请參考源码的说明。

2.3分析日志文件

日志文件memwatch.log中包括的信息主要有下面几点:

Ø        測试日期

Ø        状态搜集器的信息

Ø        使用MemWatch的输出函数或宏(如TRACE等)的信息。

Ø        MemWatch捕获的错误信息

Ø        内存使用的全局信息统计,包含四点:1)分配了多少次内存
2)最大内存使用量3)分配的内存总量 4)为释放的内存总数

MemWatch捕获的错误记录在日志文件里的输出格式例如以下:

message: <sequence-number> filename(linenumber), information

2.4注意事项

mwInit()和mwTerm()是相应的.所以使用了多少次mwInit(),就须要调用多少次

mwTerm()用于终止MemWatch.

 

假设在流程中捕获了程序的异常中断,那么须要调用mwAbort()而不是

mwTerm()。即使有显示的调用mwTerm(),mwAbort()也将终止MemWatch。

MemWatch不能确保是线程安全的。假设你碰巧使用Wind32或者你使用了线程,作为2.66,是初步支持线程的。定义WIN32或者MW_PTHREADS以明白支持线程。这会导致一个全局相互排斥变量产生,同一时候当訪问全局内存链时,MemWatch会锁定相互排斥变量,但这远不能证明是线程安全的。

3结论

从MemWatch的使用能够得知,无法用于内核模块。由于MemWatch自身就使用了应用层的接口,而不是内核接口。可是,对于普通的应用层程序,我觉得还是比較实用,而且是开源的,能够自己改动代码实现;它能方便地查找内存泄漏,特别是提供的接口函数简单易懂,学习掌握非常easy,相应用层程序的单元測试会较适用。

博主的新Blog地址:http://www.brantchen.com

欢迎訪问:)

memwatch的使用的更多相关文章

  1. memwatch内存泄露检测工具

    工具介绍 官网 http://www.linkdata.se/sourcecode/memwatch/ 其功能如下官网介绍,挑选重点整理: 1. 号称功能: 内存泄露检测 (检测未释放内存, 即 动态 ...

  2. memwatch

    一.简介 memwatch可以跟踪程序中的内存泄漏和错误,能检测双重释放(double-free).错误释放(erroneous free).没有释放的内存(unfreed memory).溢出(Ov ...

  3. 【转】 memwatch使用说明书

    memwatch使用说明书 1.memwatch是什么?    memwatch是C语言的内存检测器.除了检测内存的功能外,它同样可以做其它的一些事情,而我们主要还是在于讲述它的基本功能.如果你真的想 ...

  4. Linux内存调试工具初探-MEMWATCH

    C 语言作为 Linux 系统上标准的编程语言给予了我们对动态内存分配很大的控制权.这种自由可能会导致严重的内存管理问题,可能导致程序崩溃或随时间的推移导致性能降级. 内存泄漏(即 malloc()  ...

  5. Linux C 编程内存泄露检測工具(二):memwatch

    Memwatch简单介绍 在三种检測工具其中,设置最简单的算是memwatch,和dmalloc一样,它能检測未释放的内存.同一段内存被释放多次.位址存取错误及不当使用未分配之内存区域.请往http: ...

  6. Linux内存调试工具初探-MEMWATCH(转)

    C 语言作为 Linux 系统上标准的编程语言给予了我们对动态内存分配很大的控制权.这种自由可能会导致严重的内存管理问题,可能导致程序崩溃或随时间的推移导致性能降级. 内存泄漏(即 malloc()  ...

  7. vld,Bounds Checker,memwatch,mtrace,valgrind,debug_new几种内存泄露检测工具的比较,Valgrind Cheatsheet

    概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的.复杂的应用程序中,内存泄漏是常见的问题.当以前分配的一片内存不再需要使用或无法访问时,但是却 ...

  8. linux 下C语言学习路线

    UNIX/Linux下C语言的学习路线.一.工具篇“公欲善其事,必先利其器”.编程是一门实践性很强的工作,在你以后的学习或工作中,你将常常会与以下工具打交道, 下面列出学习C语言编程常常用到的软件和工 ...

  9. Linux下调试程序方法

    您可以用各种方法来监控运行着的用户空间程序:可以为其运行调试器并单步调试该程序,添加打印语句,或者添加工具来分析程序.本文描述了几种可以用来调试在 Linux 上运行的程序的方法.我们将回顾四种调试问 ...

随机推荐

  1. lsh341999的资源

    懒得下载了,仔细研究: http://download.csdn.net/user/lsh341999/uploads/2

  2. javaee加密部署,tomcat使用自己的classloader解密【正解】

    [起因] 公司需要对一个web项目进行加密之后出售, 大家都知道的,class很好反编译, 所以需要对class文件先进行加密, 然后使用自己的classloader进行解密并加载. [步骤] 大概分 ...

  3. javascript 判断IOS版本号

    先来观察 iOS 的 User-Agent 串: iPhone 4.3.2 系统: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; ...

  4. java WEB Response重定向和缓存控制

    package cn.com; import java.io.IOException; import javax.servlet.ServletException; import javax.serv ...

  5. Python集成开发环境(Eclipse+Pydev)

    刚開始学习python,就用Editplus, Notepad++来写小程序, 后来接触了Sublime Text2.认为很不错,没事写写代码.就用编辑器Sublime Text2,最好再配搭一个ap ...

  6. leetcode先刷_Path Sum

    水的问题不解释,具有参数保持部和,当它到达一个叶子节点,推断是否与给予平等. 需要注意的是节点在树中的数目值它可以是正的或负.它不使用,修剪.有仅仅存在罐.因此,关于或代表最终结果的字. bool h ...

  7. 在Java中使用MD5和BASE64

    MD5: 在上一篇<Servlet的学习之Session(5)>中,为了能使获取的所有随机数都能有相同的位数,我们采用MD5获取随机数的消息摘要(或称数据指纹.数据摘要等等). MD5可以 ...

  8. Delphi 能不能从Ring 3进入Ring 0

    我发现了一篇发表在1999.11.29   b13版的     <令win32应用程序跳入系统层>东南大学   卢威   luwei@126.com     是用vc++嵌汇编做的,    ...

  9. Solaris 11的自动化安装(AI server)的搭建

    solaris 11 总体比solaris 10很多变动的地方,可以去官方网站上面学习:http://www.oracle.com/technetwork/server-storage/solaris ...

  10. 记一个手游app数据文件的破解

    出于一些非常猥琐的须要,同一时候自己也想做一些新奇的尝试,周末用了大半天时间破解了某款手游的数据文件. 过程比我预想的要顺利,主要原因还是我们开发者的懈怠.咳咳. 步骤例如以下: 下载安装包,解压,发 ...