BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
KalFitMemLeak.h File Reference
#include <stdlib.h>

Go to the source code of this file.

Macros

#define MW_ARI_NULLREAD   0x10 /* Null read (to start debugger) */
#define MW_ARI_ABORT   0x04 /* ARI handler says: abort program! */
#define MW_ARI_RETRY   0x02 /* ARI handler says: retry action! */
#define MW_ARI_IGNORE   0x01 /* ARI handler says: ignore error! */
#define MW_VAL_NEW   0xFE /* value in newly allocated memory */
#define MW_VAL_DEL   0xFD /* value in newly deleted memory */
#define MW_VAL_NML   0xFC /* value in no-mans-land */
#define MW_VAL_GRB   0xFB /* value in grabbed memory */
#define MW_TEST_ALL   0xFFFF /* perform all tests */
#define MW_TEST_CHAIN   0x0001 /* walk the heap chain */
#define MW_TEST_ALLOC   0x0002 /* test allocations & NML guards */
#define MW_TEST_NML   0x0004 /* test all-NML areas for modifications */
#define MW_NML_NONE   0 /* no NML */
#define MW_NML_FREE   1 /* turn FREE'd memory into NML */
#define MW_NML_ALL   2 /* all unused memory is NML */
#define MW_NML_DEFAULT   0 /* the default NML setting */
#define MW_STAT_GLOBAL   0 /* only global statistics collected */
#define MW_STAT_MODULE   1 /* collect statistics on a module basis */
#define MW_STAT_LINE   2 /* collect statistics on a line basis */
#define MW_STAT_DEFAULT   0 /* the default statistics setting */
#define MW_TRACE_BUFFER   2048 /* (min 160) size of TRACE()'s output buffer */
#define MW_FREE_LIST   64 /* (min 4) number of free()'s to track */
#define mwASSERT(exp)
#define ASSERT   mwASSERT
#define mwVERIFY(exp)
#define VERIFY   mwVERIFY
#define mwTRACE
#define TRACE   mwTRACE
#define mwDoFlush(n)
#define mwPuts(s)
#define mwInit()
#define mwGrab(n)
#define mwDrop(n)
#define mwLimit(n)
#define mwTest(f, l)
#define mwSetOutFunc(f)
#define mwSetAriFunc(f)
#define mwDefaultAri()
#define mwNomansland()
#define mwStatistics(f)
#define mwMark(p, t, f, n)
#define mwUnmark(p, f, n)
#define mwMalloc(n, f, l)
#define mwStrdup(p, f, l)
#define mwRealloc(p, n, f, l)
#define mwCalloc(n, m, f, l)
#define mwFree(p)
#define mwMalloc_(n)
#define mwRealloc_(p, n)
#define mwCalloc_(n, m)
#define mwFree_(p)
#define mwAssert(e, es, f, l)
#define mwVerify(e, es, f, l)
#define mwTrace   mwDummyTrace
#define mwTestBuffer(f, l, b)
#define CHECK()
#define CHECK_THIS(n)
#define CHECK_BUFFER(b)
#define MARK(p)
#define UNMARK(p)

Functions

void mwTerm (void)
void mwAbort (void)
void mwFlushNow (void)
void mwDoFlush (int onoff)
void mwLimit (long bytes)
unsigned mwGrab (unsigned kilobytes)
unsigned mwDrop (unsigned kilobytes)
void mwNoMansLand (int mw_nml_level)
void mwStatistics (int level)
void mwFreeBufferInfo (int onoff)
void mwAutoCheck (int onoff)
void mwCalcCheck (void)
void mwDumpCheck (void)
void * mwMark (void *p, const char *description, const char *file, unsigned line)
void * mwUnmark (void *p, const char *file, unsigned line)
int mwIsReadAddr (const void *p, unsigned len)
int mwIsSafeAddr (void *p, unsigned len)
int mwTest (const char *file, int line, int mw_test_flags)
int mwTestBuffer (const char *file, int line, void *p)
int mwAssert (int, const char *, const char *, int)
int mwVerify (int, const char *, const char *, int)
void mwTrace (const char *format_string,...)
void mwPuts (const char *text)
void mwSetOutFunc (void(*func)(int))
void mwSetAriFunc (int(*func)(const char *))
void mwSetAriAction (int mw_ari_value)
int mwAriHandler (const char *cause)
void mwBreakOut (const char *cause)
void * mwMalloc (size_t, const char *, int)
void * mwMalloc_ (size_t)
void * mwRealloc (void *, size_t, const char *, int)
void * mwRealloc_ (void *, size_t)
void * mwCalloc (size_t, size_t, const char *, int)
void * mwCalloc_ (size_t, size_t)
void mwFree (void *, const char *, int)
void mwFree_ (void *)
char * mwStrdup (const char *, const char *, int)
void mwDummyTraceFunction (const char *,...)

Variables

const unsigned long mwCounter

Macro Definition Documentation

◆ ASSERT

#define ASSERT   mwASSERT

◆ CHECK

#define CHECK ( )

◆ CHECK_BUFFER

#define CHECK_BUFFER ( b)

◆ CHECK_THIS

#define CHECK_THIS ( n)

◆ MARK

#define MARK ( p)

◆ MW_ARI_ABORT

#define MW_ARI_ABORT   0x04 /* ARI handler says: abort program! */

◆ MW_ARI_IGNORE

#define MW_ARI_IGNORE   0x01 /* ARI handler says: ignore error! */

◆ MW_ARI_NULLREAD

#define MW_ARI_NULLREAD   0x10 /* Null read (to start debugger) */

◆ MW_ARI_RETRY

#define MW_ARI_RETRY   0x02 /* ARI handler says: retry action! */

◆ MW_FREE_LIST

#define MW_FREE_LIST   64 /* (min 4) number of free()'s to track */

