官網html
http://www.linkdata.se/sourcecode/memwatch/app
其功能以下官網介紹,挑選重點整理:ide
一、 號稱功能: 內存泄露檢測 (檢測未釋放內存, 即 動態內存開闢未釋放的狀況)工具
二、 檢測 屢次調用free, 和 free 錯誤地址this
三、 檢測內存訪問的 上越界 和 下越界spa
四、 檢測對野指針進行的寫操做3d
其餘內存檢測工具備 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!)code
下載工具後, 解壓查看其中主要文件爲 htm
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 代碼以下
/* ** 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!\n"); 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\n", p+50000); *(p+50000) = 0; } if( mwIsSafeAddr(p+30000,1) ) { TRACE("Killing byte at %p\n", p+30000); *(p+30000) = 0; } if( mwIsSafeAddr(p+1000,1) ) { TRACE("Killing byte at %p\n", p+1000); *(p+1000) = 0; } if( mwIsSafeAddr(p-100,1) ) { TRACE("Killing byte at %p\n", 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