/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Reconstruction/KalFitAlg/KalFitAlg-00-07-55-p03/src/KalFitMemLeak.c File Reference

#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 mwStatmwStatGet (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 mwDatamwHead = NULL
static mwDatamwTail = 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 mwStatmwStatList = 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 mwGrabDatamwGrabList = 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 mwMarkermwFirstMark = NULL
static FILE * mwLogB2 = NULL
static int mwFlushingB2 = 0


Define Documentation

#define __MEMWATCH_C   1

Definition at line 97 of file KalFitMemLeak.c.

 
#define AIPH (  )     if( always_invoked ) { mwWrite("autocheck: <%ld> %s(%d) ", mwCounter, file, line ); always_invoked = 0; }

Definition at line 2152 of file KalFitMemLeak.c.

Referenced by mwTestNow().

#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   ""

Definition at line 153 of file KalFitMemLeak.c.

Referenced by mwLogFile().

#define CPPTEXT   ""

Definition at line 159 of file KalFitMemLeak.c.

Referenced by mwInit().

 
#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 (  ) 

Definition at line 174 of file KalFitMemLeak.c.

Referenced by mwInit().

 
#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 (  ) 

Definition at line 175 of file KalFitMemLeak.c.

Referenced by mwAbort().

 
#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 (  )     ( (mwData*) (void*) ( ((char*)p)-mwDataSize-mwOverflowZoneSize ) )

Definition at line 145 of file KalFitMemLeak.c.

Referenced by mwFree(), mwRealloc(), and mwTestBuffer().

#define mwROUNDALLOC   mwROUNDALLOC_DEFAULT

Definition at line 217 of file KalFitMemLeak.c.

Referenced by mwFree(), and mwInit().

#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,
 )     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 139 of file KalFitMemLeak.c.

Referenced by mwInit().


Typedef Documentation

typedef struct mwData_ mwData

Definition at line 254 of file KalFitMemLeak.c.

typedef struct mwGrabData_ mwGrabData

Definition at line 282 of file KalFitMemLeak.c.

typedef struct mwMarker_ mwMarker

Definition at line 289 of file KalFitMemLeak.c.

typedef struct mwStat_ mwStat

Definition at line 270 of file KalFitMemLeak.c.


Function Documentation

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  ) 

Definition at line 709 of file KalFitMemLeak.c.

References mwSTDERR, and mwWrite().

Referenced by mwARI().

00709                                      {
00710     fprintf(mwSTDERR, "breakout: %s\n", cause);
00711     mwWrite("breakout: %s\n", cause );
00712     return;
00713     }

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]

Definition at line 2041 of file KalFitMemLeak.c.

References mwLogR().

Referenced by mwTrace(), and mwWrite().

02041                                       {
02042     if( mwLogR() ) fputc( c, mwLogR() );
02043     }

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]

Definition at line 2373 of file KalFitMemLeak.c.

Referenced by mwAssert(), and mwVerify().

02374 {
02375         return c;
02376 }

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   ) 

Definition at line 1191 of file KalFitMemLeak.c.

References mwLogR().

01191                         {
01192     if( mwLogR() ) fflush( mwLogR() );
01193     return;
01194     }

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().

01557                        {
01558     mwErrors++;
01559     mwFlushW( mwFlushR()+1 );
01560     FLUSH();
01561     }

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().

02492 {
02493     if( p == NULL ) return 0;
02494     if( len == 0 ) return 1;
02495     return 1;
02496 }

int mwIsSafeAddr ( void *  p,
unsigned  len 
)

Definition at line 2497 of file KalFitMemLeak.c.

Referenced by mwIsHeapOK(), mwIsOwned(), mwRelink(), mwTestBuf(), and mwTestNow().

02498 {
02499     if( p == NULL ) return 0;
02500     if( len == 0 ) return 1;
02501     return 1;
02502 }

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().

01534                               {
01535     mwLog = mwLogB1 = mwLogB2 = p;
01536     }

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 }


Variable Documentation

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]

Definition at line 334 of file KalFitMemLeak.c.

Referenced by mwAbort(), and mwIncErr().

int mwFBI = 0 [static]

Definition at line 316 of file KalFitMemLeak.c.

Referenced by mwFree().