◆ MW_NML_ALL

#define MW_NML_ALL   2 /* all unused memory is NML */

◆ MW_NML_DEFAULT

#define MW_NML_DEFAULT   0 /* the default NML setting */

◆ MW_NML_FREE

#define MW_NML_FREE   1 /* turn FREE'd memory into NML */

◆ MW_NML_NONE

#define MW_NML_NONE   0 /* no NML */

◆ MW_STAT_DEFAULT

#define MW_STAT_DEFAULT   0 /* the default statistics setting */

◆ MW_STAT_GLOBAL

#define MW_STAT_GLOBAL   0 /* only global statistics collected */

◆ MW_STAT_LINE

#define MW_STAT_LINE   2 /* collect statistics on a line basis */

◆ MW_STAT_MODULE

#define MW_STAT_MODULE   1 /* collect statistics on a module basis */

◆ MW_TEST_ALL

#define MW_TEST_ALL   0xFFFF /* perform all tests */

◆ MW_TEST_ALLOC

#define MW_TEST_ALLOC   0x0002 /* test allocations & NML guards */

◆ MW_TEST_CHAIN

#define MW_TEST_CHAIN   0x0001 /* walk the heap chain */

◆ MW_TEST_NML

#define MW_TEST_NML   0x0004 /* test all-NML areas for modifications */

◆ MW_TRACE_BUFFER

#define MW_TRACE_BUFFER   2048 /* (min 160) size of TRACE()'s output buffer */

◆ MW_VAL_DEL

#define MW_VAL_DEL   0xFD /* value in newly deleted memory */

◆ MW_VAL_GRB

#define MW_VAL_GRB   0xFB /* value in grabbed memory */

◆ MW_VAL_NEW

#define MW_VAL_NEW   0xFE /* value in newly allocated memory */

◆ MW_VAL_NML

#define MW_VAL_NML   0xFC /* value in no-mans-land */

◆ mwASSERT

#define mwASSERT ( exp)

◆ mwAssert

#define mwAssert ( e,
es,
f,
l )

◆ mwCalloc

#define mwCalloc ( n,
m,
f,
l )
Value:
calloc( n, m )
const Int_t n

Definition at line 634 of file InstallArea/x86_64-el9-gcc13-dbg/include/KalFitAlg/KalFitMemLeak.h.

◆ mwCalloc_

#define mwCalloc_ ( n,
m )
Value:
calloc( n, m )

Definition at line 638 of file InstallArea/x86_64-el9-gcc13-dbg/include/KalFitAlg/KalFitMemLeak.h.

◆ mwDefaultAri

#define mwDefaultAri ( )

◆ mwDoFlush

#define mwDoFlush ( n)

◆ mwDrop

#define mwDrop ( n)

◆ mwFree

#define mwFree ( p)
Value:
free( p )

Definition at line 635 of file InstallArea/x86_64-el9-gcc13-dbg/include/KalFitAlg/KalFitMemLeak.h.

Referenced by mwRealloc().

◆ mwFree_

#define mwFree_ ( p)
Value:
free( p )

Definition at line 639 of file InstallArea/x86_64-el9-gcc13-dbg/include/KalFitAlg/KalFitMemLeak.h.

Referenced by mwFree().

◆ mwGrab

#define mwGrab ( n)

◆ mwInit

void mwInit ( )

◆ mwLimit

#define mwLimit ( n)

◆ mwMalloc

#define mwMalloc ( n,
f,
l )
Value:
malloc( n )

Definition at line 631 of file InstallArea/x86_64-el9-gcc13-dbg/include/KalFitAlg/KalFitMemLeak.h.

Referenced by mwCalloc(), mwRealloc(), and mwStrdup().

◆ mwMalloc_

#define mwMalloc_ ( n)
Value:
malloc( n )

Definition at line 636 of file InstallArea/x86_64-el9-gcc13-dbg/include/KalFitAlg/KalFitMemLeak.h.

◆ mwMark

#define mwMark ( p,
t,
f,
n )

◆ mwNomansland

#define mwNomansland ( )

◆ mwPuts

#define mwPuts ( s)

◆ mwRealloc

#define mwRealloc ( p,
n,
f,
l )
Value:
realloc( p, n )

Definition at line 633 of file InstallArea/x86_64-el9-gcc13-dbg/include/KalFitAlg/KalFitMemLeak.h.

◆ mwRealloc_

#define mwRealloc_ ( p,
n )
Value:
realloc( p, n )

Definition at line 637 of file InstallArea/x86_64-el9-gcc13-dbg/include/KalFitAlg/KalFitMemLeak.h.

◆ mwSetAriFunc

#define mwSetAriFunc ( f)

◆ mwSetOutFunc

#define mwSetOutFunc ( f)

◆ mwStatistics

#define mwStatistics ( f)

◆ mwStrdup

#define mwStrdup ( p,
f,
l )
Value:
strdup( p )

Definition at line 632 of file InstallArea/x86_64-el9-gcc13-dbg/include/KalFitAlg/KalFitMemLeak.h.

◆ mwTest

#define mwTest ( f,
l )

◆ mwTestBuffer

#define mwTestBuffer ( f,
l,
b )

◆ mwTRACE

#define mwTRACE
Value:
/*lint -save -e506 */ \
1 ? (void)0 : mwDummyTraceFunction /*lint -restore */
void mwDummyTraceFunction(const char *,...)

Definition at line 606 of file InstallArea/x86_64-el9-gcc13-dbg/include/KalFitAlg/KalFitMemLeak.h.

606# define mwTRACE /*lint -save -e506 */ \
607 1 ? (void)0 : mwDummyTraceFunction /*lint -restore */

◆ mwTrace

#define mwTrace   mwDummyTrace

◆ mwUnmark

#define mwUnmark ( p,
f,
n )

◆ mwVERIFY

#define mwVERIFY ( exp)
Value:
EvtComplex exp(const EvtComplex &c)

Definition at line 598 of file InstallArea/x86_64-el9-gcc13-dbg/include/KalFitAlg/KalFitMemLeak.h.

◆ mwVerify

#define mwVerify ( e,
es,
f,
l )

◆ TRACE

#define TRACE   mwTRACE

◆ UNMARK

#define UNMARK ( p)

◆ VERIFY

#define VERIFY   mwVERIFY

Function Documentation

◆ mwAbort()

void mwAbort ( void )

Definition at line 524 of file KalFitMemLeak.c.

524 {
525 mwData* mw;
526 mwMarker* mrk;
527 char* data;
528 time_t tid;
529 int c, i, j;
530 int errors;
531
532 tid = time( NULL );
533 mwWrite( "\nStopped at %s\n", ctime( &tid ) );
534
535 if ( !mwInited ) mwWrite( "internal: mwAbort(): MEMWATCH not initialized!\n" );
536
537 /* release the grab list */
538 mwDropAll();
539
540 /* report mwMarked items */
541 while ( mwFirstMark )
542 {
543 mrk = mwFirstMark->next;
544 mwWrite( "mark: %p: %s\n", mwFirstMark->host, mwFirstMark->text );
545 free( mwFirstMark->text );
546 free( mwFirstMark );
547 mwFirstMark = mrk;
548 mwErrors++;
549 }
550
551 /* release all still allocated memory */
552 errors = 0;
553 while ( mwHead != NULL && errors < 3 )
554 {
555 if ( !mwIsOwned( mwHead, __FILE__, __LINE__ ) )
556 {
557 if ( errors < 3 )
558 {
559 errors++;
560 mwWrite( "internal: NML/unfreed scan restarting\n" );
561 FLUSH();
562 mwHead = mwHead;
563 continue;
564 }
565 mwWrite( "internal: NML/unfreed scan aborted, heap too damaged\n" );
566 FLUSH();
567 break;
568 }
569 mwFlushW( 0 );
570 if ( !( mwHead->flag & MW_NML ) )
571 {
572 mwErrors++;
573 data = ( (char*)mwHead ) + mwDataSize;
574 mwWrite( "unfreed: <%ld> %s(%d), %ld bytes at %p ", mwHead->count, mwHead->file,
575 mwHead->line, (long)mwHead->size, data + mwOverflowZoneSize );
576 if ( mwCheckOF( data ) )
577 {
578 mwWrite( "[underflowed] " );
579 FLUSH();
580 }
581 if ( mwCheckOF( ( data + mwOverflowZoneSize + mwHead->size ) ) )
582 {
583 mwWrite( "[overflowed] " );
584 FLUSH();
585 }
586 mwWrite( " \t{" );
587 j = 16;
588 if ( mwHead->size < 16 ) j = (int)mwHead->size;
589 for ( i = 0; i < 16; i++ )
590 {
591 if ( i < j ) mwWrite( "%02X ", (unsigned char)*( data + mwOverflowZoneSize + i ) );
592 else mwWrite( ".. " );
593 }
594 for ( i = 0; i < j; i++ )
595 {
596 c = *( data + mwOverflowZoneSize + i );
597 if ( c < 32 || c > 126 ) c = '.';
598 mwWrite( "%c", c );
599 }
600 mwWrite( "}\n" );
601 mw = mwHead;
602 mwUnlink( mw, __FILE__, __LINE__ );
603 free( mw );
604 }
605 else
606 {
607 data = ( (char*)mwHead ) + mwDataSize + mwOverflowZoneSize;
608 if ( mwTestMem( data, mwHead->size, MW_VAL_NML ) )
609 {
610 mwErrors++;
611 mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n", mwHead->count,
612 data + mwOverflowZoneSize, mwHead->file, mwHead->line );
613 FLUSH();
614 }
615 mwNmlNumAlloc--;
616 mwNmlCurAlloc -= mwHead->size;
617 mw = mwHead;
618 mwUnlink( mw, __FILE__, __LINE__ );
619 free( mw );
620 }
621 }
622
623 if ( mwNmlNumAlloc )
624 mwWrite( "internal: NoMansLand block counter %ld, not zero\n", mwNmlNumAlloc );
625 if ( mwNmlCurAlloc )
626 mwWrite( "internal: NoMansLand byte counter %ld, not zero\n", mwNmlCurAlloc );
627
628 /* report statistics */
629 mwStatReport();
630 FLUSH();
631
632 mwInited = 0;
633 mwHead = mwTail = NULL;
634 if ( mwErrors ) fprintf( mwSTDERR, "MEMWATCH detected %ld anomalies\n", mwErrors );
635 mwLogFile( NULL );
636 mwErrors = 0;
637
639}
TTree * data
Double_t time
struct mwMarker_ mwMarker
#define MW_NML
#define MW_MUTEX_TERM()
#define mwSTDERR
#define FLUSH()
struct mwData_ mwData
mwMarker * next

Referenced by mwInit().

◆ mwAriHandler()

int mwAriHandler ( const char * cause)

Definition at line 869 of file KalFitMemLeak.c.

869 {
870 mwAutoInit();
871 return mwARI( estr );
872}

◆ mwAssert()

int mwAssert ( int exp,
const char * exps,
const char * fn,
int ln )

Definition at line 1266 of file KalFitMemLeak.c.

