memtrack.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 567 行 · 第 1/2 页
C
567 行
tracker *trk;
char *p1;
p1 = name;
while( *p1 ) {
++p1;
}
trk = alloc( sizeof( tracker ) + ( p1 - name ) );
#ifdef _EXTRA_MEM
if( ExtMem == 0 ) {
ExtMem = ExtMemAlloc( TRACK_SIZE );
if( ExtMem == (void FAR *)0 ) {
ExtMem = ExtMemAlloc( ExtMemAvail() );
}
TrkFrl = 0;
TrkBeg = ExtMem;
}
#endif
if( trk == 0 ) return( 0 );
trk->mem_a_list = 0;
trk->mem_used = 0;
trk->max_mem = 0;
trk->alloc = alloc;
trk->realloc = realloc;
trk->free = free;
trk->prt_line = prt_line;
CopyStr( name, trk->name );
return( trk );
}
extern void TrCheck( tracker *trk ) {
/***************************************/
TRPTR alloc;
alloc = trk->mem_a_list;
while( alloc != 0 ) {
TrValidate( Mem( alloc ), TR_NO_ROUTINE, trk );
alloc = Next( alloc );
}
}
extern void TrMemFini( tracker *trk ) {
/*****************************************/
unsigned chunks;
TRPTR alloc;
chunks = 0;
alloc = trk->mem_a_list;
while( alloc != 0 ) {
++chunks;
alloc = Next( alloc );
}
if( chunks != 0 ) {
TrPrt( trk, "%NMemFini: %U chunks (%L bytes) unfreed",
chunks, trk->mem_used );
}
while( trk->mem_a_list != 0 ) {
TrValidate( Mem( trk->mem_a_list ), TR_NO_ROUTINE, trk );
TrFree( Mem( trk->mem_a_list ), trk );
}
_Free( trk );
#ifdef _EXTRA_MEM
ExtMemFree( ExtMem );
#endif
}
extern void TrPrtUsage( tracker *trk ) {
/******************************************/
TrPrt( trk, "%N Memory usage: %L bytes", trk->max_mem );
}
extern void TrPrtMemUse( tracker *trk ) {
/*******************************************/
TRPTR alloc;
TrPrtUsage( trk );
alloc = trk->mem_a_list;
if( alloc == 0 ) return;
TrPrt( trk, " Who Addr Size" );
TrPrt( trk, " ======== ======== ====" );
do {
TrPrt( trk, "&%C %D %U", Who( alloc ), Mem( alloc ), Size( alloc ) );
alloc = Next( alloc );
} while( alloc != 0 );
}
extern void *TrAlloc( unsigned size, void (*ra)(), tracker *trk ) {
/******************************************************************/
void *chunk;
TRPTR trchunk;
if( size == 0 ) {
TrPrt( trk, "%W size zero allocation", "Alloc", ra );
return( 0 );
}
chunk = _Alloc( size + 1 );
if( chunk != 0 ) {
trchunk = AllocTrk( trk );
if( trchunk == 0 ) {
_Free( chunk );
return( 0 );
}
SetNext( trchunk, trk->mem_a_list );
SetWho( trchunk, ra );
SetSize( trchunk, size );
SetMem( trchunk, chunk );
trk->mem_a_list = trchunk;
trk->mem_used += size;
if( trk->mem_used > trk->max_mem ) {
trk->max_mem = trk->mem_used;
}
Fill( chunk, size + 1, ALLOC_BYTE );
}
return( chunk );
}
static int ValidChunk( TRPTR entry, char *who, void (*ra)(), tracker *trk ) {
/****************************************************************************/
void *chunk;
chunk = Mem( entry );
if( *((char *)_PtrAdd( chunk, Size(entry) )) != ALLOC_BYTE ) {
TrPrt( trk, "%W %D overrun allocation of %U bytes", who, ra,
chunk, Size(entry) );
return( FALSE );
#ifdef _SYS_CHKS
} else if( !MemOk( chunk, Size( entry ) + 1 ) ) {
TrPrt( trk, "%W boundry tag hammered %D", who, ra, chunk );
return( FALSE );
} else if( ( chunk = MemOtherOk() ) != 0 ) {
TrPrt( trk, "%W bad free list entry at %D", who, ra, chunk );
return( FALSE );
#endif
}
return( TRUE );
}
extern int TrValidate( void *chunk, void (*ra)(), tracker *trk ) {
/*************************************************************************/
TRPTR entry;
entry = trk->mem_a_list;
for(;;) {
if( entry == 0 ) {
TrPrt( trk, "%W unowned chunk %D", "Validate", ra, chunk );
return( FALSE );
}
if( _PT( Mem( entry ) ) == _PT( chunk ) ) break;
entry = Next( entry );
}
return( ValidChunk( entry, "Validate", ra, trk ) );
}
extern int TrChkRange( void *start, unsigned len,
void (*ra)(), tracker *trk ) {
TRPTR ptr;
void *end;
void *end_chunk;
ptr = trk->mem_a_list;
for(;;) {
if( ptr == 0 ) {
TrPrt( trk, "%W %D not in any allocation", "ChkRange", ra, start );
return( FALSE );
}
end_chunk = _PtrAdd( Mem( ptr ), Size( ptr ) );
if( _PT( start ) >= _PT( Mem( ptr ) )
&& _PT( start ) < _PT( end_chunk ) ) break;
ptr = Next( ptr );
}
end = _PtrAdd( start, len );
if( _PT( end ) > _PT( end_chunk ) ) {
TrPrt( trk, "%W %D+%U overruns allocation %D+%U", "ChkRange", ra,
start, len, Mem( ptr ), Size( ptr ) );
return( FALSE );
}
return( ValidChunk( ptr, "ChkRange", ra, trk ) );
}
extern int TrFree( void *chunk, tracker *trk ) {
/*****************************************************/
return( TrFreeSize( chunk, 0, trk ) );
}
extern int TrFreeSize( void *chunk, unsigned given_size, tracker *trk ) {
/**************************************************************************/
unsigned size;
TRPTR entry;
TRPTR prev;
int ret;
if( chunk == 0 ) return( TRUE );
prev = 0;
entry = trk->mem_a_list;
for(;;) {
if( entry == 0 ) {
TrPrt( trk, "%W unowned chunk %D", "Free", TR_NO_ROUTINE, chunk );
return( FALSE );
}
if( _PT( chunk ) == _PT( Mem( entry ) ) ) break;
prev = entry;
entry = Next( entry );
}
ret = ValidChunk( entry, "Free", TR_NO_ROUTINE, trk );
if( prev == 0 ) {
trk->mem_a_list = Next( entry );
} else {
SetNext( prev, Next( entry ) );
}
size = Size( entry );
trk->mem_used -= size;
FreeTrk( entry, trk );
Fill( chunk, size + 1, FREED_BYTE );
_Free( chunk );
if( given_size != 0 && given_size != size ) {
TrPrt( trk, "%W %D allocated %U, freed %U", "FreeSize", TR_NO_ROUTINE,
chunk, size, given_size );
return( FALSE );
}
return( ret );
}
extern void * TrReAlloc( void *old, unsigned size, void (*ra)(), tracker *trk )
/*****************************************************************************/
// reallocate a block of memory
{
unsigned sizeold;
TRPTR entry;
TRPTR prev;
void *chunk;
if( size == 0 ) {
TrPrt( trk, "%W size zero reallocation", "ReAlloc", ra );
return( 0 );
}
if( old == 0 ) {
TrPrt( trk, "%W reallocation of a NULL pointer", "ReAlloc", ra );
return( 0 );
}
prev = 0;
entry = trk->mem_a_list;
for(;;) {
if( entry == 0 ) {
TrPrt( trk, "%W unowned chunk %D", "ReAlloc", TR_NO_ROUTINE, old );
return( 0 );
}
if( _PT( old ) == _PT( Mem( entry ) ) ) break;
prev = entry;
entry = Next( entry );
}
if( !ValidChunk( entry, "ReAlloc", TR_NO_ROUTINE, trk ) ) {
return( 0 );
}
sizeold = Size( entry );
chunk = _ReAlloc( old, size + 1 );
if( chunk != 0 ) {
SetWho( entry, ra );
SetSize( entry, size );
SetMem( entry, chunk );
trk->mem_used -= sizeold;
trk->mem_used += size;
if( trk->mem_used > trk->max_mem ) {
trk->max_mem = trk->mem_used;
}
*((char *)chunk + size) = ALLOC_BYTE;
}
return( chunk );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?