mwMarker* mwFirstMark = NULL [static]

Definition at line 358 of file KalFitMemLeak.c.

Referenced by mwAbort(), mwMark(), and mwUnmark().

int mwFlushing = 0 [static]

Definition at line 313 of file KalFitMemLeak.c.

Referenced by mwFlushR(), and mwFlushW().

int mwFlushingB1 = 0 [static]

Definition at line 340 of file KalFitMemLeak.c.

Referenced by mwFlushR(), and mwFlushW().

int mwFlushingB2 = 0 [static]

Definition at line 361 of file KalFitMemLeak.c.

Referenced by mwFlushR(), and mwFlushW().

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 351 of file KalFitMemLeak.c.

Referenced by mwDrop_(), and mwGrab_().

mwData* mwHead = NULL [static]

Definition at line 321 of file KalFitMemLeak.c.

Referenced by mwAbort(), mwFreeUp(), mwIsHeapOK(), mwIsOwned(), mwMalloc(), mwRelink(), mwTestNow(), and mwUnlink().

int mwInfoWritten = 0 [static]

Definition at line 310 of file KalFitMemLeak.c.

Referenced by mwInit().

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]

Definition at line 353 of file KalFitMemLeak.c.

Referenced by mwFree(), and mwRealloc().

int mwLFcur = 0 [static]

Definition at line 356 of file KalFitMemLeak.c.

Referenced by mwFree().

const char* mwLFfile[MW_FREE_LIST] [static]

Definition at line 354 of file KalFitMemLeak.c.

Referenced by mwFree(), and mwRealloc().

int mwLFline[MW_FREE_LIST] [static]

Definition at line 355 of file KalFitMemLeak.c.

Referenced by mwFree(), and mwRealloc().

FILE* mwLog = NULL [static]

Definition at line 312 of file KalFitMemLeak.c.

Referenced by mwLogR(), and mwLogW().

FILE* mwLogB1 = NULL [static]

Definition at line 339 of file KalFitMemLeak.c.

Referenced by mwLogR(), and mwLogW().

FILE* mwLogB2 = NULL [static]

Definition at line 360 of file KalFitMemLeak.c.

Referenced by mwLogR(), and mwLogW().

int mwNML = MW_NML_DEFAULT [static]

Definition at line 315 of file KalFitMemLeak.c.

Referenced by mwFree(), and mwNoMansLand().

long mwNmlCurAlloc = 0L [static]

Definition at line 348 of file KalFitMemLeak.c.

Referenced by mwAbort(), mwFree(), and mwInit().

long mwNmlNumAlloc = 0L [static]

Definition at line 347 of file KalFitMemLeak.c.

Referenced by mwAbort(), mwFree(), and mwInit().

long mwNumCurAlloc = 0L [static]

Definition at line 320 of file KalFitMemLeak.c.

Referenced by mwFree(), and mwMalloc().

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]

Definition at line 324 of file KalFitMemLeak.c.

Referenced by mwCheckOF(), and mwWriteOF().

char mwPrintBuf[MW_TRACE_BUFFER+8] [static]

Definition at line 331 of file KalFitMemLeak.c.

Referenced by mwTrace(), and mwWrite().

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().

mwData* mwTail = NULL [static]

Definition at line 322 of file KalFitMemLeak.c.

Referenced by mwAbort(), mwIsHeapOK(), mwIsOwned(), mwMalloc(), mwTestNow(), and mwUnlink().

int mwTestAlways = 0 [static]

Definition at line 337 of file KalFitMemLeak.c.

Referenced by mwAutoCheck().

int mwTestFlags = 0 [static]

Definition at line 336 of file KalFitMemLeak.c.

Referenced by mwAutoCheck(), mwTest(), and mwTestNow().

int mwUseAtexit = 0 [static]

Definition at line 311 of file KalFitMemLeak.c.

Referenced by mwAutoInit(), and mwInit().

int mwUseLimit = 0 [static]

Definition at line 318 of file KalFitMemLeak.c.

Referenced by mwGrab_(), mwLimit(), mwMalloc(), and mwRealloc().


Generated on Tue Nov 29 23:16:53 2016 for BOSS_7.0.2 by  doxygen 1.4.7