1266 {
1267 int i;
1268 char buffer[MW_TRACE_BUFFER + 8];
1269 if ( exp ) { return 0; }
1270 mwAutoInit();
1271 MW_MUTEX_LOCK();
1272 TESTS( fn, ln );
1273 mwIncErr();
1274 mwCounter++;
1275 mwWrite( "assert trap: <%ld> %s(%d), %s\n", mwCounter, fn, ln, exps );
1276 if ( mwAriFunction != NULL )
1277 {
1278 sprintf( buffer, "MEMWATCH: assert trap: %s(%d), %s", fn, ln, exps );
1279 i = ( *mwAriFunction )( buffer );
1280 switch ( i )
1281 {
1282 case MW_ARI_IGNORE:
1283 mwWrite( "assert trap: <%ld> IGNORED - execution continues\n", mwCounter );
1285 return 0;
1286 case MW_ARI_RETRY:
1287 mwWrite( "assert trap: <%ld> RETRY - executing again\n", mwCounter );
1289 return 1;
1290 }
1291 }
1292 else
1293 {
1294 if ( mwAriAction & MW_ARI_IGNORE )
1295 {
1296 mwWrite( "assert trap: <%ld> AUTO IGNORED - execution continues\n", mwCounter );
1298 return 0;
1299 }
1300 fprintf( mwSTDERR, "\nMEMWATCH: assert trap: %s(%d), %s\n", fn, ln, exps );
1301 }
1302
1303 FLUSH();
1304 (void)mwTestNow( fn, ln, 1 );
1305 FLUSH();
1306
1307 if ( mwAriAction & MW_ARI_NULLREAD )
1308 {
1309 /* This is made in an attempt to kick in */
1310 /* any debuggers or OS stack traces */
1311 FLUSH();
1312 /*lint -save -e413 */
1313 i = *( (int*)NULL );
1314 mwDummy( (char)i );
1315 /*lint -restore */
1316 }
1317
1319 exit( 255 );
1320 /* NOT REACHED - the return statement is in to keep */
1321 /* stupid compilers from squeaking about differing return modes. */
1322 /* Smart compilers instead say 'code unreachable...' */
1323 /*lint -save -e527 */
1324 return 0;
1325 /*lint -restore */
1326}
sprintf(cut, "kal_costheta0_em>-0.93&&kal_costheta0_em<0.93&&kal_pxy0_em>=0.05+%d*0.1&&kal_" "pxy0_em<0.15+%d*0.1&&NGch>=2", j, j)
const unsigned long mwCounter
#define MW_MUTEX_UNLOCK()
#define TESTS(f, l)
#define MW_MUTEX_LOCK()

◆ mwAutoCheck()

void mwAutoCheck ( int onoff)

Definition at line 662 of file KalFitMemLeak.c.

662 {
663 mwAutoInit();
664 mwTestAlways = onoff;
665 if ( onoff ) mwTestFlags = MW_TEST_ALL;
666}

◆ mwBreakOut()

void mwBreakOut ( const char * cause)

Definition at line 714 of file KalFitMemLeak.c.

714 {
715 fprintf( mwSTDERR, "breakout: %s\n", cause );
716 mwWrite( "breakout: %s\n", cause );
717 return;
718}

◆ mwCalcCheck()

void mwCalcCheck ( void )

◆ mwCalloc()

void * mwCalloc ( size_t a,
size_t b,
const char * file,
int line )

Definition at line 1189 of file KalFitMemLeak.c.

1189 {
1190 void* p;
1191 size_t size = a * b;
1192 p = mwMalloc( size, file, line );
1193 if ( p == NULL ) return NULL;
1194 memset( p, 0, size );
1195 return p;
1196}
char * file
Definition DQA_TO_DB.cxx:16

◆ mwCalloc_()

void * mwCalloc_ ( size_t a,
size_t b )

Definition at line 1219 of file KalFitMemLeak.c.

1219 {
1220 MW_MUTEX_LOCK();
1221 TESTS( NULL, 0 );
1223 return calloc( a, b );
1224}

◆ mwDoFlush()

void mwDoFlush ( int onoff)

Definition at line 1231 of file KalFitMemLeak.c.

1231 {
1232 mwFlushW( onoff < 1 ? 0 : onoff );
1233 if ( onoff )
1234 if ( mwLogR() ) fflush( mwLogR() );
1235 return;
1236}

◆ mwDrop()

unsigned mwDrop ( unsigned kilobytes)

Definition at line 1425 of file KalFitMemLeak.c.

1425 {
1426 TESTS( NULL, 0 );
1427 return mwDrop_( kb, MW_VAL_GRB, 0 );
1428}

◆ mwDummyTraceFunction()

void mwDummyTraceFunction ( const char * ,
... )
extern

◆ mwDumpCheck()

void mwDumpCheck ( void )

◆ mwFlushNow()

void mwFlushNow ( void )

Definition at line 1226 of file KalFitMemLeak.c.

1226 {
1227 if ( mwLogR() ) fflush( mwLogR() );
1228 return;
1229}

◆ mwFree()

void mwFree ( void * p,
const char * file,
int line )

Definition at line 1081 of file KalFitMemLeak.c.

1081 {
1082 int i;
1083 mwData* mw;
1084 char buffer[sizeof( mwData ) + ( mwROUNDALLOC * 3 ) + 64];
1085
1086 /* this code is in support of C++ delete */
1087 if ( file == NULL )
1088 {
1089 mwFree_( p );
1091 return;
1092 }
1093
1094 mwAutoInit();
1095
1096 MW_MUTEX_LOCK();
1097 TESTS( file, line );
1098 mwCounter++;
1099
1100 /* on NULL free, write a warning and return */
1101 if ( p == NULL )
1102 {
1103 mwWrite( "NULL free: <%ld> %s(%d), NULL pointer free'd\n", mwCounter, file, line );
1104 FLUSH();
1106 return;
1107 }
1108
1109 /* do the quick ownership test */
1110 mw = (mwData*)mwBUFFER_TO_MW( p );
1111
1112 if ( mwIsOwned( mw, file, line ) )
1113 {
1114 (void)mwTestBuf( mw, file, line );
1115
1116 /* if the buffer is an NML, treat this as a double-free */
1117 if ( mw->flag & MW_NML )
1118 {
1119 if ( *( ( (unsigned char*)mw ) + mwDataSize + mwOverflowZoneSize ) != MW_VAL_NML )
1120 {
1121 mwWrite( "internal: <%ld> %s(%d), no-mans-land MW-%p is corrupted\n", mwCounter, file,
1122 line, mw );
1123 }
1124 goto check_dbl_free;
1125 }
1126
1127 /* update the statistics */
1128 mwNumCurAlloc--;
1129 mwStatCurAlloc -= (long)mw->size;
1130 if ( mwStatLevel ) mwStatFree( mw->size, mw->file, mw->line );
1131
1132 /* we should either free the allocation or keep it as NML */
1133 if ( mwNML )
1134 {
1135 mw->flag |= MW_NML;
1136 mwNmlNumAlloc++;
1137 mwNmlCurAlloc += (long)mw->size;
1138 memset( ( (char*)mw ) + mwDataSize + mwOverflowZoneSize, MW_VAL_NML, mw->size );
1139 }
1140 else
1141 {
1142 /* unlink the allocation, and enter the post-free data */
1143 mwUnlink( mw, file, line );
1144 memset( mw, MW_VAL_DEL,
1145 mw->size + mwDataSize + mwOverflowZoneSize + mwOverflowZoneSize );
1146 if ( mwFBI )
1147 {
1148 memset( mw, '.', mwDataSize + mwOverflowZoneSize );
1149 sprintf( buffer, "FBI<%ld>%s(%d)", mwCounter, file, line );
1150 strncpy( (char*)(void*)mw, buffer, mwDataSize + mwOverflowZoneSize );
1151 }
1152 free( mw );
1153 }
1154
1155 /* add the pointer to the last-free track */
1156 mwLFfile[mwLFcur] = file;
1157 mwLFline[mwLFcur] = line;
1158 mwLastFree[mwLFcur++] = p;
1159 if ( mwLFcur == MW_FREE_LIST ) mwLFcur = 0;
1160
1162 return;
1163 }
1164
1165 /* check for double-freeing */
1166check_dbl_free:
1167 for ( i = 0; i < MW_FREE_LIST; i++ )
1168 {
1169 if ( mwLastFree[i] == p )
1170 {
1171 mwIncErr();
1172 mwWrite( "double-free: <%ld> %s(%d), %p was"
1173 " freed from %s(%d)\n",
1174 mwCounter, file, line, p, mwLFfile[i], mwLFline[i] );
1175 FLUSH();
1177 return;
1178 }
1179 }
1180
1181 /* some weird pointer... block the free */
1182 mwIncErr();
1183 mwWrite( "WILD free: <%ld> %s(%d), unknown pointer %p\n", mwCounter, file, line, p );
1184 FLUSH();
1186 return;
1187}
#define mwBUFFER_TO_MW(p)
#define mwROUNDALLOC
size_t size
const char * file
unsigned flag

◆ mwFree_()

void mwFree_ ( void * p)

Definition at line 1198 of file KalFitMemLeak.c.

1198 {
1199 MW_MUTEX_LOCK();
1200 TESTS( NULL, 0 );
1202 free( p );
1203}

◆ mwFreeBufferInfo()

void mwFreeBufferInfo ( int onoff)

◆ mwGrab()

unsigned mwGrab ( unsigned kilobytes)

Definition at line 1420 of file KalFitMemLeak.c.

1420 {
1421 TESTS( NULL, 0 );
1422 return mwGrab_( kb, MW_VAL_GRB, 0 );
1423}

◆ mwIsReadAddr()

int mwIsReadAddr ( const void * p,
unsigned len )

Definition at line 2617 of file KalFitMemLeak.c.

2617 {
2618 if ( p == NULL ) return 0;
2619 if ( len == 0 ) return 1;
2620 return 1;
2621}

Referenced by mwMark().

◆ mwIsSafeAddr()

int mwIsSafeAddr ( void * p,
unsigned len )

Definition at line 2622 of file KalFitMemLeak.c.

2622 {
2623 if ( p == NULL ) return 0;
2624 if ( len == 0 ) return 1;
2625 return 1;
2626}

◆ mwLimit()

void mwLimit ( long bytes)

Definition at line 1238 of file KalFitMemLeak.c.

1238 {
1239 TESTS( NULL, 0 );
1240 mwWrite( "limit: old limit = " );
1241 if ( !mwAllocLimit ) mwWrite( "none" );
1242 else mwWrite( "%ld bytes", mwAllocLimit );
1243 mwWrite( ", new limit = " );
1244 if ( !lim )
1245 {
1246 mwWrite( "none\n" );
1247 mwUseLimit = 0;
1248 }
1249 else
1250 {
1251 mwWrite( "%ld bytes\n", lim );
1252 mwUseLimit = 1;
1253 }
1254 mwAllocLimit = lim;
1255 FLUSH();
1256}

◆ mwMalloc()

void * mwMalloc ( size_t size,
const char * file,
int line )

Definition at line 884 of file KalFitMemLeak.c.

884 {
885 size_t needed;
886 mwData* mw;
887 char* ptr;
888 void* p;
889
890 mwAutoInit();
891
893
894 TESTS( file, line );
895
896 mwCounter++;
897 needed = mwDataSize + mwOverflowZoneSize * 2 + size;
898 if ( needed < size )
899 {
900 /* theoretical case: req size + mw overhead exceeded size_t limits */
901 return NULL;
902 }
903
904 /* if this allocation would violate the limit, fail it */
905 if ( mwUseLimit && ( (long)size + mwStatCurAlloc > mwAllocLimit ) )
906 {
907 mwWrite( "limit fail: <%ld> %s(%d), %ld wanted %ld available\n", mwCounter, file, line,
908 (long)size, mwAllocLimit - mwStatCurAlloc );
909 mwIncErr();
910 FLUSH();
912 return NULL;
913 }
914
915 mw = (mwData*)malloc( needed );
916 if ( mw == NULL )
917 {
918 if ( mwFreeUp( needed, 0 ) >= needed )
919 {
920 mw = (mwData*)malloc( needed );
921 if ( mw == NULL )
922 {
923 mwWrite( "internal: mwFreeUp(%u) reported success, but malloc() fails\n", needed );
924 mwIncErr();
925 FLUSH();
926 }
927 }
928 if ( mw == NULL )
929 {
930 mwWrite( "fail: <%ld> %s(%d), %ld wanted %ld allocated\n", mwCounter, file, line,
931 (long)size, mwStatCurAlloc );
932 mwIncErr();
933 FLUSH();
935 return NULL;
936 }
937 }
938
939 mw->count = mwCounter;
940 mw->prev = NULL;
941 mw->next = mwHead;
942 mw->file = file;
943 mw->size = size;
944 mw->line = line;
945 mw->flag = 0;
946 mw->check = CHKVAL( mw );
947
948 if ( mwHead ) mwHead->prev = mw;
949 mwHead = mw;
950 if ( mwTail == NULL ) mwTail = mw;
951
952 ptr = ( (char*)mw ) + mwDataSize;
953 mwWriteOF( ptr ); /* '*(long*)ptr = PRECHK;' */
954 ptr += mwOverflowZoneSize;
955 p = ptr;
956 memset( ptr, MW_VAL_NEW, size );
957 ptr += size;
958 mwWriteOF( ptr ); /* '*(long*)ptr = POSTCHK;' */
959
960 mwNumCurAlloc++;
961 mwStatCurAlloc += (long)size;
962 mwStatTotAlloc += (long)size;
963 if ( mwStatCurAlloc > mwStatMaxAlloc ) mwStatMaxAlloc = mwStatCurAlloc;
964 mwStatNumAlloc++;
965
966 if ( mwStatLevel ) mwStatAlloc( size, file, line );
967
969 return p;
970}
#define CHKVAL(mw)
mwData * prev
mwData * next

◆ mwMalloc_()

void * mwMalloc_ ( size_t size)

Definition at line 1205 of file KalFitMemLeak.c.

1205 {
1206 MW_MUTEX_LOCK();
1207 TESTS( NULL, 0 );
1209 return malloc( size );
1210}

◆ mwMark()

void * mwMark ( void * p,
const char * description,
const char * file,
unsigned line )

Definition at line 723 of file KalFitMemLeak.c.

723 {
724 mwMarker* mrk;
725 unsigned n, isnew;
726 char* buf;
727 int tot, oflow = 0;
728 char wherebuf[128];
729
730 mwAutoInit();
731 TESTS( NULL, 0 );
732
733 if ( desc == NULL ) desc = "unknown";
734 if ( file == NULL ) file = "unknown";
735
736 tot = sprintf( wherebuf, "%.48s called from %s(%d)", desc, file, line );
737 if ( tot >= (int)sizeof( wherebuf ) )
738 {
739 wherebuf[sizeof( wherebuf ) - 1] = 0;
740 oflow = 1;
741 }
742
743 if ( p == NULL )
744 {
745 mwWrite( "mark: %s(%d), no mark for NULL:'%s' may be set\n", file, line, desc );
746 return p;
747 }
748
749 if ( mwFirstMark != NULL && !mwIsReadAddr( mwFirstMark, sizeof( mwMarker ) ) )
750 {
751 mwWrite( "mark: %s(%d), mwFirstMark (%p) is trashed, can't mark for %s\n", file, line,
752 mwFirstMark, desc );
753 return p;
754 }
755
756 for ( mrk = mwFirstMark; mrk; mrk = mrk->next )
757 {
758 if ( mrk->next != NULL && !mwIsReadAddr( mrk->next, sizeof( mwMarker ) ) )
759 {
760 mwWrite( "mark: %s(%d), mark(%p)->next(%p) is trashed, can't mark for %s\n", file, line,
761 mrk, mrk->next, desc );
762 return p;
763 }
764 if ( mrk->host == p ) break;
765 }
766
767 if ( mrk == NULL )
768 {
769 isnew = 1;
770 mrk = (mwMarker*)malloc( sizeof( mwMarker ) );
771 if ( mrk == NULL )
772 {
773 mwWrite( "mark: %s(%d), no mark for %p:'%s', out of memory\n", file, line, p, desc );
774 return p;
775 }
776 mrk->next = NULL;
777 n = 0;
778 }
779 else
780 {
781 isnew = 0;
782 n = strlen( mrk->text );
783 }
784
785 n += strlen( wherebuf );
786 buf = (char*)malloc( n + 3 );
787 if ( buf == NULL )
788 {
789 if ( isnew ) free( mrk );
790 mwWrite( "mark: %s(%d), no mark for %p:'%s', out of memory\n", file, line, p, desc );
791 return p;
792 }
793
794 if ( isnew )
795 {
796 memcpy( buf, wherebuf, n + 1 );
797 mrk->next = mwFirstMark;
798 mrk->host = p;
799 mrk->text = buf;
800 mrk->level = 1;
801 mwFirstMark = mrk;
802 }
803 else
804 {
805 strcpy( buf, mrk->text );
806 strcat( buf, ", " );
807 strcat( buf, wherebuf );
808 free( mrk->text );
809 mrk->text = buf;
810 mrk->level++;
811 }
812
813 if ( oflow )
814 {
815 mwIncErr();
816 mwTrace( " [WARNING: OUTPUT BUFFER OVERFLOW - SYSTEM UNSTABLE]\n" );
817 }
818 return p;
819}
int mwIsReadAddr(const void *p, unsigned len)
int mwIsReadAddr(const void *p, unsigned len)

◆ mwNoMansLand()

void mwNoMansLand ( int mw_nml_level)

Definition at line 1547 of file KalFitMemLeak.c.

1547 {
1548 mwAutoInit();
1549 TESTS( NULL, 0 );
1550 switch ( level )
1551 {
1552 case MW_NML_NONE: (void)mwDrop_( 0, MW_VAL_NML, 0 ); break;
1553 case MW_NML_FREE: break;
1554 case MW_NML_ALL: (void)mwGrab_( 0, MW_VAL_NML, 0 ); break;
1555 default: return;
1556 }
1557 mwNML = level;
1558}

◆ mwPuts()

void mwPuts ( const char * text)

◆ mwRealloc()

void * mwRealloc ( void * p,
size_t size,
const char * file,
int line )

Definition at line 972 of file KalFitMemLeak.c.

972 {
973 int oldUseLimit, i;
974 mwData* mw;
975 char* ptr;
976
977 mwAutoInit();
978
979 if ( p == NULL ) return mwMalloc( size, file, line );
980 if ( size == 0 )
981 {
982 mwFree( p, file, line );
983 return NULL;
984 }
985
987
988 /* do the quick ownership test */
989 mw = (mwData*)mwBUFFER_TO_MW( p );
990 if ( mwIsOwned( mw, file, line ) )
991 {
992
993 /* if the buffer is an NML, treat this as a double-free */
994 if ( mw->flag & MW_NML )
995 {
996 mwIncErr();
997 if ( *( (unsigned char*)( mw ) + mwDataSize + mwOverflowZoneSize ) != MW_VAL_NML )
998 {
999 mwWrite( "internal: <%ld> %s(%d), no-mans-land MW-%p is corrupted\n", mwCounter, file,
1000 line, mw );
1001 }
1002 goto check_dbl_free;
1003 }
1004
1005 /* if this allocation would violate the limit, fail it */
1006 if ( mwUseLimit && ( (long)size + mwStatCurAlloc - (long)mw->size > mwAllocLimit ) )
1007 {
1008 TESTS( file, line );
1009 mwCounter++;
1010 mwWrite( "limit fail: <%ld> %s(%d), %ld wanted %ld available\n", mwCounter, file, line,
1011 (unsigned long)size - mw->size, mwAllocLimit - mwStatCurAlloc );
1012 mwIncErr();
1013 FLUSH();
1015 return NULL;
1016 }
1017
1018 /* fake realloc operation */
1019 oldUseLimit = mwUseLimit;
1020 mwUseLimit = 0;
1021 ptr = (char*)mwMalloc( size, file, line );
1022 if ( ptr != NULL )
1023 {
1024 if ( size < mw->size ) memcpy( ptr, p, size );
1025 else memcpy( ptr, p, mw->size );
1026 mwFree( p, file, line );
1027 }
1028 mwUseLimit = oldUseLimit;
1030 return (void*)ptr;
1031 }
1032
1033 /* Unknown pointer! */
1034
1035 /* using free'd pointer? */
1036check_dbl_free:
1037 for ( i = 0; i < MW_FREE_LIST; i++ )
1038 {
1039 if ( mwLastFree[i] == p )
1040 {
1041 mwIncErr();
1042 mwWrite( "realloc: <%ld> %s(%d), %p was"
1043 " freed from %s(%d)\n",
1044 mwCounter, file, line, p, mwLFfile[i], mwLFline[i] );
1045 FLUSH();
1047 return NULL;
1048 }
1049 }
1050
1051 /* some weird pointer */
1052 mwIncErr();
1053 mwWrite( "realloc: <%ld> %s(%d), unknown pointer %p\n", mwCounter, file, line, p );
1054 FLUSH();
1056 return NULL;
1057}

◆ mwRealloc_()

void * mwRealloc_ ( void * p,
size_t size )

Definition at line 1212 of file KalFitMemLeak.c.

1212 {
1213 MW_MUTEX_LOCK();
1214 TESTS( NULL, 0 );
1216 return realloc( p, size );
1217}

◆ mwSetAriAction()

void mwSetAriAction ( int mw_ari_value)

Definition at line 1258 of file KalFitMemLeak.c.

1258 {
1259 MW_MUTEX_LOCK();
1260 TESTS( NULL, 0 );
1261 mwAriAction = action;
1263 return;
1264}

◆ mwSetAriFunc()

void mwSetAriFunc ( int(* func )(const char *))

Definition at line 875 of file KalFitMemLeak.c.

875 {
876 mwAutoInit();
877 mwAriFunction = func;
878}

◆ mwSetOutFunc()

void mwSetOutFunc ( void(* func )(int))

Definition at line 668 of file KalFitMemLeak.c.

668 {
669 mwAutoInit();
670 mwOutFunction = func;
671}

◆ mwStatistics()

void mwStatistics ( int level)

Definition at line 651 of file KalFitMemLeak.c.

651 {
652 mwAutoInit();
653 if ( level < 0 ) level = 0;
654 if ( mwStatLevel != level )
655 {
656 mwWrite( "statistics: now collecting on a %s basis\n",
657 level < 1 ? "global" : ( level < 2 ? "module" : "line" ) );
658 mwStatLevel = level;
659 }
660}

◆ mwStrdup()

char * mwStrdup ( const char * str,
const char * file,
int line )

Definition at line 1059 of file KalFitMemLeak.c.

1059 {
1060 size_t len;
1061 char* newstring;
1062
1063 MW_MUTEX_LOCK();
1064
1065 if ( str == NULL )
1066 {
1067 mwIncErr();
1068 mwWrite( "strdup: <%ld> %s(%d), strdup(NULL) called\n", mwCounter, file, line );
1069 FLUSH();
1071 return NULL;
1072 }
1073
1074 len = strlen( str ) + 1;
1075 newstring = (char*)mwMalloc( len, file, line );
1076 if ( newstring != NULL ) memcpy( newstring, str, len );
1078 return newstring;
1079}

◆ mwTerm()

void mwTerm ( void )

Definition at line 641 of file KalFitMemLeak.c.

641 {
642 if ( mwInited == 1 )
643 {
644 mwAbort();
645 return;
646 }
647 if ( !mwInited ) mwWrite( "internal: mwTerm(): MEMWATCH has not been started!\n" );
648 else mwInited--;
649}
void mwAbort(void)

◆ mwTest()

int mwTest ( const char * file,
int line,
int mw_test_flags )

Definition at line 692 of file KalFitMemLeak.c.

692 {
693 mwAutoInit();
694 mwTestFlags = items;
695 return mwTestNow( file, line, 0 );
696}

◆ mwTestBuffer()

int mwTestBuffer ( const char * file,
int line,
void * p )

Definition at line 702 of file KalFitMemLeak.c.

702 {
703 mwData* mw;
704
705 mwAutoInit();
706
707 /* do the quick ownership test */
708 mw = (mwData*)mwBUFFER_TO_MW( p );
709
710 if ( mwIsOwned( mw, file, line ) ) { return mwTestBuf( mw, file, line ); }
711 return 1;
712}

◆ mwTrace()

void mwTrace ( const char * format_string,
... )

Definition at line 1388 of file KalFitMemLeak.c.

1388 {
1389 int tot, oflow = 0;
1390 va_list mark;
1391
1392 mwAutoInit();
1393 MW_MUTEX_LOCK();
1394 TESTS( NULL, 0 );
1395 if ( mwOutFunction == NULL ) mwOutFunction = mwDefaultOutFunc;
1396
1397 va_start( mark, format );
1398 tot = vsprintf( mwPrintBuf, format, mark );
1399 va_end( mark );
1400 if ( tot >= MW_TRACE_BUFFER )
1401 {
1402 mwPrintBuf[MW_TRACE_BUFFER] = 0;
1403 oflow = 1;
1404 }
1405 for ( tot = 0; mwPrintBuf[tot]; tot++ ) ( *mwOutFunction )( mwPrintBuf[tot] );
1406 if ( oflow )
1407 {
1408 mwIncErr();
1409 mwTrace( " [WARNING: OUTPUT BUFFER OVERFLOW - SYSTEM UNSTABLE]\n" );
1410 }
1411
1412 FLUSH();
1414}

◆ mwUnmark()

void * mwUnmark ( void * p,
const char * file,
unsigned line )

Definition at line 821 of file KalFitMemLeak.c.

821 {
822 mwMarker *mrk, *prv;
823 mrk = mwFirstMark;
824 prv = NULL;
825 while ( mrk )
826 {
827 if ( mrk->host == p )
828 {
829 if ( mrk->level < 2 )
830 {
831 if ( prv ) prv->next = mrk->next;
832 else mwFirstMark = mrk->next;
833 free( mrk->text );
834 free( mrk );
835 return p;
836 }
837 mrk->level--;
838 return p;
839 }
840 prv = mrk;
841 mrk = mrk->next;
842 }
843 mwWrite( "mark: %s(%d), no mark found for %p\n", file, line, p );
844 return p;
845}

◆ mwVerify()

int mwVerify ( int exp,
const char * exps,
const char * fn,
int ln )

Definition at line 1328 of file KalFitMemLeak.c.

1328 {
1329 int i;
1330 char buffer[MW_TRACE_BUFFER + 8];
1331 if ( exp ) { return 0; }
1332 mwAutoInit();
1333 MW_MUTEX_LOCK();
1334 TESTS( fn, ln );
1335 mwIncErr();
1336 mwCounter++;
1337 mwWrite( "verify trap: <%ld> %s(%d), %s\n", mwCounter, fn, ln, exps );
1338 if ( mwAriFunction != NULL )
1339 {
1340 sprintf( buffer, "MEMWATCH: verify trap: %s(%d), %s", fn, ln, exps );
1341 i = ( *mwAriFunction )( buffer );
1342 if ( i == 0 )
1343 {
1344 mwWrite( "verify trap: <%ld> IGNORED - execution continues\n", mwCounter );
1346 return 0;
1347 }
1348 if ( i == 1 )
1349 {
1350 mwWrite( "verify trap: <%ld> RETRY - executing again\n", mwCounter );
1352 return 1;
1353 }
1354 }
1355 else
1356 {
1357 if ( mwAriAction & MW_ARI_NULLREAD )
1358 {
1359 /* This is made in an attempt to kick in */
1360 /* any debuggers or OS stack traces */
1361 FLUSH();
1362 /*lint -save -e413 */
1363 i = *( (int*)NULL );
1364 mwDummy( (char)i );
1365 /*lint -restore */
1366 }
1367 if ( mwAriAction & MW_ARI_IGNORE )
1368 {
1369 mwWrite( "verify trap: <%ld> AUTO IGNORED - execution continues\n", mwCounter );
1371 return 0;
1372 }
1373 fprintf( mwSTDERR, "\nMEMWATCH: verify trap: %s(%d), %s\n", fn, ln, exps );
1374 }
1375 FLUSH();
1376 (void)mwTestNow( fn, ln, 1 );
1377 FLUSH();
1379 exit( 255 );
1380 /* NOT REACHED - the return statement is in to keep */
1381 /* stupid compilers from squeaking about differing return modes. */
1382 /* Smart compilers instead say 'code unreachable...' */
1383 /*lint -save -e527 */
1384 return 0;
1385 /*lint -restore */
1386}

Variable Documentation

◆ mwCounter

const unsigned long mwCounter
extern