#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"
#include <ctype.h>
Go to the source code of this file.
Classes | |
struct | mwData_ |
struct | mwStat_ |
struct | mwGrabData_ |
struct | mwMarker_ |
Defines | |
#define | __MEMWATCH_C 1 |
#define | VERSION "2.71" |
#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 ) ) |
#define | MW_NML 0x0001 |
#define | COMMIT "" |
#define | CPPTEXT "" |
#define | mwSTDERR mwLog |
#define | MW_MUTEX_INIT() |
#define | MW_MUTEX_TERM() |
#define | MW_MUTEX_LOCK() |
#define | MW_MUTEX_UNLOCK() |
#define | mw16BIT 1 |
#define | mwROUNDALLOC_DEFAULT 2 |
#define | mwROUNDALLOC mwROUNDALLOC_DEFAULT |
#define | AIPH() if( always_invoked ) { mwWrite("autocheck: <%ld> %s(%d) ", mwCounter, file, line ); always_invoked = 0; } |
Typedefs | |
typedef mwData_ | mwData |
typedef mwStat_ | mwStat |
typedef mwGrabData_ | mwGrabData |
typedef mwMarker_ | mwMarker |
Functions | |
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) |
void | mwInit (void) |
void | mwAbort (void) |
void | mwTerm (void) |
void | mwStatistics (int level) |
void | mwAutoCheck (int onoff) |
void | mwSetOutFunc (void(*func)(int)) |
int | mwTest (const char *file, int line, int items) |
int | mwTestBuffer (const char *file, int line, void *p) |
void | mwBreakOut (const char *cause) |
void * | mwMark (void *p, const char *desc, const char *file, unsigned line) |
void * | mwUnmark (void *p, const char *file, unsigned line) |
int | mwAriHandler (const char *estr) |
void | mwSetAriFunc (int(*func)(const char *)) |
void * | mwMalloc (size_t size, const char *file, int line) |
void * | mwRealloc (void *p, size_t size, const char *file, int line) |
char * | mwStrdup (const char *str, const char *file, int line) |
void | mwFree (void *p, const char *file, int line) |
void * | mwCalloc (size_t a, size_t b, const char *file, int line) |
void | mwFree_ (void *p) |
void * | mwMalloc_ (size_t size) |
void * | mwRealloc_ (void *p, size_t size) |
void * | mwCalloc_ (size_t a, size_t b) |
void | mwFlushNow (void) |
void | mwDoFlush (int onoff) |
void | mwLimit (long lim) |
void | mwSetAriAction (int action) |
int | mwAssert (int exp, const char *exps, const char *fn, int ln) |
int | mwVerify (int exp, const char *exps, const char *fn, int ln) |
void | mwTrace (const char *format,...) |
unsigned | mwGrab (unsigned kb) |
unsigned | mwDrop (unsigned kb) |
void | mwNoMansLand (int level) |
int | mwIsReadAddr (const void *p, unsigned len) |
int | mwIsSafeAddr (void *p, unsigned len) |
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 |
#define __MEMWATCH_C 1 |
Definition at line 97 of file KalFitMemLeak.c.
#define CHKVAL | ( | mw | ) | (0xFE0180L^(long)mw->count^(long)mw->size^(long)mw->line) |
Definition at line 140 of file KalFitMemLeak.c.
Referenced by mwIsOwned(), mwMalloc(), and mwTestBuf().
#define COMMIT "" |
#define CPPTEXT "" |
#define FLUSH | ( | ) | mwFlush() |
Definition at line 141 of file KalFitMemLeak.c.
Referenced by mwAbort(), mwAssert(), mwDrop_(), mwFlushR(), mwFree(), mwGrab_(), mwIncErr(), mwInit(), mwLimit(), mwLogR(), mwMalloc(), mwRealloc(), mwRelink(), mwStatReport(), mwStrdup(), mwTrace(), mwVerify(), and mwWrite().
#define mw16BIT 1 |
Definition at line 199 of file KalFitMemLeak.c.
#define MW_MUTEX_INIT | ( | ) |
#define MW_MUTEX_LOCK | ( | ) |
Definition at line 176 of file KalFitMemLeak.c.
Referenced by mwAssert(), mwCalloc_(), mwFree(), mwFree_(), mwMalloc(), mwMalloc_(), mwRealloc(), mwRealloc_(), mwSetAriAction(), mwStrdup(), mwTrace(), and mwVerify().
#define MW_MUTEX_TERM | ( | ) |
#define MW_MUTEX_UNLOCK | ( | ) |
Definition at line 177 of file KalFitMemLeak.c.
Referenced by mwAssert(), mwCalloc_(), mwFree(), mwFree_(), mwMalloc(), mwMalloc_(), mwRealloc(), mwRealloc_(), mwSetAriAction(), mwStrdup(), mwTrace(), and mwVerify().
#define MW_NML 0x0001 |
Definition at line 148 of file KalFitMemLeak.c.
Referenced by mwAbort(), mwFree(), mwFreeUp(), mwRealloc(), and mwTestNow().
#define mwBUFFER_TO_MW | ( | p | ) | ( (mwData*) (void*) ( ((char*)p)-mwDataSize-mwOverflowZoneSize ) ) |
Definition at line 145 of file KalFitMemLeak.c.
Referenced by mwFree(), mwRealloc(), and mwTestBuffer().
#define mwROUNDALLOC mwROUNDALLOC_DEFAULT |
#define mwROUNDALLOC_DEFAULT 2 |
Definition at line 200 of file KalFitMemLeak.c.
#define mwSTDERR mwLog |
Definition at line 165 of file KalFitMemLeak.c.
Referenced by mwAbort(), mwARI(), mwAssert(), mwBreakOut(), mwLogR(), and mwVerify().
#define POSTCHK 0x76543210L |
Definition at line 144 of file KalFitMemLeak.c.
#define PRECHK 0x01234567L |
Definition at line 143 of file KalFitMemLeak.c.
#define TESTS | ( | f, | |||
l | ) | if(mwTestAlways) (void)mwTestNow(f,l,1) |
Definition at line 142 of file KalFitMemLeak.c.
Referenced by mwAssert(), mwCalloc_(), mwDrop(), mwDropAll(), mwFree(), mwFree_(), mwGrab(), mwLimit(), mwMalloc(), mwMalloc_(), mwMark(), mwNoMansLand(), mwRealloc(), mwRealloc_(), mwSetAriAction(), mwTrace(), and mwVerify().
#define VERSION "2.71" |
Definition at line 254 of file KalFitMemLeak.c.
typedef struct mwGrabData_ mwGrabData |
Definition at line 282 of file KalFitMemLeak.c.
Definition at line 289 of file KalFitMemLeak.c.
Definition at line 270 of file KalFitMemLeak.c.
void mwAbort | ( | void | ) |
Definition at line 517 of file KalFitMemLeak.c.
References mwData_::count, mwData_::file, mwData_::flag, FLUSH, mwMarker_::host, genRecEmupikp::i, ganga-rec::j, mwData_::line, mw, MW_MUTEX_TERM, MW_NML, MW_VAL_NML, mwCheckOF(), mwDataSize, mwDropAll(), mwErrors, mwFirstMark, mwFlushW(), mwHead, mwInited, mwIsOwned(), mwLogFile(), mwNmlCurAlloc, mwNmlNumAlloc, mwOverflowZoneSize, mwStatReport(), mwSTDERR, mwTail, mwTestMem(), mwUnlink(), mwWrite(), mwMarker_::next, mwData_::size, and mwMarker_::text.
Referenced by mwInit(), and mwTerm().
00517 { 00518 mwData *mw; 00519 mwMarker *mrk; 00520 char *data; 00521 time_t tid; 00522 int c, i, j; 00523 int errors; 00524 00525 tid = time( NULL ); 00526 mwWrite( "\nStopped at %s\n", ctime( &tid) ); 00527 00528 if( !mwInited ) 00529 mwWrite( "internal: mwAbort(): MEMWATCH not initialized!\n" ); 00530 00531 /* release the grab list */ 00532 mwDropAll(); 00533 00534 /* report mwMarked items */ 00535 while( mwFirstMark ) { 00536 mrk = mwFirstMark->next; 00537 mwWrite( "mark: %p: %s\n", mwFirstMark->host, mwFirstMark->text ); 00538 free( mwFirstMark->text ); 00539 free( mwFirstMark ); 00540 mwFirstMark = mrk; 00541 mwErrors ++; 00542 } 00543 00544 /* release all still allocated memory */ 00545 errors = 0; 00546 while( mwHead != NULL && errors < 3 ) { 00547 if( !mwIsOwned(mwHead, __FILE__, __LINE__ ) ) { 00548 if( errors < 3 ) 00549 { 00550 errors ++; 00551 mwWrite( "internal: NML/unfreed scan restarting\n" ); 00552 FLUSH(); 00553 mwHead = mwHead; 00554 continue; 00555 } 00556 mwWrite( "internal: NML/unfreed scan aborted, heap too damaged\n" ); 00557 FLUSH(); 00558 break; 00559 } 00560 mwFlushW(0); 00561 if( !(mwHead->flag & MW_NML) ) { 00562 mwErrors++; 00563 data = ((char*)mwHead)+mwDataSize; 00564 mwWrite( "unfreed: <%ld> %s(%d), %ld bytes at %p ", 00565 mwHead->count, mwHead->file, mwHead->line, (long)mwHead->size, data+mwOverflowZoneSize ); 00566 if( mwCheckOF( data ) ) { 00567 mwWrite( "[underflowed] "); 00568 FLUSH(); 00569 } 00570 if( mwCheckOF( (data+mwOverflowZoneSize+mwHead->size) ) ) { 00571 mwWrite( "[overflowed] "); 00572 FLUSH(); 00573 } 00574 mwWrite( " \t{" ); 00575 j = 16; if( mwHead->size < 16 ) j = (int) mwHead->size; 00576 for( i=0;i<16;i++ ) { 00577 if( i<j ) mwWrite( "%02X ", 00578 (unsigned char) *(data+mwOverflowZoneSize+i) ); 00579 else mwWrite( ".. " ); 00580 } 00581 for( i=0;i<j;i++ ) { 00582 c = *(data+mwOverflowZoneSize+i); 00583 if( c < 32 || c > 126 ) c = '.'; 00584 mwWrite( "%c", c ); 00585 } 00586 mwWrite( "}\n" ); 00587 mw = mwHead; 00588 mwUnlink( mw, __FILE__, __LINE__ ); 00589 free( mw ); 00590 } 00591 else { 00592 data = ((char*)mwHead) + mwDataSize + mwOverflowZoneSize; 00593 if( mwTestMem( data, mwHead->size, MW_VAL_NML ) ) { 00594 mwErrors++; 00595 mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n", 00596 mwHead->count, data + mwOverflowZoneSize, mwHead->file, mwHead->line ); 00597 FLUSH(); 00598 } 00599 mwNmlNumAlloc --; 00600 mwNmlCurAlloc -= mwHead->size; 00601 mw = mwHead; 00602 mwUnlink( mw, __FILE__, __LINE__ ); 00603 free( mw ); 00604 } 00605 } 00606 00607 if( mwNmlNumAlloc ) mwWrite("internal: NoMansLand block counter %ld, not zero\n", mwNmlNumAlloc ); 00608 if( mwNmlCurAlloc ) mwWrite("internal: NoMansLand byte counter %ld, not zero\n", mwNmlCurAlloc ); 00609 00610 /* report statistics */ 00611 mwStatReport(); 00612 FLUSH(); 00613 00614 mwInited = 0; 00615 mwHead = mwTail = NULL; 00616 if( mwErrors ) 00617 fprintf(mwSTDERR,"MEMWATCH detected %ld anomalies\n",mwErrors); 00618 mwLogFile( NULL ); 00619 mwErrors = 0; 00620 00621 MW_MUTEX_TERM(); 00622 00623 }
static int mwARI | ( | const char * | text | ) | [static] |
Definition at line 832 of file KalFitMemLeak.c.
References MW_ARI_ABORT, MW_ARI_IGNORE, MW_ARI_RETRY, mwBreakOut(), and mwSTDERR.
Referenced by mwAriHandler().
00832 { 00833 char inbuf[81]; 00834 int c; 00835 fprintf(mwSTDERR, "\n%s\nMEMWATCH: Abort, Retry or Ignore? ", estr); 00836 (void) fgets(inbuf,sizeof(inbuf),stdin); 00837 for( c=0; inbuf[c] && inbuf[c] <= ' '; c++ ) ; 00838 c = inbuf[c]; 00839 if( c == 'R' || c == 'r' ) { 00840 mwBreakOut( estr ); 00841 return MW_ARI_RETRY; 00842 } 00843 if( c == 'I' || c == 'i' ) return MW_ARI_IGNORE; 00844 return MW_ARI_ABORT; 00845 }
int mwAriHandler | ( | const char * | estr | ) |
Definition at line 848 of file KalFitMemLeak.c.
References mwARI(), and mwAutoInit().
00848 { 00849 mwAutoInit(); 00850 return mwARI( estr ); 00851 }
int mwAssert | ( | int | exp, | |
const char * | exps, | |||
const char * | fn, | |||
int | ln | |||
) |
Definition at line 1228 of file KalFitMemLeak.c.
References FLUSH, genRecEmupikp::i, MW_ARI_IGNORE, MW_ARI_NULLREAD, MW_ARI_RETRY, MW_MUTEX_LOCK, MW_MUTEX_UNLOCK, MW_TRACE_BUFFER, mwAriAction, mwAriFunction, mwAutoInit(), mwCounter, mwDummy(), mwIncErr(), mwSTDERR, mwTestNow(), mwWrite(), and TESTS.
01228 { 01229 int i; 01230 char buffer[MW_TRACE_BUFFER+8]; 01231 if( exp ) { 01232 return 0; 01233 } 01234 mwAutoInit(); 01235 MW_MUTEX_LOCK(); 01236 TESTS(fn,ln); 01237 mwIncErr(); 01238 mwCounter++; 01239 mwWrite( "assert trap: <%ld> %s(%d), %s\n", mwCounter, fn, ln, exps ); 01240 if( mwAriFunction != NULL ) { 01241 sprintf( buffer, "MEMWATCH: assert trap: %s(%d), %s", fn, ln, exps ); 01242 i = (*mwAriFunction)(buffer); 01243 switch( i ) { 01244 case MW_ARI_IGNORE: 01245 mwWrite( "assert trap: <%ld> IGNORED - execution continues\n", mwCounter ); 01246 MW_MUTEX_UNLOCK(); 01247 return 0; 01248 case MW_ARI_RETRY: 01249 mwWrite( "assert trap: <%ld> RETRY - executing again\n", mwCounter ); 01250 MW_MUTEX_UNLOCK(); 01251 return 1; 01252 } 01253 } 01254 else { 01255 if( mwAriAction & MW_ARI_IGNORE ) { 01256 mwWrite( "assert trap: <%ld> AUTO IGNORED - execution continues\n", mwCounter ); 01257 MW_MUTEX_UNLOCK(); 01258 return 0; 01259 } 01260 fprintf(mwSTDERR,"\nMEMWATCH: assert trap: %s(%d), %s\n", fn, ln, exps ); 01261 } 01262 01263 FLUSH(); 01264 (void) mwTestNow( fn, ln, 1 ); 01265 FLUSH(); 01266 01267 if( mwAriAction & MW_ARI_NULLREAD ) { 01268 /* This is made in an attempt to kick in */ 01269 /* any debuggers or OS stack traces */ 01270 FLUSH(); 01271 /*lint -save -e413 */ 01272 i = *((int*)NULL); 01273 mwDummy( (char)i ); 01274 /*lint -restore */ 01275 } 01276 01277 MW_MUTEX_UNLOCK(); 01278 exit(255); 01279 /* NOT REACHED - the return statement is in to keep */ 01280 /* stupid compilers from squeaking about differing return modes. */ 01281 /* Smart compilers instead say 'code unreachable...' */ 01282 /*lint -save -e527 */ 01283 return 0; 01284 /*lint -restore */ 01285 }
void mwAutoCheck | ( | int | onoff | ) |
Definition at line 649 of file KalFitMemLeak.c.
References MW_TEST_ALL, mwAutoInit(), mwTestAlways, and mwTestFlags.
00649 { 00650 mwAutoInit(); 00651 mwTestAlways = onoff; 00652 if( onoff ) mwTestFlags = MW_TEST_ALL; 00653 }
static void mwAutoInit | ( | void | ) | [static] |
Definition at line 1511 of file KalFitMemLeak.c.
References mwInit, mwInited, and mwUseAtexit.
Referenced by mwAriHandler(), mwAssert(), mwAutoCheck(), mwFree(), mwMalloc(), mwMark(), mwNoMansLand(), mwRealloc(), mwSetAriFunc(), mwSetOutFunc(), mwStatistics(), mwTest(), mwTestBuffer(), mwTrace(), mwVerify(), and mwWrite().
01512 { 01513 if( mwInited ) return; 01514 mwUseAtexit = 1; 01515 mwInit(); 01516 return; 01517 }
void mwBreakOut | ( | const char * | cause | ) |
void* mwCalloc | ( | size_t | a, | |
size_t | b, | |||
const char * | file, | |||
int | line | |||
) |
Definition at line 1154 of file KalFitMemLeak.c.
References mwMalloc, and delete_small_size::size.
01154 { 01155 void *p; 01156 size_t size = a * b; 01157 p = mwMalloc( size, file, line ); 01158 if( p == NULL ) return NULL; 01159 memset( p, 0, size ); 01160 return p; 01161 }
void* mwCalloc_ | ( | size_t | a, | |
size_t | b | |||
) |
Definition at line 1184 of file KalFitMemLeak.c.
References MW_MUTEX_LOCK, MW_MUTEX_UNLOCK, and TESTS.
01184 { 01185 MW_MUTEX_LOCK(); 01186 TESTS(NULL,0); 01187 MW_MUTEX_UNLOCK(); 01188 return calloc( a, b ); 01189 }
static int mwCheckOF | ( | const void * | p | ) | [static] |
Definition at line 672 of file KalFitMemLeak.c.
References genRecEmupikp::i, mwOverflowZoneSize, and mwOverflowZoneTemplate.
Referenced by mwAbort(), and mwTestBuf().
00673 { 00674 int i; 00675 const unsigned char *ptr; 00676 ptr = (const unsigned char *) p; 00677 for( i=0; i<mwOverflowZoneSize; i++ ) 00678 { 00679 if( *(ptr+i) != mwOverflowZoneTemplate[i%8] ) 00680 return 1; /* errors found */ 00681 } 00682 return 0; /* no errors */ 00683 }
static void mwDefaultOutFunc | ( | int | ) | [static] |
void mwDoFlush | ( | int | onoff | ) |
Definition at line 1196 of file KalFitMemLeak.c.
References mwFlushW(), and mwLogR().
01196 { 01197 mwFlushW( onoff<1?0:onoff ); 01198 if( onoff ) if( mwLogR() ) fflush( mwLogR() ); 01199 return; 01200 }
unsigned mwDrop | ( | unsigned | kb | ) |
Definition at line 1377 of file KalFitMemLeak.c.
References MW_VAL_GRB, mwDrop_(), and TESTS.
01377 { 01378 TESTS(NULL,0); 01379 return mwDrop_( kb, MW_VAL_GRB, 0 ); 01380 }
static unsigned mwDrop_ | ( | unsigned | kb, | |
int | type, | |||
int | silent | |||
) | [static] |
Definition at line 1440 of file KalFitMemLeak.c.
References mwGrabData_::blob, FLUSH, genRecEmupikp::i, mwCounter, mwGrabList, mwGrabSize, mwGrabType(), mwTestMem(), mwWrite(), mwGrabData_::next, pr, and mwGrabData_::type.
Referenced by mwDrop(), mwDropAll(), mwFreeUp(), and mwNoMansLand().
01440 { 01441 unsigned i = kb; 01442 mwGrabData *gd,*tmp,*pr; 01443 const void *p; 01444 01445 if( mwGrabList == NULL && kb == 0 ) return 0; 01446 if( !kb ) i = kb = 60000U; 01447 01448 pr = NULL; 01449 gd = mwGrabList; 01450 for(;kb;) { 01451 if( gd == NULL ) { 01452 if( i-kb > 0 && !silent ) { 01453 mwWrite("dropped: all %s memory (%u kb)\n", mwGrabType(type), i-kb); 01454 FLUSH(); 01455 } 01456 return i-kb; 01457 } 01458 if( gd->type == type ) { 01459 if( pr ) pr->next = gd->next; 01460 kb --; 01461 tmp = gd; 01462 if( mwGrabList == gd ) mwGrabList = gd->next; 01463 gd = gd->next; 01464 p = mwTestMem( tmp->blob, sizeof( tmp->blob ), type ); 01465 if( p != NULL ) { 01466 mwWrite( "wild pointer: <%ld> %s memory hit at %p\n", 01467 mwCounter, mwGrabType(type), p ); 01468 FLUSH(); 01469 } 01470 mwGrabSize -= (long) sizeof(mwGrabData); 01471 free( tmp ); 01472 } 01473 else { 01474 pr = gd; 01475 gd = gd->next; 01476 } 01477 } 01478 if( !silent ) { 01479 mwWrite("dropped: %u kilobytes of %s memory\n", i, mwGrabType(type) ); 01480 FLUSH(); 01481 } 01482 return i; 01483 }
static void mwDropAll | ( | void | ) | [static] |
Definition at line 1382 of file KalFitMemLeak.c.
References MW_VAL_GRB, MW_VAL_NML, mwDrop_(), mwGrabList, mwWrite(), and TESTS.
Referenced by mwAbort().
01382 { 01383 TESTS(NULL,0); 01384 (void) mwDrop_( 0, MW_VAL_GRB, 0 ); 01385 (void) mwDrop_( 0, MW_VAL_NML, 0 ); 01386 if( mwGrabList != NULL ) 01387 mwWrite( "internal: the grab list is not empty after mwDropAll()\n"); 01388 }
static char mwDummy | ( | char | c | ) | [static] |
static void mwFlush | ( | void | ) | [static] |
Definition at line 1563 of file KalFitMemLeak.c.
References mwFlushR(), and mwLogR().
01563 { 01564 if( mwLogR() == NULL ) return; 01565 #ifdef MW_FLUSH 01566 fflush( mwLogR() ); 01567 #else 01568 if( mwFlushR() ) fflush( mwLogR() ); 01569 #endif 01570 return; 01571 }
void mwFlushNow | ( | void | ) |
static int mwFlushR | ( | void | ) | [static] |
Definition at line 1538 of file KalFitMemLeak.c.
References FLUSH, mwFlushing, mwFlushingB1, mwFlushingB2, and mwWrite().
Referenced by mwFlush(), and mwIncErr().
01538 { 01539 if( (mwFlushing == mwFlushingB1) && (mwFlushing == mwFlushingB2) ) return mwFlushing; 01540 if( mwFlushing == mwFlushingB1 ) mwFlushingB2 = mwFlushing; 01541 if( mwFlushing == mwFlushingB2 ) mwFlushingB1 = mwFlushing; 01542 if( mwFlushingB1 == mwFlushingB2 ) mwFlushing = mwFlushingB1; 01543 if( (mwFlushing == mwFlushingB1) && (mwFlushing == mwFlushingB2) ) { 01544 mwWrite("internal: flushing flag damaged and recovered\n"); 01545 FLUSH(); 01546 return mwFlushing; 01547 } 01548 mwWrite("internal: flushing flag destroyed, so set to true\n"); 01549 mwFlushing = mwFlushingB1 = mwFlushingB2 = 1; 01550 return 1; 01551 }
static void mwFlushW | ( | int | ) | [static] |
Definition at line 1553 of file KalFitMemLeak.c.
References mwFlushing, mwFlushingB1, and mwFlushingB2.
Referenced by mwAbort(), mwDoFlush(), and mwIncErr().
01553 { 01554 mwFlushing = mwFlushingB1 = mwFlushingB2 = n; 01555 }
void mwFree | ( | void * | p, | |
const char * | file, | |||
int | line | |||
) |
Definition at line 1051 of file KalFitMemLeak.c.
References FLUSH, genRecEmupikp::i, mw, MW_FREE_LIST, MW_MUTEX_LOCK, MW_MUTEX_UNLOCK, MW_NML, MW_VAL_DEL, MW_VAL_NML, mwAutoInit(), mwBUFFER_TO_MW, mwCounter, mwDataSize, mwFBI, mwFree_, mwIncErr(), mwIsOwned(), mwLastFree, mwLFcur, mwLFfile, mwLFline, mwNML, mwNmlCurAlloc, mwNmlNumAlloc, mwNumCurAlloc, mwOverflowZoneSize, mwROUNDALLOC, mwStatCurAlloc, mwStatFree(), mwStatLevel, mwTestBuf(), mwUnlink(), mwWrite(), and TESTS.
01051 { 01052 int i; 01053 mwData* mw; 01054 char buffer[ sizeof(mwData) + (mwROUNDALLOC*3) + 64 ]; 01055 01056 /* this code is in support of C++ delete */ 01057 if( file == NULL ) { 01058 mwFree_( p ); 01059 MW_MUTEX_UNLOCK(); 01060 return; 01061 } 01062 01063 mwAutoInit(); 01064 01065 MW_MUTEX_LOCK(); 01066 TESTS(file,line); 01067 mwCounter ++; 01068 01069 /* on NULL free, write a warning and return */ 01070 if( p == NULL ) { 01071 mwWrite( "NULL free: <%ld> %s(%d), NULL pointer free'd\n", 01072 mwCounter, file, line ); 01073 FLUSH(); 01074 MW_MUTEX_UNLOCK(); 01075 return; 01076 } 01077 01078 /* do the quick ownership test */ 01079 mw = (mwData*) mwBUFFER_TO_MW( p ); 01080 01081 if( mwIsOwned( mw, file, line ) ) { 01082 (void) mwTestBuf( mw, file, line ); 01083 01084 /* if the buffer is an NML, treat this as a double-free */ 01085 if( mw->flag & MW_NML ) 01086 { 01087 if( *(((unsigned char*)mw)+mwDataSize+mwOverflowZoneSize) != MW_VAL_NML ) 01088 { 01089 mwWrite( "internal: <%ld> %s(%d), no-mans-land MW-%p is corrupted\n", 01090 mwCounter, file, line, mw ); 01091 } 01092 goto check_dbl_free; 01093 } 01094 01095 /* update the statistics */ 01096 mwNumCurAlloc --; 01097 mwStatCurAlloc -= (long) mw->size; 01098 if( mwStatLevel ) mwStatFree( mw->size, mw->file, mw->line ); 01099 01100 /* we should either free the allocation or keep it as NML */ 01101 if( mwNML ) { 01102 mw->flag |= MW_NML; 01103 mwNmlNumAlloc ++; 01104 mwNmlCurAlloc += (long) mw->size; 01105 memset( ((char*)mw)+mwDataSize+mwOverflowZoneSize, MW_VAL_NML, mw->size ); 01106 } 01107 else { 01108 /* unlink the allocation, and enter the post-free data */ 01109 mwUnlink( mw, file, line ); 01110 memset( mw, MW_VAL_DEL, 01111 mw->size + mwDataSize+mwOverflowZoneSize+mwOverflowZoneSize ); 01112 if( mwFBI ) { 01113 memset( mw, '.', mwDataSize + mwOverflowZoneSize ); 01114 sprintf( buffer, "FBI<%ld>%s(%d)", mwCounter, file, line ); 01115 strncpy( (char*)(void*)mw, buffer, mwDataSize + mwOverflowZoneSize ); 01116 } 01117 free( mw ); 01118 } 01119 01120 /* add the pointer to the last-free track */ 01121 mwLFfile[ mwLFcur ] = file; 01122 mwLFline[ mwLFcur ] = line; 01123 mwLastFree[ mwLFcur++ ] = p; 01124 if( mwLFcur == MW_FREE_LIST ) mwLFcur = 0; 01125 01126 MW_MUTEX_UNLOCK(); 01127 return; 01128 } 01129 01130 /* check for double-freeing */ 01131 check_dbl_free: 01132 for(i=0;i<MW_FREE_LIST;i++) { 01133 if( mwLastFree[i] == p ) { 01134 mwIncErr(); 01135 mwWrite( "double-free: <%ld> %s(%d), %p was" 01136 " freed from %s(%d)\n", 01137 mwCounter, file, line, p, 01138 mwLFfile[i], mwLFline[i] ); 01139 FLUSH(); 01140 MW_MUTEX_UNLOCK(); 01141 return; 01142 } 01143 } 01144 01145 /* some weird pointer... block the free */ 01146 mwIncErr(); 01147 mwWrite( "WILD free: <%ld> %s(%d), unknown pointer %p\n", 01148 mwCounter, file, line, p ); 01149 FLUSH(); 01150 MW_MUTEX_UNLOCK(); 01151 return; 01152 }
void mwFree_ | ( | void * | p | ) |
Definition at line 1163 of file KalFitMemLeak.c.
References MW_MUTEX_LOCK, MW_MUTEX_UNLOCK, and TESTS.
01163 { 01164 MW_MUTEX_LOCK(); 01165 TESTS(NULL,0); 01166 MW_MUTEX_UNLOCK(); 01167 free(p); 01168 }
static size_t mwFreeUp | ( | size_t | , | |
int | ||||
) | [static] |
Definition at line 2082 of file KalFitMemLeak.c.
References mw, MW_NML, MW_VAL_GRB, MW_VAL_NML, mwDataSize, mwDrop_(), mwHead, mwIncErr(), mwOverflowZoneSize, mwTestMem(), mwUnlink(), and mwWrite().
Referenced by mwMalloc().
02082 { 02083 void *p; 02084 mwData *mw, *mw2; 02085 char *data; 02086 02087 /* free grabbed NML memory */ 02088 for(;;) { 02089 if( mwDrop_( 1, MW_VAL_NML, 1 ) == 0 ) break; 02090 p = malloc( needed ); 02091 if( p == NULL ) continue; 02092 free( p ); 02093 return needed; 02094 } 02095 02096 /* free normal NML memory */ 02097 mw = mwHead; 02098 while( mw != NULL ) { 02099 if( !(mw->flag & MW_NML) ) mw = mw->next; 02100 else { 02101 data = ((char*)mw)+mwDataSize+mwOverflowZoneSize; 02102 if( mwTestMem( data, mw->size, MW_VAL_NML ) ) { 02103 mwIncErr(); 02104 mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n", 02105 mw->count, data + mwOverflowZoneSize, mw->file, mw->line ); 02106 } 02107 mw2 = mw->next; 02108 mwUnlink( mw, "mwFreeUp", 0 ); 02109 free( mw ); 02110 mw = mw2; 02111 p = malloc( needed ); 02112 if( p == NULL ) continue; 02113 free( p ); 02114 return needed; 02115 } 02116 } 02117 02118 /* if not urgent (for internal purposes), fail */ 02119 if( !urgent ) return 0; 02120 02121 /* free grabbed memory */ 02122 for(;;) { 02123 if( mwDrop_( 1, MW_VAL_GRB, 1 ) == 0 ) break; 02124 p = malloc( needed ); 02125 if( p == NULL ) continue; 02126 free( p ); 02127 return needed; 02128 } 02129 02130 return 0; 02131 }
unsigned mwGrab | ( | unsigned | kb | ) |
Definition at line 1372 of file KalFitMemLeak.c.
References MW_VAL_GRB, mwGrab_(), and TESTS.
01372 { 01373 TESTS(NULL,0); 01374 return mwGrab_( kb, MW_VAL_GRB, 0 ); 01375 }
static unsigned mwGrab_ | ( | unsigned | kb, | |
int | type, | |||
int | silent | |||
) | [static] |
Definition at line 1403 of file KalFitMemLeak.c.
References mwGrabData_::blob, FLUSH, genRecEmupikp::i, mwAllocLimit, mwGrabList, mwGrabSize, mwGrabType(), mwStatCurAlloc, mwUseLimit, mwWrite(), mwGrabData_::next, and mwGrabData_::type.
Referenced by mwGrab(), and mwNoMansLand().
01403 { 01404 unsigned i = kb; 01405 mwGrabData *gd; 01406 if( !kb ) i = kb = 65000U; 01407 01408 for(;kb;kb--) { 01409 if( mwUseLimit && 01410 (mwStatCurAlloc + mwGrabSize + (long)sizeof(mwGrabData) > mwAllocLimit) ) { 01411 if( !silent ) { 01412 mwWrite("grabbed: all allowed memory to %s (%u kb)\n", 01413 mwGrabType(type), i-kb); 01414 FLUSH(); 01415 } 01416 return i-kb; 01417 } 01418 gd = (mwGrabData*) malloc( sizeof(mwGrabData) ); 01419 if( gd == NULL ) { 01420 if( !silent ) { 01421 mwWrite("grabbed: all available memory to %s (%u kb)\n", 01422 mwGrabType(type), i-kb); 01423 FLUSH(); 01424 } 01425 return i-kb; 01426 } 01427 mwGrabSize += (long) sizeof(mwGrabData); 01428 gd->next = mwGrabList; 01429 memset( gd->blob, type, sizeof(gd->blob) ); 01430 gd->type = type; 01431 mwGrabList = gd; 01432 } 01433 if( !silent ) { 01434 mwWrite("grabbed: %u kilobytes of %s memory\n", i, mwGrabType(type) ); 01435 FLUSH(); 01436 } 01437 return i; 01438 }
static const char * mwGrabType | ( | int | type | ) | [static] |
Definition at line 1390 of file KalFitMemLeak.c.
References MW_VAL_GRB, and MW_VAL_NML.
Referenced by mwDrop_(), and mwGrab_().
01390 { 01391 switch( type ) { 01392 case MW_VAL_GRB: 01393 return "grabbed"; 01394 case MW_VAL_NML: 01395 return "no-mans-land"; 01396 default: 01397 /* do nothing */ 01398 ; 01399 } 01400 return "<unknown type>"; 01401 }
static void mwIncErr | ( | void | ) | [static] |
Definition at line 1557 of file KalFitMemLeak.c.
References FLUSH, mwErrors, mwFlushR(), and mwFlushW().
Referenced by mwAssert(), mwFree(), mwFreeUp(), mwIsOwned(), mwMalloc(), mwRealloc(), mwStrdup(), mwTestBuf(), mwTestNow(), mwTrace(), and mwVerify().
void mwInit | ( | void | ) |
Definition at line 413 of file KalFitMemLeak.c.
References CPPTEXT, FLUSH, genRecEmupikp::i, MW_MUTEX_INIT, mwAbort(), mwDataSize, mwInfoWritten, mwInited, mwLogFile(), mwLogR(), mwNmlCurAlloc, mwNmlNumAlloc, mwROUNDALLOC, mwStatCurAlloc, mwStatList, mwStatMaxAlloc, mwStatNumAlloc, mwStatTotAlloc, mwUseAtexit, mwWrite(), and VERSION.
00413 { 00414 time_t tid; 00415 00416 if( mwInited++ > 0 ) return; 00417 00418 MW_MUTEX_INIT(); 00419 00420 /* start a log if none is running */ 00421 if( mwLogR() == NULL ) mwLogFile( "memwatch.log" ); 00422 if( mwLogR() == NULL ) { 00423 int i; 00424 char buf[32]; 00425 /* oops, could not open it! */ 00426 /* probably because it's already open */ 00427 /* so we try some other names */ 00428 for( i=1; i<100; i++ ) { 00429 sprintf( buf, "memwat%02d.log", i ); 00430 mwLogFile( buf ); 00431 if( mwLogR() != NULL ) break; 00432 } 00433 } 00434 00435 /* initialize the statistics */ 00436 mwStatList = NULL; 00437 mwStatTotAlloc = 0L; 00438 mwStatCurAlloc = 0L; 00439 mwStatMaxAlloc = 0L; 00440 mwStatNumAlloc = 0L; 00441 mwNmlCurAlloc = 0L; 00442 mwNmlNumAlloc = 0L; 00443 00444 /* calculate the buffer size to use for a mwData */ 00445 mwDataSize = sizeof(mwData); 00446 while( mwDataSize % mwROUNDALLOC ) mwDataSize ++; 00447 00448 /* write informational header if needed */ 00449 if( !mwInfoWritten ) { 00450 mwInfoWritten = 1; 00451 (void) time( &tid ); 00452 mwWrite( 00453 "\n=============" 00454 " MEMWATCH " VERSION " Copyright (C) 1992-1999 Johan Lindh " 00455 "=============\n"); 00456 mwWrite( "\nStarted at %s\n", ctime( &tid ) ); 00457 00458 /**************************************************************** Generic */ 00459 mwWrite( "Modes: " ); 00460 #ifdef mwNew 00461 mwWrite( "C++ " ); 00462 #endif /* mwNew */ 00463 #ifdef __STDC__ 00464 mwWrite( "__STDC__ " ); 00465 #endif /* __STDC__ */ 00466 #ifdef mw16BIT 00467 mwWrite( "16-bit " ); 00468 #endif 00469 #ifdef mw32BIT 00470 mwWrite( "32-bit " ); 00471 #endif 00472 #ifdef mw64BIT 00473 mwWrite( "64-bit " ); 00474 #endif 00475 mwWrite( "mwDWORD==(" mwDWORD_DEFINED ")\n" ); 00476 mwWrite( "mwROUNDALLOC==%d sizeof(mwData)==%d mwDataSize==%d\n", 00477 mwROUNDALLOC, sizeof(mwData), mwDataSize ); 00478 /**************************************************************** Generic */ 00479 00480 /************************************************************ Microsoft C */ 00481 #ifdef _MSC_VER 00482 mwWrite( "Compiled using Microsoft C" CPPTEXT 00483 " %d.%02d\n", _MSC_VER / 100, _MSC_VER % 100 ); 00484 #endif /* _MSC_VER */ 00485 /************************************************************ Microsoft C */ 00486 00487 /************************************************************** Borland C */ 00488 #ifdef __BORLANDC__ 00489 mwWrite( "Compiled using Borland C" 00490 #ifdef __cplusplus 00491 "++ %d.%01d\n", __BCPLUSPLUS__/0x100, (__BCPLUSPLUS__%0x100)/0x10 ); 00492 #else 00493 " %d.%01d\n", __BORLANDC__/0x100, (__BORLANDC__%0x100)/0x10 ); 00494 #endif /* __cplusplus */ 00495 #endif /* __BORLANDC__ */ 00496 /************************************************************** Borland C */ 00497 00498 /************************************************************** Watcom C */ 00499 #ifdef __WATCOMC__ 00500 mwWrite( "Compiled using Watcom C %d.%02d ", 00501 __WATCOMC__/100, __WATCOMC__%100 ); 00502 #ifdef __FLAT__ 00503 mwWrite( "(32-bit flat model)" ); 00504 #endif /* __FLAT__ */ 00505 mwWrite( "\n" ); 00506 #endif /* __WATCOMC__ */ 00507 /************************************************************** Watcom C */ 00508 00509 mwWrite( "\n" ); 00510 FLUSH(); 00511 } 00512 00513 if( mwUseAtexit ) (void) atexit( mwAbort ); 00514 return; 00515 }
static int mwIsHeapOK | ( | mwData * | mw | ) | [static] |
Definition at line 1899 of file KalFitMemLeak.c.
References mw, mwDataSize, mwHead, mwIsSafeAddr(), and mwTail.
Referenced by mwIsOwned().
01899 { 01900 int found = 0; 01901 mwData *mw; 01902 01903 for( mw = mwHead; mw; mw=mw->next ) { 01904 if( includes_mw == mw ) found++; 01905 if( !mwIsSafeAddr( mw, mwDataSize ) ) return 0; 01906 if( mw->prev ) { 01907 if( !mwIsSafeAddr( mw->prev, mwDataSize ) ) return 0; 01908 if( mw==mwHead || mw->prev->next != mw ) return 0; 01909 } 01910 if( mw->next ) { 01911 if( !mwIsSafeAddr( mw->next, mwDataSize ) ) return 0; 01912 if( mw==mwTail || mw->next->prev != mw ) return 0; 01913 } 01914 else if( mw!=mwTail ) return 0; 01915 } 01916 01917 if( includes_mw != NULL && !found ) return 0; 01918 01919 return 1; 01920 }
static int mwIsOwned | ( | mwData * | mw, | |
const char * | file, | |||
int | line | |||
) | [static] |
Definition at line 1922 of file KalFitMemLeak.c.
References CHKVAL, mw, mwCounter, mwDataSize, mwHead, mwIncErr(), mwIsHeapOK(), mwIsReadAddr(), mwIsSafeAddr(), mwRelink(), mwStatCurAlloc, mwStatGet(), mwTail, and mwWrite().
Referenced by mwAbort(), mwFree(), mwRealloc(), and mwTestBuffer().
01922 { 01923 int retv; 01924 mwStat *ms; 01925 01926 /* see if the address is legal according to OS */ 01927 if( !mwIsSafeAddr( mw, mwDataSize ) ) return 0; 01928 01929 /* make sure we have _anything_ allocated */ 01930 if( mwHead == NULL && mwTail == NULL && mwStatCurAlloc == 0 ) 01931 return 0; 01932 01933 /* calculate checksum */ 01934 if( mw->check != CHKVAL(mw) ) { 01935 /* may be damaged checksum, see if block is in heap */ 01936 if( mwIsHeapOK( mw ) ) { 01937 /* damaged checksum, repair it */ 01938 mwWrite( "internal: <%ld> %s(%d), checksum for MW-%p is incorrect\n", 01939 mwCounter, file, line, mw ); 01940 mwIncErr(); 01941 if( mwIsReadAddr( mw->file, 1 ) ) { 01942 ms = mwStatGet( mw->file, -1, 0 ); 01943 if( ms == NULL ) mw->file = "<relinked>"; 01944 } 01945 else mw->file = "<unknown>"; 01946 mw->size = 0; 01947 mw->check = CHKVAL(mw); 01948 return 1; 01949 } 01950 /* no, it's just some garbage data */ 01951 return 0; 01952 } 01953 01954 /* check that the non-NULL pointers are safe */ 01955 if( mw->prev && !mwIsSafeAddr( mw->prev, mwDataSize ) ) mwRelink( mw, file, line ); 01956 if( mw->next && !mwIsSafeAddr( mw->next, mwDataSize ) ) mwRelink( mw, file, line ); 01957 01958 /* safe address, checksum OK, proceed with heap checks */ 01959 01960 /* see if the block is in the heap */ 01961 retv = 0; 01962 if( mw->prev ) { if( mw->prev->next == mw ) retv ++; } 01963 else { if( mwHead == mw ) retv++; } 01964 if( mw->next ) { if( mw->next->prev == mw ) retv ++; } 01965 else { if( mwTail == mw ) retv++; } 01966 if( mw->check == CHKVAL(mw) ) retv ++; 01967 if( retv > 2 ) return 1; 01968 01969 /* block not in heap, check heap for corruption */ 01970 01971 if( !mwIsHeapOK( mw ) ) { 01972 if( mwRelink( mw, file, line ) ) 01973 return 1; 01974 } 01975 01976 /* unable to repair */ 01977 mwWrite( "internal: <%ld> %s(%d), mwIsOwned fails for MW-%p\n", 01978 mwCounter, file, line, mw ); 01979 mwIncErr(); 01980 01981 return 0; 01982 }
int mwIsReadAddr | ( | const void * | p, | |
unsigned | len | |||
) |
Definition at line 2491 of file KalFitMemLeak.c.
Referenced by mwIsOwned(), mwMark(), mwStatReport(), and mwTestBuf().
int mwIsSafeAddr | ( | void * | p, | |
unsigned | len | |||
) |
Definition at line 2497 of file KalFitMemLeak.c.
Referenced by mwIsHeapOK(), mwIsOwned(), mwRelink(), mwTestBuf(), and mwTestNow().
void mwLimit | ( | long | lim | ) |
Definition at line 1202 of file KalFitMemLeak.c.
References FLUSH, mwAllocLimit, mwUseLimit, mwWrite(), and TESTS.
01202 { 01203 TESTS(NULL,0); 01204 mwWrite("limit: old limit = "); 01205 if( !mwAllocLimit ) mwWrite( "none" ); 01206 else mwWrite( "%ld bytes", mwAllocLimit ); 01207 mwWrite( ", new limit = "); 01208 if( !lim ) { 01209 mwWrite( "none\n" ); 01210 mwUseLimit = 0; 01211 } 01212 else { 01213 mwWrite( "%ld bytes\n", lim ); 01214 mwUseLimit = 1; 01215 } 01216 mwAllocLimit = lim; 01217 FLUSH(); 01218 }
static void mwLogFile | ( | const char * | name | ) | [static] |
Definition at line 2063 of file KalFitMemLeak.c.
References COMMIT, mwLogR(), mwLogW(), and mwWrite().
Referenced by mwAbort(), and mwInit().
02063 { 02064 time_t tid; 02065 (void) time( &tid ); 02066 if( mwLogR() != NULL ) { 02067 fclose( mwLogR() ); 02068 mwLogW( NULL ); 02069 } 02070 if( name == NULL ) return; 02071 mwLogW( fopen( name, "a" COMMIT ) ); 02072 if( mwLogR() == NULL ) 02073 mwWrite( "logfile: failed to open/create file '%s'\n", name ); 02074 }
static FILE * mwLogR | ( | void | ) | [static] |
Definition at line 1519 of file KalFitMemLeak.c.
References FLUSH, mwLog, mwLogB1, mwLogB2, mwSTDERR, and mwWrite().
Referenced by mwDefaultOutFunc(), mwDoFlush(), mwFlush(), mwFlushNow(), mwInit(), and mwLogFile().
01519 { 01520 if( (mwLog == mwLogB1) && (mwLog == mwLogB2) ) return mwLog; 01521 if( mwLog == mwLogB1 ) mwLogB2 = mwLog; 01522 if( mwLog == mwLogB2 ) mwLogB1 = mwLog; 01523 if( mwLogB1 == mwLogB2 ) mwLog = mwLogB1; 01524 if( (mwLog == mwLogB1) && (mwLog == mwLogB2) ) { 01525 mwWrite("internal: log file handle damaged and recovered\n"); 01526 FLUSH(); 01527 return mwLog; 01528 } 01529 fprintf(mwSTDERR,"\nMEMWATCH: log file handle destroyed, using mwSTDERR\n" ); 01530 mwLog = mwLogB1 = mwLogB2 = mwSTDERR; 01531 return mwSTDERR; 01532 }
static void mwLogW | ( | FILE * | ) | [static] |
Definition at line 1534 of file KalFitMemLeak.c.
References mwLog, mwLogB1, and mwLogB2.
Referenced by mwLogFile().
void* mwMalloc | ( | size_t | size, | |
const char * | file, | |||
int | line | |||
) |
Definition at line 863 of file KalFitMemLeak.c.
References CHKVAL, FLUSH, mw, MW_MUTEX_LOCK, MW_MUTEX_UNLOCK, MW_VAL_NEW, mwAllocLimit, mwAutoInit(), mwCounter, mwDataSize, mwFreeUp(), mwHead, mwIncErr(), mwNumCurAlloc, mwOverflowZoneSize, mwStatAlloc(), mwStatCurAlloc, mwStatLevel, mwStatMaxAlloc, mwStatNumAlloc, mwStatTotAlloc, mwTail, mwUseLimit, mwWrite(), mwWriteOF(), mwData_::prev, and TESTS.
00863 { 00864 size_t needed; 00865 mwData *mw; 00866 char *ptr; 00867 void *p; 00868 00869 mwAutoInit(); 00870 00871 MW_MUTEX_LOCK(); 00872 00873 TESTS(file,line); 00874 00875 mwCounter ++; 00876 needed = mwDataSize + mwOverflowZoneSize*2 + size; 00877 if( needed < size ) 00878 { 00879 /* theoretical case: req size + mw overhead exceeded size_t limits */ 00880 return NULL; 00881 } 00882 00883 /* if this allocation would violate the limit, fail it */ 00884 if( mwUseLimit && ((long)size + mwStatCurAlloc > mwAllocLimit) ) { 00885 mwWrite( "limit fail: <%ld> %s(%d), %ld wanted %ld available\n", 00886 mwCounter, file, line, (long)size, mwAllocLimit - mwStatCurAlloc ); 00887 mwIncErr(); 00888 FLUSH(); 00889 MW_MUTEX_UNLOCK(); 00890 return NULL; 00891 } 00892 00893 mw = (mwData*) malloc( needed ); 00894 if( mw == NULL ) { 00895 if( mwFreeUp(needed,0) >= needed ) { 00896 mw = (mwData*) malloc(needed); 00897 if( mw == NULL ) { 00898 mwWrite( "internal: mwFreeUp(%u) reported success, but malloc() fails\n", needed ); 00899 mwIncErr(); 00900 FLUSH(); 00901 } 00902 } 00903 if( mw == NULL ) { 00904 mwWrite( "fail: <%ld> %s(%d), %ld wanted %ld allocated\n", 00905 mwCounter, file, line, (long)size, mwStatCurAlloc ); 00906 mwIncErr(); 00907 FLUSH(); 00908 MW_MUTEX_UNLOCK(); 00909 return NULL; 00910 } 00911 } 00912 00913 mw->count = mwCounter; 00914 mw->prev = NULL; 00915 mw->next = mwHead; 00916 mw->file = file; 00917 mw->size = size; 00918 mw->line = line; 00919 mw->flag = 0; 00920 mw->check = CHKVAL(mw); 00921 00922 if( mwHead ) mwHead->prev = mw; 00923 mwHead = mw; 00924 if( mwTail == NULL ) mwTail = mw; 00925 00926 ptr = ((char*)mw) + mwDataSize; 00927 mwWriteOF( ptr ); /* '*(long*)ptr = PRECHK;' */ 00928 ptr += mwOverflowZoneSize; 00929 p = ptr; 00930 memset( ptr, MW_VAL_NEW, size ); 00931 ptr += size; 00932 mwWriteOF( ptr ); /* '*(long*)ptr = POSTCHK;' */ 00933 00934 mwNumCurAlloc ++; 00935 mwStatCurAlloc += (long) size; 00936 mwStatTotAlloc += (long) size; 00937 if( mwStatCurAlloc > mwStatMaxAlloc ) 00938 mwStatMaxAlloc = mwStatCurAlloc; 00939 mwStatNumAlloc ++; 00940 00941 if( mwStatLevel ) mwStatAlloc( size, file, line ); 00942 00943 MW_MUTEX_UNLOCK(); 00944 return p; 00945 }
void* mwMalloc_ | ( | size_t | size | ) |
Definition at line 1170 of file KalFitMemLeak.c.
References MW_MUTEX_LOCK, MW_MUTEX_UNLOCK, and TESTS.
01170 { 01171 MW_MUTEX_LOCK(); 01172 TESTS(NULL,0); 01173 MW_MUTEX_UNLOCK(); 01174 return malloc( size ); 01175 }
void* mwMark | ( | void * | p, | |
const char * | desc, | |||
const char * | file, | |||
unsigned | line | |||
) |
Definition at line 718 of file KalFitMemLeak.c.
References mwMarker_::host, mwAutoInit(), mwFirstMark, mwIsReadAddr(), mwWrite(), mwMarker_::next, and TESTS.
00718 { 00719 mwMarker *mrk; 00720 unsigned n, isnew; 00721 char *buf; 00722 int tot, oflow = 0; 00723 char wherebuf[128]; 00724 00725 mwAutoInit(); 00726 TESTS(NULL,0); 00727 00728 if( desc == NULL ) desc = "unknown"; 00729 if( file == NULL ) file = "unknown"; 00730 00731 tot = sprintf( wherebuf, "%.48s called from %s(%d)", desc, file, line ); 00732 if( tot >= (int)sizeof(wherebuf) ) { wherebuf[sizeof(wherebuf)-1] = 0; oflow = 1; } 00733 00734 if( p == NULL ) { 00735 mwWrite("mark: %s(%d), no mark for NULL:'%s' may be set\n", file, line, desc ); 00736 return p; 00737 } 00738 00739 if( mwFirstMark != NULL && !mwIsReadAddr( mwFirstMark, sizeof( mwMarker ) ) ) 00740 { 00741 mwWrite("mark: %s(%d), mwFirstMark (%p) is trashed, can't mark for %s\n", 00742 file, line, mwFirstMark, desc ); 00743 return p; 00744 } 00745 00746 for( mrk=mwFirstMark; mrk; mrk=mrk->next ) 00747 { 00748 if( mrk->next != NULL && !mwIsReadAddr( mrk->next, sizeof( mwMarker ) ) ) 00749 { 00750 mwWrite("mark: %s(%d), mark(%p)->next(%p) is trashed, can't mark for %s\n", 00751 file, line, mrk, mrk->next, desc ); 00752 return p; 00753 } 00754 if( mrk->host == p ) break; 00755 } 00756 00757 if( mrk == NULL ) { 00758 isnew = 1; 00759 mrk = (mwMarker*) malloc( sizeof( mwMarker ) ); 00760 if( mrk == NULL ) { 00761 mwWrite("mark: %s(%d), no mark for %p:'%s', out of memory\n", file, line, p, desc ); 00762 return p; 00763 } 00764 mrk->next = NULL; 00765 n = 0; 00766 } 00767 else { 00768 isnew = 0; 00769 n = strlen( mrk->text ); 00770 } 00771 00772 n += strlen( wherebuf ); 00773 buf = (char*) malloc( n+3 ); 00774 if( buf == NULL ) { 00775 if( isnew ) free( mrk ); 00776 mwWrite("mark: %s(%d), no mark for %p:'%s', out of memory\n", file, line, p, desc ); 00777 return p; 00778 } 00779 00780 if( isnew ) { 00781 memcpy( buf, wherebuf, n+1 ); 00782 mrk->next = mwFirstMark; 00783 mrk->host = p; 00784 mrk->text = buf; 00785 mrk->level = 1; 00786 mwFirstMark = mrk; 00787 } 00788 else { 00789 strcpy( buf, mrk->text ); 00790 strcat( buf, ", " ); 00791 strcat( buf, wherebuf ); 00792 free( mrk->text ); 00793 mrk->text = buf; 00794 mrk->level ++; 00795 } 00796 00797 if( oflow ) { 00798 mwIncErr(); 00799 mwTrace( " [WARNING: OUTPUT BUFFER OVERFLOW - SYSTEM UNSTABLE]\n" ); 00800 } 00801 return p; 00802 }
void mwNoMansLand | ( | int | level | ) |
Definition at line 1489 of file KalFitMemLeak.c.
References MW_NML_ALL, MW_NML_FREE, MW_NML_NONE, MW_VAL_NML, mwAutoInit(), mwDrop_(), mwGrab_(), mwNML, and TESTS.
01489 { 01490 mwAutoInit(); 01491 TESTS(NULL,0); 01492 switch( level ) { 01493 case MW_NML_NONE: 01494 (void) mwDrop_( 0, MW_VAL_NML, 0 ); 01495 break; 01496 case MW_NML_FREE: 01497 break; 01498 case MW_NML_ALL: 01499 (void) mwGrab_( 0, MW_VAL_NML, 0 ); 01500 break; 01501 default: 01502 return; 01503 } 01504 mwNML = level; 01505 }
void* mwRealloc | ( | void * | p, | |
size_t | size, | |||
const char * | file, | |||
int | line | |||
) |
Definition at line 947 of file KalFitMemLeak.c.
References FLUSH, genRecEmupikp::i, mw, MW_FREE_LIST, MW_MUTEX_LOCK, MW_MUTEX_UNLOCK, MW_NML, MW_VAL_NML, mwAllocLimit, mwAutoInit(), mwBUFFER_TO_MW, mwCounter, mwDataSize, mwFree, mwIncErr(), mwIsOwned(), mwLastFree, mwLFfile, mwLFline, mwMalloc, mwOverflowZoneSize, mwStatCurAlloc, mwUseLimit, mwWrite(), and TESTS.
00947 { 00948 int oldUseLimit, i; 00949 mwData *mw; 00950 char *ptr; 00951 00952 mwAutoInit(); 00953 00954 if( p == NULL ) return mwMalloc( size, file, line ); 00955 if( size == 0 ) { mwFree( p, file, line ); return NULL; } 00956 00957 MW_MUTEX_LOCK(); 00958 00959 /* do the quick ownership test */ 00960 mw = (mwData*) mwBUFFER_TO_MW( p ); 00961 if( mwIsOwned( mw, file, line ) ) { 00962 00963 /* if the buffer is an NML, treat this as a double-free */ 00964 if( mw->flag & MW_NML ) 00965 { 00966 mwIncErr(); 00967 if( *((unsigned char*)(mw)+mwDataSize+mwOverflowZoneSize) != MW_VAL_NML ) 00968 { 00969 mwWrite( "internal: <%ld> %s(%d), no-mans-land MW-%p is corrupted\n", 00970 mwCounter, file, line, mw ); 00971 } 00972 goto check_dbl_free; 00973 } 00974 00975 /* if this allocation would violate the limit, fail it */ 00976 if( mwUseLimit && ((long)size + mwStatCurAlloc - (long)mw->size > mwAllocLimit) ) { 00977 TESTS(file,line); 00978 mwCounter ++; 00979 mwWrite( "limit fail: <%ld> %s(%d), %ld wanted %ld available\n", 00980 mwCounter, file, line, (unsigned long)size - mw->size, mwAllocLimit - mwStatCurAlloc ); 00981 mwIncErr(); 00982 FLUSH(); 00983 MW_MUTEX_UNLOCK(); 00984 return NULL; 00985 } 00986 00987 /* fake realloc operation */ 00988 oldUseLimit = mwUseLimit; 00989 mwUseLimit = 0; 00990 ptr = (char*) mwMalloc( size, file, line ); 00991 if( ptr != NULL ) { 00992 if( size < mw->size ) 00993 memcpy( ptr, p, size ); 00994 else 00995 memcpy( ptr, p, mw->size ); 00996 mwFree( p, file, line ); 00997 } 00998 mwUseLimit = oldUseLimit; 00999 MW_MUTEX_UNLOCK(); 01000 return (void*) ptr; 01001 } 01002 01003 /* Unknown pointer! */ 01004 01005 /* using free'd pointer? */ 01006 check_dbl_free: 01007 for(i=0;i<MW_FREE_LIST;i++) { 01008 if( mwLastFree[i] == p ) { 01009 mwIncErr(); 01010 mwWrite( "realloc: <%ld> %s(%d), %p was" 01011 " freed from %s(%d)\n", 01012 mwCounter, file, line, p, 01013 mwLFfile[i], mwLFline[i] ); 01014 FLUSH(); 01015 MW_MUTEX_UNLOCK(); 01016 return NULL; 01017 } 01018 } 01019 01020 /* some weird pointer */ 01021 mwIncErr(); 01022 mwWrite( "realloc: <%ld> %s(%d), unknown pointer %p\n", 01023 mwCounter, file, line, p ); 01024 FLUSH(); 01025 MW_MUTEX_UNLOCK(); 01026 return NULL; 01027 }
void* mwRealloc_ | ( | void * | p, | |
size_t | size | |||
) |
Definition at line 1177 of file KalFitMemLeak.c.
References MW_MUTEX_LOCK, MW_MUTEX_UNLOCK, and TESTS.
01177 { 01178 MW_MUTEX_LOCK(); 01179 TESTS(NULL,0); 01180 MW_MUTEX_UNLOCK(); 01181 return realloc( p, size ); 01182 }
static int mwRelink | ( | mwData * | , | |
const char * | file, | |||
int | line | |||
) | [static] |
Definition at line 1605 of file KalFitMemLeak.c.
References count, FLUSH, mw, mwCounter, mwDataSize, mwHead, mwIsSafeAddr(), mwWrite(), mwData_::next, mwData_::prev, and delete_small_size::size.
Referenced by mwIsOwned(), and mwTestBuf().
01605 { 01606 int fails; 01607 mwData *mw1, *mw2; 01608 long count, size; 01609 mwStat *ms; 01610 01611 if( file == NULL ) file = "unknown"; 01612 01613 if( mw == NULL ) { 01614 mwWrite("relink: cannot repair MW at NULL\n"); 01615 FLUSH(); 01616 goto emergency; 01617 } 01618 01619 if( !mwIsSafeAddr(mw, mwDataSize) ) { 01620 mwWrite("relink: MW-%p is a garbage pointer\n", mw); 01621 FLUSH(); 01622 goto emergency; 01623 } 01624 01625 mwWrite("relink: <%ld> %s(%d) attempting to repair MW-%p...\n", mwCounter, file, line, mw ); 01626 FLUSH(); 01627 fails = 0; 01628 01629 /* Repair from head */ 01630 if( mwHead != mw ) { 01631 if( !mwIsSafeAddr( mwHead, mwDataSize ) ) { 01632 mwWrite("relink: failed for MW-%p; head pointer destroyed\n", mw ); 01633 FLUSH(); 01634 goto emergency; 01635 } 01636 for( mw1=mwHead; mw1; mw1=mw1->next ) { 01637 if( mw1->next == mw ) { 01638 mw->prev = mw1; 01639 break; 01640 } 01641 if( mw1->next && 01642 ( !mwIsSafeAddr(mw1->next, mwDataSize ) || mw1->next->prev != mw1) ) { 01643 mwWrite("relink: failed for MW-%p; forward chain fragmented at MW-%p: 'next' is %p\n", mw, mw1, mw1->next ); 01644 FLUSH(); 01645 goto emergency; 01646 } 01647 } 01648 if( mw1 == NULL ) { 01649 mwWrite("relink: MW-%p not found in forward chain search\n", mw ); 01650 FLUSH(); 01651 fails ++; 01652 } 01653 } 01654 else 01655 { 01656 mwWrite( "relink: MW-%p is the head (first) allocation\n", mw ); 01657 if( mw->prev != NULL ) 01658 { 01659 mwWrite( "relink: MW-%p prev pointer is non-NULL, you have a wild pointer\n", mw ); 01660 mw->prev = NULL; 01661 } 01662 } 01663 01664 /* Repair from tail */ 01665 if( mwTail != mw ) { 01666 if( !mwIsSafeAddr( mwTail, mwDataSize ) ) { 01667 mwWrite("relink: failed for MW-%p; tail pointer destroyed\n", mw ); 01668 FLUSH(); 01669 goto emergency; 01670 } 01671 for( mw1=mwTail; mw1; mw1=mw1->prev ) { 01672 if( mw1->prev == mw ) { 01673 mw->next = mw1; 01674 break; 01675 } 01676 if( mw1->prev && (!mwIsSafeAddr(mw1->prev, mwDataSize ) || mw1->prev->next != mw1) ) { 01677 mwWrite("relink: failed for MW-%p; reverse chain fragmented at MW-%p, 'prev' is %p\n", mw, mw1, mw1->prev ); 01678 FLUSH(); 01679 goto emergency; 01680 } 01681 } 01682 if( mw1 == NULL ) { 01683 mwWrite("relink: MW-%p not found in reverse chain search\n", mw ); 01684 FLUSH(); 01685 fails ++; 01686 } 01687 } 01688 else 01689 { 01690 mwWrite( "relink: MW-%p is the tail (last) allocation\n", mw ); 01691 if( mw->next != NULL ) 01692 { 01693 mwWrite( "relink: MW-%p next pointer is non-NULL, you have a wild pointer\n", mw ); 01694 mw->next = NULL; 01695 } 01696 } 01697 01698 if( fails > 1 ) { 01699 mwWrite("relink: heap appears intact, MW-%p probably garbage pointer\n", mw ); 01700 FLUSH(); 01701 goto verifyok; 01702 } 01703 01704 /* restore MW info where possible */ 01705 if( mwIsReadAddr( mw->file, 1 ) ) { 01706 ms = mwStatGet( mw->file, -1, 0 ); 01707 if( ms == NULL ) mw->file = "<relinked>"; 01708 } 01709 mw->check = CHKVAL(mw); 01710 goto verifyok; 01711 01712 /* Emergency repair */ 01713 emergency: 01714 01715 if( mwHead == NULL && mwTail == NULL ) 01716 { 01717 if( mwStatCurAlloc == 0 ) 01718 mwWrite("relink: <%ld> %s(%d) heap is empty, nothing to repair\n", mwCounter, file, line ); 01719 else 01720 mwWrite("relink: <%ld> %s(%d) heap damaged beyond repair\n", mwCounter, file, line ); 01721 FLUSH(); 01722 return 0; 01723 } 01724 01725 mwWrite("relink: <%ld> %s(%d) attempting emergency repairs...\n", mwCounter, file, line ); 01726 FLUSH(); 01727 01728 if( mwHead == NULL || mwTail == NULL ) 01729 { 01730 if( mwHead == NULL ) mwWrite("relink: mwHead is NULL, but mwTail is %p\n", mwTail ); 01731 else mwWrite("relink: mwTail is NULL, but mwHead is %p\n", mwHead ); 01732 } 01733 01734 mw1=NULL; 01735 if( mwHead != NULL ) 01736 { 01737 if( !mwIsReadAddr( mwHead, mwDataSize ) || mwHead->check != CHKVAL(mwHead) ) 01738 { 01739 mwWrite("relink: mwHead (MW-%p) is damaged, skipping forward scan\n", mwHead ); 01740 mwHead = NULL; 01741 goto scan_reverse; 01742 } 01743 if( mwHead->prev != NULL ) 01744 { 01745 mwWrite("relink: the mwHead pointer's 'prev' member is %p, not NULL\n", mwHead->prev ); 01746 } 01747 for( mw1=mwHead; mw1; mw1=mw1->next ) 01748 { 01749 if( mw1->next ) 01750 { 01751 if( !mwIsReadAddr(mw1->next,mwDataSize) || 01752 !mw1->next->check != CHKVAL(mw1) || 01753 mw1->next->prev != mw1 ) 01754 { 01755 mwWrite("relink: forward chain's last intact MW is MW-%p, %ld %sbytes at %s(%d)\n", 01756 mw1, mw1->size, (mw->flag & MW_NML)?"NoMansLand ":"", mw1->file, mw1->line ); 01757 if( mwIsReadAddr(mw1->next,mwDataSize ) ) 01758 { 01759 mwWrite("relink: forward chain's first damaged MW is MW-%p, %ld %sbytes at %s(%d)\n", 01760 mw1->next, mw1->size, (mw->flag & MW_NML)?"NoMansLand ":"", 01761 mwIsReadAddr(mw1->file,16)?mw1->file:"<garbage-pointer>", mw1->line ); 01762 } 01763 else 01764 { 01765 mwWrite("relink: the 'next' pointer of this MW points to %p, which is out-of-legal-access\n", 01766 mw1->next ); 01767 } 01768 break; 01769 } 01770 } 01771 } 01772 } 01773 01774 01775 scan_reverse: 01776 mw2=NULL; 01777 if( mwTail != NULL ) 01778 { 01779 if( !mwIsReadAddr(mwTail,mwDataSize) || mwTail->check != CHKVAL(mwTail) ) 01780 { 01781 mwWrite("relink: mwTail (%p) is damaged, skipping reverse scan\n", mwTail ); 01782 mwTail = NULL; 01783 goto analyze; 01784 } 01785 if( mwTail->next != NULL ) 01786 { 01787 mwWrite("relink: the mwTail pointer's 'next' member is %p, not NULL\n", mwTail->next ); 01788 } 01789 for( mw2=mwTail; mw2; mw2=mw2->prev ) 01790 { 01791 if( mw2->prev ) 01792 { 01793 if( !mwIsReadAddr(mw2->prev,mwDataSize) || 01794 !mw2->prev->check != CHKVAL(mw2) || 01795 mw2->prev->next != mw2 ) 01796 { 01797 mwWrite("relink: reverse chain's last intact MW is MW-%p, %ld %sbytes at %s(%d)\n", 01798 mw2, mw2->size, (mw->flag & MW_NML)?"NoMansLand ":"", mw2->file, mw2->line ); 01799 if( mwIsReadAddr(mw2->prev,mwDataSize ) ) 01800 { 01801 mwWrite("relink: reverse chain's first damaged MW is MW-%p, %ld %sbytes at %s(%d)\n", 01802 mw2->prev, mw2->size, (mw->flag & MW_NML)?"NoMansLand ":"", 01803 mwIsReadAddr(mw2->file,16)?mw2->file:"<garbage-pointer>", mw2->line ); 01804 } 01805 else 01806 { 01807 mwWrite("relink: the 'prev' pointer of this MW points to %p, which is out-of-legal-access\n", 01808 mw2->prev ); 01809 } 01810 break; 01811 } 01812 } 01813 } 01814 } 01815 01816 analyze: 01817 if( mwHead == NULL && mwTail == NULL ) 01818 { 01819 mwWrite("relink: both head and tail pointers damaged, aborting program\n"); 01820 mwFlushW(1); 01821 FLUSH(); 01822 abort(); 01823 } 01824 if( mwHead == NULL ) 01825 { 01826 mwHead = mw2; 01827 mwWrite("relink: heap truncated, MW-%p designated as new mwHead\n", mw2 ); 01828 mw2->prev = NULL; 01829 mw1 = mw2 = NULL; 01830 } 01831 if( mwTail == NULL ) 01832 { 01833 mwTail = mw1; 01834 mwWrite("relink: heap truncated, MW-%p designated as new mwTail\n", mw1 ); 01835 mw1->next = NULL; 01836 mw1 = mw2 = NULL; 01837 } 01838 if( mw1 == NULL && mw2 == NULL && 01839 mwHead->prev == NULL && mwTail->next == NULL ) { 01840 mwWrite("relink: verifying heap integrity...\n" ); 01841 FLUSH(); 01842 goto verifyok; 01843 } 01844 if( mw1 && mw2 && mw1 != mw2 ) { 01845 mw1->next = mw2; 01846 mw2->prev = mw1; 01847 mwWrite("relink: emergency repairs successful, assessing damage...\n"); 01848 FLUSH(); 01849 } 01850 else { 01851 mwWrite("relink: heap totally destroyed, aborting program\n"); 01852 mwFlushW(1); 01853 FLUSH(); 01854 abort(); 01855 } 01856 01857 /* Verify by checking that the number of active allocations */ 01858 /* match the number of entries in the chain */ 01859 verifyok: 01860 if( !mwIsHeapOK( NULL ) ) { 01861 mwWrite("relink: heap verification FAILS - aborting program\n"); 01862 mwFlushW(1); 01863 FLUSH(); 01864 abort(); 01865 } 01866 for( size=count=0, mw1=mwHead; mw1; mw1=mw1->next ) { 01867 count ++; 01868 size += (long) mw1->size; 01869 } 01870 if( count == mwNumCurAlloc ) { 01871 mwWrite("relink: successful, "); 01872 if( size == mwStatCurAlloc ) { 01873 mwWrite("no allocations lost\n"); 01874 } 01875 else { 01876 if( mw != NULL ) { 01877 mwWrite("size information lost for MW-%p\n", mw); 01878 mw->size = 0; 01879 } 01880 } 01881 } 01882 else { 01883 mwWrite("relink: partial, %ld MW-blocks of %ld bytes lost\n", 01884 mwNmlNumAlloc+mwNumCurAlloc-count, mwNmlCurAlloc+mwStatCurAlloc-size ); 01885 return 0; 01886 } 01887 01888 return 1; 01889 }
void mwSetAriAction | ( | int | action | ) |
Definition at line 1220 of file KalFitMemLeak.c.
References MW_MUTEX_LOCK, MW_MUTEX_UNLOCK, mwAriAction, and TESTS.
01220 { 01221 MW_MUTEX_LOCK(); 01222 TESTS(NULL,0); 01223 mwAriAction = action; 01224 MW_MUTEX_UNLOCK(); 01225 return; 01226 }
void mwSetAriFunc | ( | int(*)(const char *) | func | ) |
Definition at line 854 of file KalFitMemLeak.c.
References mwAriFunction, and mwAutoInit().
00854 { 00855 mwAutoInit(); 00856 mwAriFunction = func; 00857 }
void mwSetOutFunc | ( | void(*)(int) | func | ) |
Definition at line 655 of file KalFitMemLeak.c.
References mwAutoInit(), and mwOutFunction.
00655 { 00656 mwAutoInit(); 00657 mwOutFunction = func; 00658 }
static void mwStatAlloc | ( | size_t | , | |
const char * | , | |||
int | ||||
) | [static] |
Definition at line 2326 of file KalFitMemLeak.c.
References mwStat_::curr, mwStat_::max, mwStatGet(), mwStatLevel, mwStat_::num, and mwStat_::total.
Referenced by mwMalloc().
02326 { 02327 mwStat* ms; 02328 02329 /* update the module statistics */ 02330 ms = mwStatGet( file, -1, 1 ); 02331 if( ms != NULL ) { 02332 ms->total += (long) size; 02333 ms->curr += (long) size; 02334 ms->num ++; 02335 if( ms->curr > ms->max ) ms->max = ms->curr; 02336 } 02337 02338 /* update the line statistics */ 02339 if( mwStatLevel > 1 && line != -1 && file ) { 02340 ms = mwStatGet( file, line, 1 ); 02341 if( ms != NULL ) { 02342 ms->total += (long) size; 02343 ms->curr += (long) size; 02344 ms->num ++; 02345 if( ms->curr > ms->max ) ms->max = ms->curr; 02346 } 02347 } 02348 02349 }
static void mwStatFree | ( | size_t | , | |
const char * | , | |||
int | ||||
) | [static] |
Definition at line 2351 of file KalFitMemLeak.c.
References mwStat_::curr, mwStatGet(), and mwStatLevel.
Referenced by mwFree().
02351 { 02352 mwStat* ms; 02353 02354 /* update the module statistics */ 02355 ms = mwStatGet( file, -1, 1 ); 02356 if( ms != NULL ) ms->curr -= (long) size; 02357 02358 /* update the line statistics */ 02359 if( mwStatLevel > 1 && line != -1 && file ) { 02360 ms = mwStatGet( file, line, 1 ); 02361 if( ms != NULL ) ms->curr -= (long) size; 02362 } 02363 }
static mwStat * mwStatGet | ( | const char * | , | |
int | , | |||
int | ||||
) | [static] |
Definition at line 2288 of file KalFitMemLeak.c.
References mwStat_::file, mwStat_::line, mwStatLevel, mwStatList, and mwStat_::next.
Referenced by mwIsOwned(), mwStatAlloc(), and mwStatFree().
02288 { 02289 mwStat* ms; 02290 02291 if( mwStatLevel < 2 ) line = -1; 02292 02293 for( ms=mwStatList; ms!=NULL; ms=ms->next ) { 02294 if( line != ms->line ) continue; 02295 if( file==NULL ) { 02296 if( ms->file == NULL ) break; 02297 continue; 02298 } 02299 if( ms->file == NULL ) continue; 02300 if( !strcmp( ms->file, file ) ) break; 02301 } 02302 02303 if( ms != NULL ) return ms; 02304 02305 if( !makenew ) return NULL; 02306 02307 ms = (mwStat*) malloc( sizeof(mwStat) ); 02308 if( ms == NULL ) { 02309 if( mwFreeUp( sizeof(mwStat), 0 ) < sizeof(mwStat) || 02310 (ms=(mwStat*)malloc(sizeof(mwStat))) == NULL ) { 02311 mwWrite("internal: memory low, statistics incomplete for '%s'\n", file ); 02312 return NULL; 02313 } 02314 } 02315 ms->file = file; 02316 ms->line = line; 02317 ms->total = 0L; 02318 ms->max = 0L; 02319 ms->num = 0L; 02320 ms->curr = 0L; 02321 ms->next = mwStatList; 02322 mwStatList = ms; 02323 return ms; 02324 }
void mwStatistics | ( | int | level | ) |
Definition at line 637 of file KalFitMemLeak.c.
References mwAutoInit(), mwStatLevel, and mwWrite().
00638 { 00639 mwAutoInit(); 00640 if( level<0 ) level=0; 00641 if( mwStatLevel != level ) 00642 { 00643 mwWrite( "statistics: now collecting on a %s basis\n", 00644 level<1?"global":(level<2?"module":"line") ); 00645 mwStatLevel = level; 00646 } 00647 }
static void mwStatReport | ( | void | ) | [static] |
Definition at line 2240 of file KalFitMemLeak.c.
References mwStat_::curr, mwStat_::file, FLUSH, mwStat_::line, mwStat_::max, mwIsReadAddr(), mwStatCurAlloc, mwStatLevel, mwStatList, mwStatMaxAlloc, mwStatNumAlloc, mwStatTotAlloc, mwStrCmpI(), mwWrite(), mwStat_::next, mwStat_::num, and mwStat_::total.
Referenced by mwAbort().
02241 { 02242 mwStat* ms, *ms2; 02243 const char *modname; 02244 int modnamelen; 02245 02246 /* global statistics report */ 02247 mwWrite( "\nMemory usage statistics (global):\n" ); 02248 mwWrite( " N)umber of allocations made: %ld\n", mwStatNumAlloc ); 02249 mwWrite( " L)argest memory usage : %ld\n", mwStatMaxAlloc ); 02250 mwWrite( " T)otal of all alloc() calls: %ld\n", mwStatTotAlloc ); 02251 mwWrite( " U)nfreed bytes totals : %ld\n", mwStatCurAlloc ); 02252 FLUSH(); 02253 02254 if( mwStatLevel < 1 ) return; 02255 02256 /* on a per-module basis */ 02257 mwWrite( "\nMemory usage statistics (detailed):\n"); 02258 mwWrite( " Module/Line Number Largest Total Unfreed \n"); 02259 for( ms=mwStatList; ms; ms=ms->next ) 02260 { 02261 if( ms->line == -1 ) 02262 { 02263 if( ms->file == NULL || !mwIsReadAddr(ms->file,22) ) modname = "<unknown>"; 02264 else modname = ms->file; 02265 modnamelen = strlen(modname); 02266 if( modnamelen > 42 ) 02267 { 02268 modname = modname + modnamelen - 42; 02269 } 02270 02271 mwWrite(" %-42s %-8ld %-8ld %-8ld %-8ld\n", 02272 modname, ms->num, ms->max, ms->total, ms->curr ); 02273 if( ms->file && mwStatLevel > 1 ) 02274 { 02275 for( ms2=mwStatList; ms2; ms2=ms2->next ) 02276 { 02277 if( ms2->line!=-1 && ms2->file!=NULL && !mwStrCmpI( ms2->file, ms->file ) ) 02278 { 02279 mwWrite( " %-8d %-8ld %-8ld %-8ld %-8ld\n", 02280 ms2->line, ms2->num, ms2->max, ms2->total, ms2->curr ); 02281 } 02282 } 02283 } 02284 } 02285 } 02286 }
static int mwStrCmpI | ( | const char * | s1, | |
const char * | s2 | |||
) | [static] |
Definition at line 2143 of file KalFitMemLeak.c.
Referenced by mwStatReport().
02143 { 02144 if( s1 == NULL || s2 == NULL ) return 0; 02145 while( *s1 ) { 02146 if( toupper(*s2) == toupper(*s1) ) { s1++; s2++; continue; } 02147 return 1; 02148 } 02149 return 0; 02150 }
char* mwStrdup | ( | const char * | str, | |
const char * | file, | |||
int | line | |||
) |
Definition at line 1029 of file KalFitMemLeak.c.
References FLUSH, MW_MUTEX_LOCK, MW_MUTEX_UNLOCK, mwCounter, mwIncErr(), mwMalloc, and mwWrite().
01029 { 01030 size_t len; 01031 char *newstring; 01032 01033 MW_MUTEX_LOCK(); 01034 01035 if( str == NULL ) { 01036 mwIncErr(); 01037 mwWrite( "strdup: <%ld> %s(%d), strdup(NULL) called\n", 01038 mwCounter, file, line ); 01039 FLUSH(); 01040 MW_MUTEX_UNLOCK(); 01041 return NULL; 01042 } 01043 01044 len = strlen( str ) + 1; 01045 newstring = (char*) mwMalloc( len, file, line ); 01046 if( newstring != NULL ) memcpy( newstring, str, len ); 01047 MW_MUTEX_UNLOCK(); 01048 return newstring; 01049 }
void mwTerm | ( | void | ) |
Definition at line 625 of file KalFitMemLeak.c.
References mwAbort(), mwInited, and mwWrite().
00625 { 00626 if( mwInited == 1 ) 00627 { 00628 mwAbort(); 00629 return; 00630 } 00631 if( !mwInited ) 00632 mwWrite("internal: mwTerm(): MEMWATCH has not been started!\n"); 00633 else 00634 mwInited --; 00635 }
int mwTest | ( | const char * | file, | |
int | line, | |||
int | items | |||
) |
Definition at line 685 of file KalFitMemLeak.c.
References mwAutoInit(), mwTestFlags, and mwTestNow().
00685 { 00686 mwAutoInit(); 00687 mwTestFlags = items; 00688 return mwTestNow( file, line, 0 ); 00689 }
static int mwTestBuf | ( | mwData * | mw, | |
const char * | file, | |||
int | line | |||
) | [static] |
Definition at line 1990 of file KalFitMemLeak.c.
References CHKVAL, mw, mwCheckOF(), mwCounter, mwDataSize, mwIncErr(), mwIsReadAddr(), mwIsSafeAddr(), mwOverflowZoneSize, mwRelink(), and mwWrite().
Referenced by mwFree(), mwTestBuffer(), and mwTestNow().
01990 { 01991 int retv = 0; 01992 char *p; 01993 01994 if( file == NULL ) file = "unknown"; 01995 01996 if( !mwIsSafeAddr( mw, mwDataSize + mwOverflowZoneSize ) ) { 01997 mwWrite( "internal: <%ld> %s(%d): pointer MW-%p is invalid\n", 01998 mwCounter, file, line, mw ); 01999 mwIncErr(); 02000 return 2; 02001 } 02002 02003 if( mw->check != CHKVAL(mw) ) { 02004 mwWrite( "internal: <%ld> %s(%d), info trashed; relinking\n", 02005 mwCounter, file, line ); 02006 mwIncErr(); 02007 if( !mwRelink( mw, file, line ) ) return 2; 02008 } 02009 02010 if( mw->prev && mw->prev->next != mw ) { 02011 mwWrite( "internal: <%ld> %s(%d), buffer <%ld> %s(%d) link1 broken\n", 02012 mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line ); 02013 mwIncErr(); 02014 if( !mwRelink( mw, file, line ) ) retv = 2; 02015 } 02016 if( mw->next && mw->next->prev != mw ) { 02017 mwWrite( "internal: <%ld> %s(%d), buffer <%ld> %s(%d) link2 broken\n", 02018 mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line ); 02019 mwIncErr(); 02020 if( !mwRelink( mw, file, line ) ) retv = 2; 02021 } 02022 02023 p = ((char*)mw) + mwDataSize; 02024 if( mwCheckOF( p ) ) { 02025 mwWrite( "underflow: <%ld> %s(%d), %ld bytes alloc'd at <%ld> %s(%d)\n", 02026 mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line ); 02027 mwIncErr(); 02028 retv = 1; 02029 } 02030 p += mwOverflowZoneSize + mw->size; 02031 if( mwIsReadAddr( p, mwOverflowZoneSize ) && mwCheckOF( p ) ) { 02032 mwWrite( "overflow: <%ld> %s(%d), %ld bytes alloc'd at <%ld> %s(%d)\n", 02033 mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line ); 02034 mwIncErr(); 02035 retv = 1; 02036 } 02037 02038 return retv; 02039 }
int mwTestBuffer | ( | const char * | file, | |
int | line, | |||
void * | p | |||
) |
Definition at line 695 of file KalFitMemLeak.c.
References mw, mwAutoInit(), mwBUFFER_TO_MW, mwIsOwned(), and mwTestBuf().
00695 { 00696 mwData* mw; 00697 00698 mwAutoInit(); 00699 00700 /* do the quick ownership test */ 00701 mw = (mwData*) mwBUFFER_TO_MW( p ); 00702 00703 if( mwIsOwned( mw, file, line ) ) { 00704 return mwTestBuf( mw, file, line ); 00705 } 00706 return 1; 00707 }
static const void * mwTestMem | ( | const void * | , | |
unsigned | , | |||
int | ||||
) | [static] |
Definition at line 2133 of file KalFitMemLeak.c.
Referenced by mwAbort(), mwDrop_(), mwFreeUp(), and mwTestNow().
02133 { 02134 const unsigned char *ptr; 02135 ptr = (const unsigned char *) p; 02136 while( len-- ) { 02137 if( *ptr != (unsigned char)c ) return (const void*)ptr; 02138 ptr ++; 02139 } 02140 return NULL; 02141 }
static int mwTestNow | ( | const char * | file, | |
int | line, | |||
int | always_invoked | |||
) | [static] |
Definition at line 2154 of file KalFitMemLeak.c.
References AIPH, mw, MW_NML, MW_TEST_ALLOC, MW_TEST_CHAIN, MW_TEST_NML, MW_VAL_NML, mwCounter, mwDataSize, mwHead, mwIncErr(), mwIsSafeAddr(), mwOverflowZoneSize, mwTail, mwTestBuf(), mwTestFlags, mwTestMem(), and mwWrite().
Referenced by mwAssert(), mwTest(), and mwVerify().
02154 { 02155 int retv = 0; 02156 mwData *mw; 02157 char *data; 02158 02159 if( file && !always_invoked ) 02160 mwWrite("check: <%ld> %s(%d), checking %s%s%s\n", 02161 mwCounter, file, line, 02162 (mwTestFlags & MW_TEST_CHAIN) ? "chain ": "", 02163 (mwTestFlags & MW_TEST_ALLOC) ? "alloc ": "", 02164 (mwTestFlags & MW_TEST_NML) ? "nomansland ": "" 02165 ); 02166 02167 if( mwTestFlags & MW_TEST_CHAIN ) { 02168 for( mw = mwHead; mw; mw=mw->next ) { 02169 if( !mwIsSafeAddr(mw, mwDataSize) ) { 02170 AIPH(); 02171 mwWrite("check: heap corruption detected\n"); 02172 mwIncErr(); 02173 return retv + 1; 02174 } 02175 if( mw->prev ) { 02176 if( !mwIsSafeAddr(mw->prev, mwDataSize) ) { 02177 AIPH(); 02178 mwWrite("check: heap corruption detected\n"); 02179 mwIncErr(); 02180 return retv + 1; 02181 } 02182 if( mw==mwHead || mw->prev->next != mw ) { 02183 AIPH(); 02184 mwWrite("check: heap chain broken, prev link incorrect\n"); 02185 mwIncErr(); 02186 retv ++; 02187 } 02188 } 02189 if( mw->next ) { 02190 if( !mwIsSafeAddr(mw->next, mwDataSize) ) { 02191 AIPH(); 02192 mwWrite("check: heap corruption detected\n"); 02193 mwIncErr(); 02194 return retv + 1; 02195 } 02196 if( mw==mwTail || mw->next->prev != mw ) { 02197 AIPH(); 02198 mwWrite("check: heap chain broken, next link incorrect\n"); 02199 mwIncErr(); 02200 retv ++; 02201 } 02202 } 02203 else if( mw!=mwTail ) { 02204 AIPH(); 02205 mwWrite("check: heap chain broken, tail incorrect\n"); 02206 mwIncErr(); 02207 retv ++; 02208 } 02209 } 02210 } 02211 if( mwTestFlags & MW_TEST_ALLOC ) { 02212 for( mw = mwHead; mw; mw=mw->next ) { 02213 if( mwTestBuf( mw, file, line ) ) retv ++; 02214 } 02215 } 02216 if( mwTestFlags & MW_TEST_NML ) { 02217 for( mw = mwHead; mw; mw=mw->next ) { 02218 if( (mw->flag & MW_NML) ) { 02219 data = ((char*)mw)+mwDataSize+mwOverflowZoneSize; 02220 if( mwTestMem( data, mw->size, MW_VAL_NML ) ) { 02221 mwIncErr(); 02222 mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n", 02223 mw->count, data + mwOverflowZoneSize, mw->file, mw->line ); 02224 } 02225 } 02226 } 02227 } 02228 02229 02230 if( file && !always_invoked && !retv ) 02231 mwWrite("check: <%ld> %s(%d), complete; no errors\n", 02232 mwCounter, file, line ); 02233 return retv; 02234 }
void mwTrace | ( | const char * | format, | |
... | ||||
) |
Definition at line 1343 of file KalFitMemLeak.c.
References FLUSH, MW_MUTEX_LOCK, MW_MUTEX_UNLOCK, MW_TRACE_BUFFER, mwAutoInit(), mwDefaultOutFunc(), mwIncErr(), mwOutFunction, mwPrintBuf, mwTrace, and TESTS.
01343 { 01344 int tot, oflow = 0; 01345 va_list mark; 01346 01347 mwAutoInit(); 01348 MW_MUTEX_LOCK(); 01349 TESTS(NULL,0); 01350 if( mwOutFunction == NULL ) mwOutFunction = mwDefaultOutFunc; 01351 01352 va_start( mark, format ); 01353 tot = vsprintf( mwPrintBuf, format, mark ); 01354 va_end( mark ); 01355 if( tot >= MW_TRACE_BUFFER ) { mwPrintBuf[MW_TRACE_BUFFER] = 0; oflow = 1; } 01356 for(tot=0;mwPrintBuf[tot];tot++) 01357 (*mwOutFunction)( mwPrintBuf[tot] ); 01358 if( oflow ) { 01359 mwIncErr(); 01360 mwTrace( " [WARNING: OUTPUT BUFFER OVERFLOW - SYSTEM UNSTABLE]\n" ); 01361 } 01362 01363 FLUSH(); 01364 MW_MUTEX_UNLOCK(); 01365 }
static void mwUnlink | ( | mwData * | , | |
const char * | file, | |||
int | line | |||
) | [static] |
Definition at line 1573 of file KalFitMemLeak.c.
References mw, mwCounter, mwHead, mwTail, and mwWrite().
Referenced by mwAbort(), mwFree(), and mwFreeUp().
01573 { 01574 if( mw->prev == NULL ) { 01575 if( mwHead != mw ) 01576 mwWrite( "internal: <%ld> %s(%d), MW-%p: link1 NULL, but not head\n", 01577 mwCounter, file, line, mw ); 01578 mwHead = mw->next; 01579 } 01580 else { 01581 if( mw->prev->next != mw ) 01582 mwWrite( "internal: <%ld> %s(%d), MW-%p: link1 failure\n", 01583 mwCounter, file, line, mw ); 01584 else mw->prev->next = mw->next; 01585 } 01586 if( mw->next == NULL ) { 01587 if( mwTail != mw ) 01588 mwWrite( "internal: <%ld> %s(%d), MW-%p: link2 NULL, but not tail\n", 01589 mwCounter, file, line, mw ); 01590 mwTail = mw->prev; 01591 } 01592 else { 01593 if( mw->next->prev != mw ) 01594 mwWrite( "internal: <%ld> %s(%d), MW-%p: link2 failure\n", 01595 mwCounter, file, line, mw ); 01596 else mw->next->prev = mw->prev; 01597 } 01598 }
void* mwUnmark | ( | void * | p, | |
const char * | file, | |||
unsigned | line | |||
) |
Definition at line 804 of file KalFitMemLeak.c.
References mwMarker_::host, mwMarker_::level, mwFirstMark, mwWrite(), mwMarker_::next, and mwMarker_::text.
00804 { 00805 mwMarker *mrk, *prv; 00806 mrk = mwFirstMark; 00807 prv = NULL; 00808 while( mrk ) { 00809 if( mrk->host == p ) { 00810 if( mrk->level < 2 ) { 00811 if( prv ) prv->next = mrk->next; 00812 else mwFirstMark = mrk->next; 00813 free( mrk->text ); 00814 free( mrk ); 00815 return p; 00816 } 00817 mrk->level --; 00818 return p; 00819 } 00820 prv = mrk; 00821 mrk = mrk->next; 00822 } 00823 mwWrite("mark: %s(%d), no mark found for %p\n", file, line, p ); 00824 return p; 00825 }
int mwVerify | ( | int | exp, | |
const char * | exps, | |||
const char * | fn, | |||
int | ln | |||
) |
Definition at line 1287 of file KalFitMemLeak.c.
References FLUSH, genRecEmupikp::i, MW_ARI_IGNORE, MW_ARI_NULLREAD, MW_MUTEX_LOCK, MW_MUTEX_UNLOCK, MW_TRACE_BUFFER, mwAriAction, mwAriFunction, mwAutoInit(), mwCounter, mwDummy(), mwIncErr(), mwSTDERR, mwTestNow(), mwWrite(), and TESTS.
01287 { 01288 int i; 01289 char buffer[MW_TRACE_BUFFER+8]; 01290 if( exp ) { 01291 return 0; 01292 } 01293 mwAutoInit(); 01294 MW_MUTEX_LOCK(); 01295 TESTS(fn,ln); 01296 mwIncErr(); 01297 mwCounter++; 01298 mwWrite( "verify trap: <%ld> %s(%d), %s\n", mwCounter, fn, ln, exps ); 01299 if( mwAriFunction != NULL ) { 01300 sprintf( buffer, "MEMWATCH: verify trap: %s(%d), %s", fn, ln, exps ); 01301 i = (*mwAriFunction)(buffer); 01302 if( i == 0 ) { 01303 mwWrite( "verify trap: <%ld> IGNORED - execution continues\n", mwCounter ); 01304 MW_MUTEX_UNLOCK(); 01305 return 0; 01306 } 01307 if( i == 1 ) { 01308 mwWrite( "verify trap: <%ld> RETRY - executing again\n", mwCounter ); 01309 MW_MUTEX_UNLOCK(); 01310 return 1; 01311 } 01312 } 01313 else { 01314 if( mwAriAction & MW_ARI_NULLREAD ) { 01315 /* This is made in an attempt to kick in */ 01316 /* any debuggers or OS stack traces */ 01317 FLUSH(); 01318 /*lint -save -e413 */ 01319 i = *((int*)NULL); 01320 mwDummy( (char)i ); 01321 /*lint -restore */ 01322 } 01323 if( mwAriAction & MW_ARI_IGNORE ) { 01324 mwWrite( "verify trap: <%ld> AUTO IGNORED - execution continues\n", mwCounter ); 01325 MW_MUTEX_UNLOCK(); 01326 return 0; 01327 } 01328 fprintf(mwSTDERR,"\nMEMWATCH: verify trap: %s(%d), %s\n", fn, ln, exps ); 01329 } 01330 FLUSH(); 01331 (void) mwTestNow( fn, ln, 1 ); 01332 FLUSH(); 01333 MW_MUTEX_UNLOCK(); 01334 exit(255); 01335 /* NOT REACHED - the return statement is in to keep */ 01336 /* stupid compilers from squeaking about differing return modes. */ 01337 /* Smart compilers instead say 'code unreachable...' */ 01338 /*lint -save -e527 */ 01339 return 0; 01340 /*lint -restore */ 01341 }
static void mwWrite | ( | const char * | format, | |
... | ||||
) | [static] |
Definition at line 2045 of file KalFitMemLeak.c.
References FLUSH, MW_TRACE_BUFFER, mwAutoInit(), mwDefaultOutFunc(), mwOutFunction, and mwPrintBuf.
Referenced by mwAbort(), mwAssert(), mwBreakOut(), mwDrop_(), mwDropAll(), mwFlushR(), mwFree(), mwFreeUp(), mwGrab_(), mwInit(), mwIsOwned(), mwLimit(), mwLogFile(), mwLogR(), mwMalloc(), mwMark(), mwRealloc(), mwRelink(), mwStatistics(), mwStatReport(), mwStrdup(), mwTerm(), mwTestBuf(), mwTestNow(), mwUnlink(), mwUnmark(), and mwVerify().
02045 { 02046 int tot, oflow = 0; 02047 va_list mark; 02048 mwAutoInit(); 02049 if( mwOutFunction == NULL ) mwOutFunction = mwDefaultOutFunc; 02050 va_start( mark, format ); 02051 tot = vsprintf( mwPrintBuf, format, mark ); 02052 va_end( mark ); 02053 if( tot >= MW_TRACE_BUFFER ) { mwPrintBuf[MW_TRACE_BUFFER] = 0; oflow = 1; } 02054 for(tot=0;mwPrintBuf[tot];tot++) 02055 (*mwOutFunction)( mwPrintBuf[tot] ); 02056 if( oflow ) { 02057 mwWrite( "\ninternal: mwWrite(): WARNING! OUTPUT EXCEEDED %u CHARS: SYSTEM UNSTABLE\n", MW_TRACE_BUFFER-1 ); 02058 FLUSH(); 02059 } 02060 return; 02061 }
static void mwWriteOF | ( | void * | p | ) | [static] |
Definition at line 660 of file KalFitMemLeak.c.
References genRecEmupikp::i, mwOverflowZoneSize, and mwOverflowZoneTemplate.
Referenced by mwMalloc().
00661 { 00662 int i; 00663 unsigned char *ptr; 00664 ptr = (unsigned char*) p; 00665 for( i=0; i<mwOverflowZoneSize; i++ ) 00666 { 00667 *(ptr+i) = mwOverflowZoneTemplate[i%8]; 00668 } 00669 return; 00670 }
long mwAllocLimit = 0L [static] |
Definition at line 317 of file KalFitMemLeak.c.
Referenced by mwGrab_(), mwLimit(), mwMalloc(), and mwRealloc().
int mwAriAction = MW_ARI_ABORT [static] |
Definition at line 329 of file KalFitMemLeak.c.
Referenced by mwAssert(), mwSetAriAction(), and mwVerify().
int(*) mwAriFunction(const char *) = NULL [static] |
Definition at line 328 of file KalFitMemLeak.c.
Referenced by mwAssert(), mwSetAriFunc(), and mwVerify().
unsigned long mwCounter = 0L [static] |
Definition at line 333 of file KalFitMemLeak.c.
int mwDataSize = 0 [static] |
Definition at line 323 of file KalFitMemLeak.c.
Referenced by mwAbort(), mwFree(), mwFreeUp(), mwInit(), mwIsHeapOK(), mwIsOwned(), mwMalloc(), mwRealloc(), mwRelink(), mwTestBuf(), and mwTestNow().
long mwErrors = 0L [static] |
int mwFBI = 0 [static] |
mwMarker* mwFirstMark = NULL [static] |
int mwFlushing = 0 [static] |
int mwFlushingB1 = 0 [static] |
int mwFlushingB2 = 0 [static] |
mwGrabData* mwGrabList = NULL [static] |
Definition at line 350 of file KalFitMemLeak.c.
Referenced by mwDrop_(), mwDropAll(), and mwGrab_().
long mwGrabSize = 0L [static] |
Definition at line 321 of file KalFitMemLeak.c.
Referenced by mwAbort(), mwFreeUp(), mwIsHeapOK(), mwIsOwned(), mwMalloc(), mwRelink(), mwTestNow(), and mwUnlink().
int mwInfoWritten = 0 [static] |
int mwInited = 0 [static] |
Definition at line 309 of file KalFitMemLeak.c.
Referenced by mwAbort(), mwAutoInit(), mwInit(), and mwTerm().
void* mwLastFree[MW_FREE_LIST] [static] |
int mwLFcur = 0 [static] |
const char* mwLFfile[MW_FREE_LIST] [static] |
int mwLFline[MW_FREE_LIST] [static] |
FILE* mwLog = NULL [static] |
FILE* mwLogB1 = NULL [static] |
FILE* mwLogB2 = NULL [static] |
int mwNML = MW_NML_DEFAULT [static] |
long mwNmlCurAlloc = 0L [static] |
long mwNmlNumAlloc = 0L [static] |
long mwNumCurAlloc = 0L [static] |
void(*) mwOutFunction(int) = NULL [static] |
Definition at line 327 of file KalFitMemLeak.c.
Referenced by mwSetOutFunc(), mwTrace(), and mwWrite().
int mwOverflowZoneSize = mwROUNDALLOC [static] |
Definition at line 325 of file KalFitMemLeak.c.
Referenced by mwAbort(), mwCheckOF(), mwFree(), mwFreeUp(), mwMalloc(), mwRealloc(), mwTestBuf(), mwTestNow(), and mwWriteOF().
unsigned char mwOverflowZoneTemplate[] = "mEmwAtch" [static] |
char mwPrintBuf[MW_TRACE_BUFFER+8] [static] |
long mwStatCurAlloc = 0L [static] |
Definition at line 346 of file KalFitMemLeak.c.
Referenced by mwFree(), mwGrab_(), mwInit(), mwIsOwned(), mwMalloc(), mwRealloc(), and mwStatReport().
int mwStatLevel = MW_STAT_DEFAULT [static] |
Definition at line 314 of file KalFitMemLeak.c.
Referenced by mwFree(), mwMalloc(), mwStatAlloc(), mwStatFree(), mwStatGet(), mwStatistics(), and mwStatReport().
mwStat* mwStatList = NULL [static] |
Definition at line 342 of file KalFitMemLeak.c.
Referenced by mwInit(), mwStatGet(), and mwStatReport().
long mwStatMaxAlloc = 0L [static] |
Definition at line 344 of file KalFitMemLeak.c.
Referenced by mwInit(), mwMalloc(), and mwStatReport().
long mwStatNumAlloc = 0L [static] |
Definition at line 345 of file KalFitMemLeak.c.
Referenced by mwInit(), mwMalloc(), and mwStatReport().
long mwStatTotAlloc = 0L [static] |
Definition at line 343 of file KalFitMemLeak.c.
Referenced by mwInit(), mwMalloc(), and mwStatReport().
Definition at line 322 of file KalFitMemLeak.c.
Referenced by mwAbort(), mwIsHeapOK(), mwIsOwned(), mwMalloc(), mwTestNow(), and mwUnlink().
int mwTestAlways = 0 [static] |
int mwTestFlags = 0 [static] |
Definition at line 336 of file KalFitMemLeak.c.
Referenced by mwAutoCheck(), mwTest(), and mwTestNow().
int mwUseAtexit = 0 [static] |
int mwUseLimit = 0 [static] |
Definition at line 318 of file KalFitMemLeak.c.
Referenced by mwGrab_(), mwLimit(), mwMalloc(), and mwRealloc().