⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memwatch.c

📁 程序代码使用说明: (1)所有源代码目录下都提供了Makefile(非Qt)
💻 C
📖 第 1 页 / 共 5 页
字号:
	while( mwDataSize % mwROUNDALLOC ) mwDataSize ++;    /* write informational header if needed */    if( !mwInfoWritten ) {        mwInfoWritten = 1;        (void) time( &tid );        mwWrite(            "\n============="            " MEMWATCH " VERSION " Copyright (C) 1992-1999 Johan Lindh "            "=============\n");        mwWrite( "\nStarted at %s\n", ctime( &tid ) );/**************************************************************** Generic */		mwWrite( "Modes: " );#ifdef mwNew        mwWrite( "C++ " );#endif /* mwNew */#ifdef __STDC__        mwWrite( "__STDC__ " );#endif /* __STDC__ */#ifdef mw16BIT		mwWrite( "16-bit " );#endif#ifdef mw32BIT		mwWrite( "32-bit " );#endif#ifdef mw64BIT		mwWrite( "64-bit " );#endif		mwWrite( "mwDWORD==(" mwDWORD_DEFINED ")\n" );		mwWrite( "mwROUNDALLOC==%d sizeof(mwData)==%d mwDataSize==%d\n",			mwROUNDALLOC, sizeof(mwData), mwDataSize );/**************************************************************** Generic *//************************************************************ Microsoft C */#ifdef _MSC_VER        mwWrite( "Compiled using Microsoft C" CPPTEXT            " %d.%02d\n", _MSC_VER / 100, _MSC_VER % 100 );#endif /* _MSC_VER *//************************************************************ Microsoft C *//************************************************************** Borland C */#ifdef __BORLANDC__        mwWrite( "Compiled using Borland C"#ifdef __cplusplus            "++ %d.%01d\n", __BCPLUSPLUS__/0x100, (__BCPLUSPLUS__%0x100)/0x10 );#else            " %d.%01d\n", __BORLANDC__/0x100, (__BORLANDC__%0x100)/0x10 );#endif /* __cplusplus */#endif /* __BORLANDC__ *//************************************************************** Borland C *//************************************************************** Watcom C */#ifdef __WATCOMC__        mwWrite( "Compiled using Watcom C %d.%02d ",            __WATCOMC__/100, __WATCOMC__%100 );#ifdef __FLAT__        mwWrite( "(32-bit flat model)" );#endif /* __FLAT__ */        mwWrite( "\n" );#endif /* __WATCOMC__ *//************************************************************** Watcom C */        mwWrite( "\n" );        FLUSH();        }    if( mwUseAtexit ) (void) atexit( mwAbort );    return;    }void mwAbort( void ) {    mwData *mw;    mwMarker *mrk;    char *data;    time_t tid;    int c, i, j;	int errors;    tid = time( NULL );    mwWrite( "\nStopped at %s\n", ctime( &tid) );    if( !mwInited )        mwWrite( "internal: mwAbort(): MEMWATCH not initialized!\n" );    /* release the grab list */    mwDropAll();    /* report mwMarked items */    while( mwFirstMark ) {        mrk = mwFirstMark->next;        mwWrite( "mark: %p: %s\n", mwFirstMark->host, mwFirstMark->text );        free( mwFirstMark->text );        free( mwFirstMark );        mwFirstMark = mrk;        mwErrors ++;        }    /* release all still allocated memory */	errors = 0;    while( mwHead != NULL && errors < 3 ) {		if( !mwIsOwned(mwHead, __FILE__, __LINE__ ) ) {			if( errors < 3 )			{				errors ++;				mwWrite( "internal: NML/unfreed scan restarting\n" );				FLUSH();				mwHead = mwHead;				continue;			}			mwWrite( "internal: NML/unfreed scan aborted, heap too damaged\n" );			FLUSH();			break;			}        mwFlushW(0);        if( !(mwHead->flag & MW_NML) ) {            mwErrors++;            data = ((char*)mwHead)+mwDataSize;            mwWrite( "unfreed: <%ld> %s(%d), %ld bytes at %p ",                mwHead->count, mwHead->file, mwHead->line, (long)mwHead->size, data+mwOverflowZoneSize );            if( mwCheckOF( data ) ) {                mwWrite( "[underflowed] ");                FLUSH();                }            if( mwCheckOF( (data+mwOverflowZoneSize+mwHead->size) ) ) {                mwWrite( "[overflowed] ");                FLUSH();                }            mwWrite( " \t{" );            j = 16; if( mwHead->size < 16 ) j = (int) mwHead->size;            for( i=0;i<16;i++ ) {                if( i<j ) mwWrite( "%02X ",                    (unsigned char) *(data+mwOverflowZoneSize+i) );                else mwWrite( ".. " );                }            for( i=0;i<j;i++ ) {                c = *(data+mwOverflowZoneSize+i);                if( c < 32 || c > 126 ) c = '.';                mwWrite( "%c", c );                }            mwWrite( "}\n" );			mw = mwHead;			mwUnlink( mw, __FILE__, __LINE__ );            free( mw );            }        else {            data = ((char*)mwHead) + mwDataSize + mwOverflowZoneSize;            if( mwTestMem( data, mwHead->size, MW_VAL_NML ) ) {                mwErrors++;                mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n",                    mwHead->count, data + mwOverflowZoneSize, mwHead->file, mwHead->line );                FLUSH();                }			mwNmlNumAlloc --;			mwNmlCurAlloc -= mwHead->size;			mw = mwHead;			mwUnlink( mw, __FILE__, __LINE__ );            free( mw );            }        }	if( mwNmlNumAlloc ) mwWrite("internal: NoMansLand block counter %ld, not zero\n", mwNmlNumAlloc );	if( mwNmlCurAlloc ) mwWrite("internal: NoMansLand byte counter %ld, not zero\n", mwNmlCurAlloc );    /* report statistics */    mwStatReport();    FLUSH();    mwInited = 0;    mwHead = mwTail = NULL;    if( mwErrors )        fprintf(mwSTDERR,"MEMWATCH detected %ld anomalies\n",mwErrors);    mwLogFile( NULL );    mwErrors = 0;    MW_MUTEX_TERM();    }void mwTerm( void ) {    if( mwInited == 1 )    {        mwAbort();        return;    }    if( !mwInited )        mwWrite("internal: mwTerm(): MEMWATCH has not been started!\n");    else        mwInited --;    }void mwStatistics( int level ){    mwAutoInit();    if( level<0 ) level=0;    if( mwStatLevel != level )    {		mwWrite( "statistics: now collecting on a %s basis\n",			level<1?"global":(level<2?"module":"line") );	    mwStatLevel = level;	}}void mwAutoCheck( int onoff ) {    mwAutoInit();    mwTestAlways = onoff;    if( onoff ) mwTestFlags = MW_TEST_ALL;    }void mwSetOutFunc( void (*func)(int) ) {    mwAutoInit();    mwOutFunction = func;    }static void mwWriteOF( void *p ){	int i;	unsigned char *ptr;	ptr = (unsigned char*) p;	for( i=0; i<mwOverflowZoneSize; i++ )	{		*(ptr+i) = mwOverflowZoneTemplate[i%8];	}	return;}static int mwCheckOF( const void *p ){	int i;	const unsigned char *ptr;	ptr = (const unsigned char *) p;	for( i=0; i<mwOverflowZoneSize; i++ )	{		if( *(ptr+i) != mwOverflowZoneTemplate[i%8] )			return 1; /* errors found */	}	return 0; /* no errors */}int mwTest( const char *file, int line, int items ) {    mwAutoInit();    mwTestFlags = items;    return mwTestNow( file, line, 0 );    }/*** Returns zero if there are no errors.** Returns nonzero if there are errors.*/int mwTestBuffer( const char *file, int line, void *p ) {    mwData* mw;    mwAutoInit();    /* do the quick ownership test */    mw = (mwData*) mwBUFFER_TO_MW( p );    if( mwIsOwned( mw, file, line ) ) {        return mwTestBuf( mw, file, line );		}	return 1;	}void mwBreakOut( const char* cause ) {    fprintf(mwSTDERR, "breakout: %s\n", cause);    mwWrite("breakout: %s\n", cause );    return;    }/*** 981217 JLI: is it possible that ->next is not always set?*/void * mwMark( void *p, const char *desc, const char *file, unsigned line ) {    mwMarker *mrk;    unsigned n, isnew;    char *buf;    int tot, oflow = 0;    char wherebuf[128];    mwAutoInit();    TESTS(NULL,0);    if( desc == NULL ) desc = "unknown";    if( file == NULL ) file = "unknown";    tot = sprintf( wherebuf, "%.48s called from %s(%d)", desc, file, line );    if( tot >= (int)sizeof(wherebuf) ) { wherebuf[sizeof(wherebuf)-1] = 0; oflow = 1; }    if( p == NULL ) {        mwWrite("mark: %s(%d), no mark for NULL:'%s' may be set\n", file, line, desc );        return p;        }	if( mwFirstMark != NULL && !mwIsReadAddr( mwFirstMark, sizeof( mwMarker ) ) )	{		mwWrite("mark: %s(%d), mwFirstMark (%p) is trashed, can't mark for %s\n",			file, line, mwFirstMark, desc );		return p;	}    for( mrk=mwFirstMark; mrk; mrk=mrk->next )	{		if( mrk->next != NULL && !mwIsReadAddr( mrk->next, sizeof( mwMarker ) ) )		{			mwWrite("mark: %s(%d), mark(%p)->next(%p) is trashed, can't mark for %s\n",				file, line, mrk, mrk->next, desc );			return p;		}		if( mrk->host == p ) break;	}    if( mrk == NULL ) {        isnew = 1;        mrk = (mwMarker*) malloc( sizeof( mwMarker ) );        if( mrk == NULL ) {            mwWrite("mark: %s(%d), no mark for %p:'%s', out of memory\n", file, line, p, desc );            return p;            }		mrk->next = NULL;        n = 0;        }    else {        isnew = 0;        n = strlen( mrk->text );        }    n += strlen( wherebuf );    buf = (char*) malloc( n+3 );    if( buf == NULL ) {        if( isnew ) free( mrk );        mwWrite("mark: %s(%d), no mark for %p:'%s', out of memory\n", file, line, p, desc );        return p;        }    if( isnew ) {        memcpy( buf, wherebuf, n+1 );        mrk->next = mwFirstMark;        mrk->host = p;        mrk->text = buf;        mrk->level = 1;        mwFirstMark = mrk;        }    else {        strcpy( buf, mrk->text );        strcat( buf, ", " );        strcat( buf, wherebuf );        free( mrk->text );        mrk->text = buf;        mrk->level ++;        }    if( oflow ) {        mwIncErr();        mwTrace( " [WARNING: OUTPUT BUFFER OVERFLOW - SYSTEM UNSTABLE]\n" );        }    return p;    }void* mwUnmark( void *p, const char *file, unsigned line ) {    mwMarker *mrk, *prv;    mrk = mwFirstMark;    prv = NULL;    while( mrk ) {        if( mrk->host == p ) {            if( mrk->level < 2 ) {                if( prv ) prv->next = mrk->next;                else mwFirstMark = mrk->next;                free( mrk->text );                free( mrk );                return p;                }            mrk->level --;            return p;            }        prv = mrk;        mrk = mrk->next;        }    mwWrite("mark: %s(%d), no mark found for %p\n", file, line, p );    return p;    }/************************************************************************* Abort/Retry/Ignore handlers***********************************************************************/static int mwARI( const char *estr ) {    char inbuf[81];    int c;    fprintf(mwSTDERR, "\n%s\nMEMWATCH: Abort, Retry or Ignore? ", estr);    (void) fgets(inbuf,sizeof(inbuf),stdin);	for( c=0; inbuf[c] && inbuf[c] <= ' '; c++ ) ;    c = inbuf[c];    if( c == 'R' || c == 'r' ) {        mwBreakOut( estr );        return MW_ARI_RETRY;        }    if( c == 'I' || c == 'i' ) return MW_ARI_IGNORE;    return MW_ARI_ABORT;    }/* standard ARI handler (exported) */int mwAriHandler( const char *estr ) {    mwAutoInit();    return mwARI( estr );    }/* used to set the ARI function */void mwSetAriFunc( int (*func)(const char *) ) {    mwAutoInit();    mwAriFunction = func;    }/************************************************************************* Allocation handlers***********************************************************************/void* mwMalloc( size_t size, const char* file, int line) {    size_t needed;    mwData *mw;    char *ptr;    void *p;    mwAutoInit();	MW_MUTEX_LOCK();    TESTS(file,line);    mwCounter ++;    needed = mwDataSize + mwOverflowZoneSize*2 + size;    if( needed < size )    {    	/* theoretical case: req size + mw overhead exceeded size_t limits */    	return NULL;    }    /* if this allocation would violate the limit, fail it */    if( mwUseLimit && ((long)size + mwStatCurAlloc > mwAllocLimit) ) {        mwWrite( "limit fail: <%ld> %s(%d), %ld wanted %ld available\n",            mwCounter, file, line, (long)size, mwAllocLimit - mwStatCurAlloc );        mwIncErr();        FLUSH();		MW_MUTEX_UNLOCK();        return NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -