BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
KalFitMemLeak.c File Reference
#include "memwatch.h"
#include <limits.h>
#include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

Go to the source code of this file.

Classes

struct  mwData_
struct  mwStat_
struct  mwGrabData_
struct  mwMarker_

Macros

#define __MEMWATCH_C   1
#define VERSION   "2.71" /* the current version number */
#define CHKVAL(mw)
#define FLUSH()
#define TESTS(f, l)
#define PRECHK   0x01234567L
#define POSTCHK   0x76543210L
#define mwBUFFER_TO_MW(p)
#define MW_NML   0x0001
#define COMMIT   "" /* Normal ANSI */
#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()

Typedefs

typedef struct mwData_ mwData
typedef struct mwStat_ mwStat
typedef struct mwGrabData_ mwGrabData
typedef struct mwMarker_ mwMarker

Functions

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)

Macro Definition Documentation

◆ __MEMWATCH_C

#define __MEMWATCH_C   1

Definition at line 98 of file KalFitMemLeak.c.

◆ AIPH

#define AIPH ( )
Value:
if ( always_invoked ) \
{ \
mwWrite( "autocheck: <%ld> %s(%d) ", mwCounter, file, line ); \
always_invoked = 0; \
}
char * file
Definition DQA_TO_DB.cxx:16
const unsigned long mwCounter

Definition at line 2267 of file KalFitMemLeak.c.

2267#define AIPH() \
2268 if ( always_invoked ) \
2269 { \
2270 mwWrite( "autocheck: <%ld> %s(%d) ", mwCounter, file, line ); \
2271 always_invoked = 0; \
2272 }

◆ CHKVAL

#define CHKVAL ( mw)
Value:
( 0xFE0180L ^ (long)mw->count ^ (long)mw->size ^ (long)mw->line )

Definition at line 141 of file KalFitMemLeak.c.

Referenced by mwMalloc().

◆ COMMIT

#define COMMIT   "" /* Normal ANSI */

Definition at line 156 of file KalFitMemLeak.c.

◆ CPPTEXT

#define CPPTEXT   ""

Definition at line 162 of file KalFitMemLeak.c.

Referenced by mwInit().

◆ FLUSH

#define FLUSH ( )
Value:
mwFlush()

Definition at line 142 of file KalFitMemLeak.c.

Referenced by mwAbort(), mwAssert(), mwFree(), mwInit(), mwLimit(), mwMalloc(), mwRealloc(), mwStrdup(), mwTrace(), and mwVerify().

◆ mw16BIT

#define mw16BIT   1

Definition at line 203 of file KalFitMemLeak.c.

◆ MW_MUTEX_INIT

#define MW_MUTEX_INIT ( )

Definition at line 177 of file KalFitMemLeak.c.

Referenced by mwInit().

◆ MW_MUTEX_LOCK

#define MW_MUTEX_LOCK ( )

◆ MW_MUTEX_TERM

#define MW_MUTEX_TERM ( )

Definition at line 178 of file KalFitMemLeak.c.

Referenced by mwAbort().

◆ MW_MUTEX_UNLOCK

#define MW_MUTEX_UNLOCK ( )

◆ MW_NML

#define MW_NML   0x0001

Definition at line 151 of file KalFitMemLeak.c.

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

◆ mwBUFFER_TO_MW

#define mwBUFFER_TO_MW ( p)
Value:
( (mwData*)(void*)( ( (char*)p ) - mwDataSize - mwOverflowZoneSize ) )
struct mwData_ mwData

Definition at line 147 of file KalFitMemLeak.c.

147#define mwBUFFER_TO_MW( p ) \
148 ( (mwData*)(void*)( ( (char*)p ) - mwDataSize - mwOverflowZoneSize ) )

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

◆ mwROUNDALLOC

#define mwROUNDALLOC   mwROUNDALLOC_DEFAULT

Definition at line 221 of file KalFitMemLeak.c.

Referenced by mwFree(), and mwInit().

◆ mwROUNDALLOC_DEFAULT

#define mwROUNDALLOC_DEFAULT   2

Definition at line 204 of file KalFitMemLeak.c.

◆ mwSTDERR

#define mwSTDERR   mwLog

Definition at line 168 of file KalFitMemLeak.c.

Referenced by mwAbort(), mwAssert(), mwBreakOut(), and mwVerify().

◆ POSTCHK

#define POSTCHK   0x76543210L

Definition at line 146 of file KalFitMemLeak.c.

◆ PRECHK

#define PRECHK   0x01234567L

Definition at line 145 of file KalFitMemLeak.c.

◆ TESTS

#define TESTS ( f,
l )
Value:
if ( mwTestAlways ) (void)mwTestNow( f, l, 1 )
TFile f("ana_bhabha660a_dqa_mcPat_zy_old.root")

Definition at line 143 of file KalFitMemLeak.c.

143#define TESTS( f, l ) \
144 if ( mwTestAlways ) (void)mwTestNow( f, l, 1 )

Referenced by mwAssert(), mwCalloc_(), mwDrop(), mwFree(), mwFree_(), mwGrab(), mwLimit(), mwMalloc(), mwMalloc_(), mwMark(), mwNoMansLand(), mwRealloc(), mwRealloc_(), mwSetAriAction(), mwTrace(), and mwVerify().

◆ VERSION

#define VERSION   "2.71" /* the current version number */

Definition at line 140 of file KalFitMemLeak.c.

Referenced by mwInit().

Typedef Documentation

◆ mwData

typedef struct mwData_ mwData

Definition at line 258 of file KalFitMemLeak.c.

◆ mwGrabData

typedef struct mwGrabData_ mwGrabData

Definition at line 286 of file KalFitMemLeak.c.

◆ mwMarker

typedef struct mwMarker_ mwMarker

Definition at line 293 of file KalFitMemLeak.c.

◆ mwStat

typedef struct mwStat_ mwStat

Definition at line 274 of file KalFitMemLeak.c.

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()
mwMarker * next

Referenced by mwInit(), and mwTerm().

◆ mwAriHandler()

int mwAriHandler ( const char * estr)

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)
EvtComplex exp(const EvtComplex &c)
#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}

◆ 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}

◆ 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 kb)

Definition at line 1425 of file KalFitMemLeak.c.

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

◆ 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}

◆ mwGrab()

unsigned mwGrab ( unsigned kb)

Definition at line 1420 of file KalFitMemLeak.c.

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

◆ mwInit()

void mwInit ( void )

Definition at line 417 of file KalFitMemLeak.c.

417 {
418 time_t tid;
419
420 if ( mwInited++ > 0 ) return;
421
423
424 /* start a log if none is running */
425 if ( mwLogR() == NULL ) mwLogFile( "memwatch.log" );
426 if ( mwLogR() == NULL )
427 {
428 int i;
429 char buf[32];
430 /* oops, could not open it! */
431 /* probably because it's already open */
432 /* so we try some other names */
433 for ( i = 1; i < 100; i++ )
434 {
435 sprintf( buf, "memwat%02d.log", i );
436 mwLogFile( buf );
437 if ( mwLogR() != NULL ) break;
438 }
439 }
440
441 /* initialize the statistics */
442 mwStatList = NULL;
443 mwStatTotAlloc = 0L;
444 mwStatCurAlloc = 0L;
445 mwStatMaxAlloc = 0L;
446 mwStatNumAlloc = 0L;
447 mwNmlCurAlloc = 0L;
448 mwNmlNumAlloc = 0L;
449
450 /* calculate the buffer size to use for a mwData */
451 mwDataSize = sizeof( mwData );
452 while ( mwDataSize % mwROUNDALLOC ) mwDataSize++;
453
454 /* write informational header if needed */
455 if ( !mwInfoWritten )
456 {
457 mwInfoWritten = 1;
458 (void)time( &tid );
459 mwWrite( "\n============="
460 " MEMWATCH " VERSION " Copyright (C) 1992-1999 Johan Lindh "
461 "=============\n" );
462 mwWrite( "\nStarted at %s\n", ctime( &tid ) );
463
464 /**************************************************************** Generic */
465 mwWrite( "Modes: " );
466#ifdef mwNew
467 mwWrite( "C++ " );
468#endif /* mwNew */
469#ifdef __STDC__
470 mwWrite( "__STDC__ " );
471#endif /* __STDC__ */
472#ifdef mw16BIT
473 mwWrite( "16-bit " );
474#endif
475#ifdef mw32BIT
476 mwWrite( "32-bit " );
477#endif
478#ifdef mw64BIT
479 mwWrite( "64-bit " );
480#endif
481 mwWrite( "mwDWORD==(" mwDWORD_DEFINED ")\n" );
482 mwWrite( "mwROUNDALLOC==%d sizeof(mwData)==%d mwDataSize==%d\n", mwROUNDALLOC,
483 sizeof( mwData ), mwDataSize );
484/**************************************************************** Generic */
485
486/************************************************************ Microsoft C */
487#ifdef _MSC_VER
488 mwWrite( "Compiled using Microsoft C" CPPTEXT " %d.%02d\n", _MSC_VER / 100,
489 _MSC_VER % 100 );
490#endif /* _MSC_VER */
491/************************************************************ Microsoft C */
492
493/************************************************************** Borland C */
494#ifdef __BORLANDC__
495 mwWrite( "Compiled using Borland C"
496# ifdef __cplusplus
497 "++ %d.%01d\n",
498 __BCPLUSPLUS__ / 0x100, ( __BCPLUSPLUS__ % 0x100 ) / 0x10 );
499# else
500 " %d.%01d\n",
501 __BORLANDC__ / 0x100, ( __BORLANDC__ % 0x100 ) / 0x10 );
502# endif /* __cplusplus */
503#endif /* __BORLANDC__ */
504/************************************************************** Borland C */
505
506/************************************************************** Watcom C */
507#ifdef __WATCOMC__
508 mwWrite( "Compiled using Watcom C %d.%02d ", __WATCOMC__ / 100, __WATCOMC__ % 100 );
509# ifdef __FLAT__
510 mwWrite( "(32-bit flat model)" );
511# endif /* __FLAT__ */
512 mwWrite( "\n" );
513#endif /* __WATCOMC__ */
514 /************************************************************** Watcom C */
515
516 mwWrite( "\n" );
517 FLUSH();
518 }
519
520 if ( mwUseAtexit ) (void)atexit( mwAbort );
521 return;
522}
void mwAbort(void)
#define VERSION
#define MW_MUTEX_INIT()
#define CPPTEXT

◆ 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 lim)

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 * desc,
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}
const Int_t n
int mwIsReadAddr(const void *p, unsigned len)
int mwIsReadAddr(const void *p, unsigned len)

◆ mwNoMansLand()

void mwNoMansLand ( int 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}

◆ 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 action)

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 items )

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

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}