⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memwatch.c

📁 程序代码使用说明: (1)所有源代码目录下都提供了Makefile(非Qt)
💻 C
📖 第 1 页 / 共 5 页
字号:
/*** MEMWATCH.C** Nonintrusive ANSI C memory leak / overwrite detection** Copyright (C) 1992-2003 Johan Lindh** All rights reserved.** Version 2.71	This file is part of MEMWATCH.    MEMWATCH is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    MEMWATCH is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with MEMWATCH; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA**** 920810 JLI   [1.00]** 920830 JLI   [1.10 double-free detection]** 920912 JLI   [1.15 mwPuts, mwGrab/Drop, mwLimit]** 921022 JLI   [1.20 ASSERT and VERIFY]** 921105 JLI   [1.30 C++ support and TRACE]** 921116 JLI   [1.40 mwSetOutFunc]** 930215 JLI   [1.50 modified ASSERT/VERIFY]** 930327 JLI   [1.51 better auto-init & PC-lint support]** 930506 JLI   [1.55 MemWatch class, improved C++ support]** 930507 JLI   [1.60 mwTest & CHECK()]** 930809 JLI   [1.65 Abort/Retry/Ignore]** 930820 JLI   [1.70 data dump when unfreed]** 931016 JLI   [1.72 modified C++ new/delete handling]** 931108 JLI   [1.77 mwSetAssertAction() & some small changes]** 940110 JLI   [1.80 no-mans-land alloc/checking]** 940328 JLI   [2.00 version 2.0 rewrite]**              Improved NML (no-mans-land) support.**              Improved performance (especially for free()ing!).**              Support for 'read-only' buffers (checksums)**              ^^ NOTE: I never did this... maybe I should?**              FBI (free'd block info) tagged before freed blocks**              Exporting of the mwCounter variable**              mwBreakOut() localizes debugger support**              Allocation statistics (global, per-module, per-line)**              Self-repair ability with relinking** 950913 JLI   [2.10 improved garbage handling]** 951201 JLI   [2.11 improved auto-free in emergencies]** 960125 JLI   [X.01 implemented auto-checking using mwAutoCheck()]** 960514 JLI   [2.12 undefining of existing macros]** 960515 JLI   [2.13 possibility to use default new() & delete()]** 960516 JLI   [2.20 suppression of file flushing on unfreed msgs]** 960516 JLI   [2.21 better support for using MEMWATCH with DLL's]** 960710 JLI   [X.02 multiple logs and mwFlushNow()]** 960801 JLI   [2.22 merged X.01 version with current]** 960805 JLI   [2.30 mwIsXXXXAddr() to avoid unneeded GP's]** 960805 JLI   [2.31 merged X.02 version with current]** 961002 JLI   [2.32 support for realloc() + fixed STDERR bug]** 961222 JLI   [2.40 added mwMark() & mwUnmark()]** 970101 JLI   [2.41 added over/underflow checking after failed ASSERT/VERIFY]** 970113 JLI   [2.42 added support for PC-Lint 7.00g]** 970207 JLI   [2.43 added support for strdup()]** 970209 JLI   [2.44 changed default filename to lowercase]** 970405 JLI   [2.45 fixed bug related with atexit() and some C++ compilers]** 970723 JLI   [2.46 added MW_ARI_NULLREAD flag]** 970813 JLI   [2.47 stabilized marker handling]** 980317 JLI   [2.48 ripped out C++ support; wasn't working good anyway]** 980318 JLI   [2.50 improved self-repair facilities & SIGSEGV support]** 980417 JLI	[2.51 more checks for invalid addresses]** 980512 JLI	[2.52 moved MW_ARI_NULLREAD to occur before aborting]** 990112 JLI	[2.53 added check for empty heap to mwIsOwned]** 990217 JLI	[2.55 improved the emergency repairs diagnostics and NML]** 990224 JLI	[2.56 changed ordering of members in structures]** 990303 JLI	[2.57 first maybe-fixit-for-hpux test]** 990516 JLI	[2.58 added 'static' to the definition of mwAutoInit]** 990517 JLI	[2.59 fixed some high-sensitivity warnings]** 990610 JLI	[2.60 fixed some more high-sensitivity warnings]** 990715 JLI	[2.61 changed TRACE/ASSERT/VERIFY macro names]** 991001 JLI	[2.62 added CHECK_BUFFER() and mwTestBuffer()]** 991007 JLI	[2.63 first shot at a 64-bit compatible version]** 991009 JLI	[2.64 undef's strdup() if defined, mwStrdup made const]** 000704 JLI	[2.65 added some more detection for 64-bits]** 010502 JLI   [2.66 incorporated some user fixes]**              [mwRelink() could print out garbage pointer (thanks mac@phobos.ca)]**				[added array destructor for C++ (thanks rdasilva@connecttel.com)]**				[added mutex support (thanks rdasilva@connecttel.com)]** 010531 JLI	[2.67 fix: mwMutexXXX() was declared even if MW_HAVE_MUTEX was not defined]** 010619 JLI	[2.68 fix: mwRealloc() could leave the mutex locked]** 020918 JLI	[2.69 changed to GPL, added C++ array allocation by Howard Cohen]** 030212 JLI	[2.70 mwMalloc() bug for very large allocations (4GB on 32bits)]** 030520 JLI	[2.71 added ULONG_LONG_MAX as a 64-bit detector (thanks Sami Salonen)]*/#define __MEMWATCH_C 1#ifdef MW_NOCPP#define MEMWATCH_NOCPP#endif#ifdef MW_STDIO#define MEMWATCH_STDIO#endif/************************************************************************* Include files***********************************************************************/#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <signal.h>#include <setjmp.h>#include <time.h>#include <limits.h>#include "memwatch.h"#ifndef toupper#include <ctype.h>#endif#if defined(WIN32) || defined(__WIN32__)#define MW_HAVE_MUTEX 1#include <windows.h>#endif#if defined(MW_PTHREADS) || defined(HAVE_PTHREAD_H)#define MW_HAVE_MUTEX 1#include <pthread.h>#endif/************************************************************************* Defines & other weird stuff***********************************************************************//*lint -save -e767 */#define VERSION     "2.71"         /* the current version number */#define CHKVAL(mw)  (0xFE0180L^(long)mw->count^(long)mw->size^(long)mw->line)#define FLUSH()     mwFlush()#define TESTS(f,l)  if(mwTestAlways) (void)mwTestNow(f,l,1)#define PRECHK      0x01234567L#define POSTCHK     0x76543210L#define mwBUFFER_TO_MW(p) ( (mwData*) (void*) ( ((char*)p)-mwDataSize-mwOverflowZoneSize ) )/*lint -restore */#define MW_NML      0x0001#ifdef _MSC_VER#define COMMIT "c"  /* Microsoft C requires the 'c' to perform as desired */#else#define COMMIT ""   /* Normal ANSI */#endif /* _MSC_VER */#ifdef __cplusplus#define CPPTEXT "++"#else#define CPPTEXT ""#endif /* __cplusplus */#ifdef MEMWATCH_STDIO#define mwSTDERR stderr#else#define mwSTDERR mwLog#endif#ifdef MW_HAVE_MUTEX#define MW_MUTEX_INIT()		mwMutexInit()#define MW_MUTEX_TERM()		mwMutexTerm()#define MW_MUTEX_LOCK()		mwMutexLock()#define MW_MUTEX_UNLOCK()	mwMutexUnlock()#else#define MW_MUTEX_INIT()#define MW_MUTEX_TERM()#define MW_MUTEX_LOCK()#define MW_MUTEX_UNLOCK()#endif/************************************************************************* If you really, really know what you're doing,** you can predefine these things yourself.***********************************************************************/#ifndef mwBYTE_DEFINED# if CHAR_BIT != 8#  error need CHAR_BIT to be 8!# elsetypedef unsigned char mwBYTE;#  define mwBYTE_DEFINED 1# endif#endif#if defined(ULONGLONG_MAX) || defined(ULLONG_MAX) || defined(_UI64_MAX) || defined(ULONG_LONG_MAX)# define mw64BIT 1# define mwROUNDALLOC_DEFAULT 8#else# if UINT_MAX <= 0xFFFFUL#  define mw16BIT 1#  define mwROUNDALLOC_DEFAULT	2# else#  if ULONG_MAX > 0xFFFFFFFFUL#   define mw64BIT 1#   define mwROUNDALLOC_DEFAULT	8#  else#   define mw32BIT 1#   define mwROUNDALLOC_DEFAULT	4#  endif# endif#endif/* mwROUNDALLOC is the number of bytes to *//* round up to, to ensure that the end of *//* the buffer is suitable for storage of *//* any kind of object */#ifndef mwROUNDALLOC# define mwROUNDALLOC mwROUNDALLOC_DEFAULT#endif#ifndef mwDWORD_DEFINED#if ULONG_MAX == 0xFFFFFFFFULtypedef unsigned long mwDWORD;#define mwDWORD_DEFINED "unsigned long"#endif#endif#ifndef mwDWORD_DEFINED#if UINT_MAX == 0xFFFFFFFFULtypedef unsigned int mwDWORD;#define mwDWORD_DEFINED "unsigned int"#endif#endif#ifndef mwDWORD_DEFINED#if USHRT_MAX == 0xFFFFFFFFULtypedef unsigned short mwDWORD;#define mwDWORD_DEFINED "unsigned short"#endif#endif#ifndef mwBYTE_DEFINED#error "can't find out the correct type for a 8 bit scalar"#endif#ifndef mwDWORD_DEFINED#error "can't find out the correct type for a 32 bit scalar"#endif/************************************************************************* Typedefs & structures***********************************************************************//* main data holding area, precedes actual allocation */typedef struct mwData_ mwData;struct mwData_ {    mwData*     prev;   /* previous allocation in chain */    mwData*     next;   /* next allocation in chain */    const char* file;   /* file name where allocated */    long        count;  /* action count */    long        check;  /* integrity check value */#if 0    long        crc;    /* data crc value */#endif    size_t      size;   /* size of allocation */    int         line;   /* line number where allocated */    unsigned    flag;   /* flag word */    };/* statistics structure */typedef struct mwStat_ mwStat;struct mwStat_ {    mwStat*     next;   /* next statistic buffer */    const char* file;    long        total;  /* total bytes allocated */    long        num;    /* total number of allocations */    long        max;    /* max allocated at one time */    long        curr;   /* current allocations */    int         line;    };/* grabbing structure, 1K in size */typedef struct mwGrabData_ mwGrabData;struct mwGrabData_ {    mwGrabData* next;    int         type;    char        blob[ 1024 - sizeof(mwGrabData*) - sizeof(int) ];    };typedef struct mwMarker_ mwMarker;struct mwMarker_ {    void *host;    char *text;    mwMarker *next;    int level;    };#if defined(WIN32) || defined(__WIN32__)typedef HANDLE          mwMutex;#endif#if defined(MW_PTHREADS) || defined(HAVE_PTHREAD_H)typedef pthread_mutex_t mwMutex;#endif/************************************************************************* Static variables***********************************************************************/static int      mwInited =      0;static int      mwInfoWritten = 0;static int      mwUseAtexit =   0;static FILE*    mwLog =         NULL;static int      mwFlushing =    0;static int      mwStatLevel =   MW_STAT_DEFAULT;static int      mwNML =         MW_NML_DEFAULT;static int      mwFBI =         0;static long     mwAllocLimit =  0L;static int      mwUseLimit =    0;static long     mwNumCurAlloc = 0L;static mwData*  mwHead = 		NULL;static mwData*  mwTail = 		NULL;static int		mwDataSize =	0;static unsigned char mwOverflowZoneTemplate[] = "mEmwAtch";static int		mwOverflowZoneSize = mwROUNDALLOC;static void     (*mwOutFunction)(int) = NULL;static int      (*mwAriFunction)(const char*) = NULL;static int      mwAriAction = MW_ARI_ABORT;static char     mwPrintBuf[MW_TRACE_BUFFER+8];static unsigned long mwCounter = 0L;static long     mwErrors =      0L;static int      mwTestFlags =   0;static int      mwTestAlways =  0;static FILE*    mwLogB1 =       NULL;static int      mwFlushingB1 =  0;static mwStat*  mwStatList = NULL;static long     mwStatTotAlloc = 0L;static long     mwStatMaxAlloc = 0L;static long     mwStatNumAlloc = 0L;static long     mwStatCurAlloc = 0L;static long     mwNmlNumAlloc = 0L;static long     mwNmlCurAlloc = 0L;static mwGrabData* mwGrabList = NULL;static long     mwGrabSize = 0L;static void *   mwLastFree[MW_FREE_LIST];static const char *mwLFfile[MW_FREE_LIST];static int      mwLFline[MW_FREE_LIST];static int      mwLFcur = 0;static mwMarker* mwFirstMark = NULL;static FILE*    mwLogB2 =       NULL;static int      mwFlushingB2 =  0;#ifdef MW_HAVE_MUTEXstatic mwMutex	mwGlobalMutex;#endif/************************************************************************* Static function declarations***********************************************************************/static void     mwAutoInit( void );static FILE*    mwLogR( void );static void     mwLogW( FILE* );static int      mwFlushR( void );static void     mwFlushW( int );static void     mwFlush( void );static void     mwIncErr( void );static void     mwUnlink( mwData*, const char* file, int line );static int      mwRelink( mwData*, const char* file, int line );static int      mwIsHeapOK( mwData *mw );static int      mwIsOwned( mwData* mw, const char* file, int line );static int      mwTestBuf( mwData* mw, const char* file, int line );static void     mwDefaultOutFunc( int );static void     mwWrite( const char* format, ... );static void     mwLogFile( const char* name );static size_t   mwFreeUp( size_t, int );static const void *mwTestMem( const void *, unsigned, int );static int      mwStrCmpI( const char *s1, const char *s2 );static int      mwTestNow( const char *file, int line, int always_invoked );static void     mwDropAll( void );static const char *mwGrabType( int type );static unsigned mwGrab_( unsigned kb, int type, int silent );static unsigned mwDrop_( unsigned kb, int type, int silent );static int      mwARI( const char* text );static void     mwStatReport( void );static mwStat*  mwStatGet( const char*, int, int );static void     mwStatAlloc( size_t, const char*, int );static void     mwStatFree( size_t, const char*, int );static int		mwCheckOF( const void * p );static void		mwWriteOF( void * p );static char		mwDummy( char c );#ifdef MW_HAVE_MUTEXstatic void		mwMutexInit( void );static void		mwMutexTerm( void );static void		mwMutexLock( void );static void		mwMutexUnlock( void );#endif/************************************************************************* System functions***********************************************************************/void mwInit( void ) {    time_t tid;    if( mwInited++ > 0 ) return;	MW_MUTEX_INIT();    /* start a log if none is running */    if( mwLogR() == NULL ) mwLogFile( "memwatch.log" );    if( mwLogR() == NULL ) {        int i;        char buf[32];        /* oops, could not open it! */        /* probably because it's already open */        /* so we try some other names */        for( i=1; i<100; i++ ) {            sprintf( buf, "memwat%02d.log", i );            mwLogFile( buf );            if( mwLogR() != NULL ) break;            }        }    /* initialize the statistics */    mwStatList = NULL;    mwStatTotAlloc = 0L;    mwStatCurAlloc = 0L;    mwStatMaxAlloc = 0L;    mwStatNumAlloc = 0L;	mwNmlCurAlloc = 0L;	mwNmlNumAlloc = 0L;	/* calculate the buffer size to use for a mwData */	mwDataSize = sizeof(mwData);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -