• memwatch内存泄露检测工具


    工具介绍

    官网

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

    其功能如下官网介绍,挑选重点整理:

    1、 号称功能: 内存泄露检测 (检测未释放内存, 即 动态内存开辟未释放的情况)

    2、 检测 多次调用free, 和 free 错误地址

    3、 检测内存访问的 上越界 和 下越界

    4、 检测对野指针进行的写操作

    其他内存检测工具有 mtrace valgrind 参考 http://www.cnblogs.com/honglihua8688/p/3727944.html

    A memory leak detection tool. Basically, you add a header file to your souce code files, and compile with MEMWATCH defined or not. The header file MEMWATCH.H contains detailed instructions. This is a list of some of the features present in version 2.71:
    - ANSI C
    - Logging to file or user function using TRACE() macro
    - Fault tolerant, can repair it’s own data structures
    - Detects double-frees and erroneous free’s
    - Detects unfreed memory
    - Detects overflow and underflow to memory buffers
    - Can set maximum allowed memory to allocate, to stress-test app
    - ASSERT(expr) and VERIFY(expr) macros
    - Can detect wild pointer writes
    - Support for OS specific address validation to avoid GP’s (segmentation faults)
    - Collects allocation statistics on application, module or line level
    - Rudimentary support for threads (see FAQ for details)
    - Rudimentary support for C++ (disabled by default, use with care!)

    工具使用

    下载工具后, 解压查看其中主要文件为 

        memwatch.h
        memwatch.c
        test.c

        Makefile

    http://www.linkdata.se/downloads/sourcecode/memwatch/memwatch-2.71.tar.gz

    直接执行make命令, 则会报错, 需要注释掉 最后一行, 开发者想让使用者通过 test.c 熟悉注释, 通过注释了解使用方法

    /* Comment out the following line to compile.
    #error "Hey! Don't just compile this program, read the comments first!"
    */

    make && ./test 则发现 此文件夹下多了一个log文件

        memwatch.log

    --------------------------------------------------------------------------------------

    可见使用memwatch很方便, 只需要将 memwatch.c 和memwatch.h移植到你的待检测程序代码中

    通过makefile将 memwatch编译进去,需要关注的是, 编译时加上-DMEMWATCH -DMW_STDIO

    $(CC) -DMEMWATCH -DMW_STDIO test.c memwatch.c -o test

    test.c demo

    test.c 代码如下

    /*
    **  NOTE: Running this program in a Win32 or Unix environment
    **  will probably result in a segmentation fault or protection
    **  error. These errors may be caused by MEMWATCH when it is
    **  looking at memory to see if it owns it, or may be caused by
    **  the test program writing to memory it does not own.
    **
    **  MEMWATCH has two functions called 'mwIsReadAddr()' and
    **  'mwIsSafeAddr()', which are system-specific.
    **  If they are implemented for your system, and works
    **  correctly, MEMWATCH will identify garbage pointers and
    **  avoid causing segmentation faults, GP's etc.
    **
    **  If they are NOT implemented, count on getting the core
    **  dumped when running this test program! As of this writing,
    **  the safe-address checking has been implemented for Win32
    **  and ANSI-C compliant systems. The ANSI-C checking traps
    **  SIGSEGV and uses setjmp/longjmp to resume processing.
    **
    **  Note for Win95 users: The Win32 IsBadReadPtr() and its
    **  similar functions can return incorrect values. This has
    **  not happened under WinNT, though, just Win95.
    **
    **  991009 Johan Lindh
    **
    */
    
    #include <stdio.h>
    #include <signal.h>
    #include "memwatch.h"
    
    #ifndef SIGSEGV
    #error "SIGNAL.H does not define SIGSEGV; running this program WILL cause a core dump/crash!"
    #endif
    
    #ifndef MEMWATCH
    #error "You really, really don't want to run this without memwatch. Trust me."
    #endif
    
    #if !defined(MW_STDIO) && !defined(MEMWATCH_STDIO)
    #error "Define MW_STDIO and try again, please."
    #endif
    
    int main()
    {
        char *p;
    
        /* Collect stats on a line number basis */
        mwStatistics( 2 );
    
        /* Slows things down, but OK for this test prg */
        /* mwAutoCheck( 1 ); */
    
        TRACE("Hello world!
    ");
    
        p = malloc(210);
        free(p);
        p = malloc(20);
        p = malloc(200);    /* causes unfreed error */
        p[-1] = 0;          /* causes underflow error */
        free(p);
    
        p = malloc(100);
        p[ -(int)(sizeof(long)*8) ] = -1; /* try to damage MW's heap chain */
        free( p ); /* should cause relink */
    
        mwSetAriFunc( mwAriHandler );
        ASSERT(1==2);
    
        mwLimit(1000000);
        mwNoMansLand( MW_NML_ALL );
    
        /* These may cause a general protection fault (segmentation fault) */
        /* They're here to help test the no-mans-land protection */
        if( mwIsSafeAddr(p+50000,1) ) {
            TRACE("Killing byte at %p
    ", p+50000);
            *(p+50000) = 0;
            }
        if( mwIsSafeAddr(p+30000,1) ) {
            TRACE("Killing byte at %p
    ", p+30000);
            *(p+30000) = 0;
            }
        if( mwIsSafeAddr(p+1000,1) ) {
            TRACE("Killing byte at %p
    ", p+1000);
            *(p+1000) = 0;
            }
        if( mwIsSafeAddr(p-100,1) ) {
            TRACE("Killing byte at %p
    ", p-100);
            *(p-100) = 0;
            }
    
        /* This may cause a GP fault as well, since MW data buffers  */
        /* have been damaged in the above killing spree */
        CHECK();
    
        p = malloc(12000);
        p[-5] = 1;
        p[-10] = 2;
        p[-15] = 3;
        p[-20] = 4;
    
        /* This may cause a GP fault since MW's buffer list may have */
        /* been damaged by above killing, and it will try to repair it. */
        free(p);
    
    	p = realloc(p,10);	/* causes realloc: free'd from error */
    
        /* May cause GP since MW will inspect the memory to see if it owns it. */
        free( (void*)main );
        
        return 0;
    }
    
    /* Comment out the following line to compile. 
    #error "Hey! Don't just compile this program, read the comments first!"
    */

    memwatch.log内容, 如下粗体字标注, 有泄露检测结果 和 越界检测结果

    ============= MEMWATCH 2.71 Copyright (C) 1992-1999 Johan Lindh =============
    
    Started at Wed Jul 15 22:04:06 2015
    
    Modes: __STDC__ 64-bit mwDWORD==(unsigned long)
    mwROUNDALLOC==8 sizeof(mwData)==32 mwDataSize==32
    
    statistics: now collecting on a line basis
    Hello world!
    underflow: <5> test.c(62), 200 bytes alloc'd at <4> test.c(60)
    assert trap: <8> test.c(69), 1==2
    assert trap: <8> IGNORED - execution continues
    limit: old limit = none, new limit = 1000000 bytes
    grabbed: all allowed memory to no-mans-land (976 kb)
    Killing byte at 0x84496f0
    Killing byte at 0x84448d0
    Killing byte at 0x843d788
    Killing byte at 0x843d33c
    check: <8> test.c(95), checking chain alloc nomansland 
    check: <8> test.c(95), complete; no errors
    internal: <10> test.c(105), checksum for MW-0x85331f8 is incorrect
    underflow: <10> test.c(105), 0 bytes alloc'd at <9> test.c(865)
    overflow: <10> test.c(105), 0 bytes alloc'd at <9> test.c(865)
    internal: <10> test.c(107), no-mans-land MW-0x85331f8 is corrupted
    realloc: <10> test.c(107), 0x8533220 was freed from test.c(105)
    WILD free: <11> test.c(110), unknown pointer 0x8048a3b
    
    Stopped at Wed Jul 15 22:04:21 2015
    
    wild pointer: <11> no-mans-land memory hit at 0x84496f0
    wild pointer: <11> no-mans-land memory hit at 0x84448d0
    wild pointer: <11> no-mans-land memory hit at 0x843d788
    dropped: all no-mans-land memory (976 kb)
    unfreed: <3> test.c(59), 20 bytes at 0x843d1d0  	{FE FE FE FE FE FE FE FE FE FE FE FE FE FE FE FE ................}
    
    Memory usage statistics (global):
     N)umber of allocations made: 5
     L)argest memory usage      : 12020
     T)otal of all alloc() calls: 12530
     U)nfreed bytes totals      : 12020
    
    Memory usage statistics (detailed):
     Module/Line                                Number   Largest  Total    Unfreed 
      %s
                                           0        0        0        -100    
      64                                        0        0        0        -100    
     test.c                                     5        12120    12530    12120   
      865                                       0        0        0        0       
      97                                        1        12000    12000    12000   
      64                                        1        100      100      100     
      60                                        1        200      200      0       
      59                                        1        20       20       20      
      57                                        1        210      210      0       
  • 相关阅读:
    Java基础模拟LinkedList的双向链表结构
    对thrift版本降级(mac)
    通信技术类网站
    Arista和他的EOS
    程序员的英文能力培养
    挖掘时间的价值
    写作的方法论
    SRv6相关资源汇总
    你不必有自己的写作优势领域
    20192416汇编语言学习总结
  • 原文地址:https://www.cnblogs.com/lightsong/p/4649800.html
Copyright © 2020-2023  润新知