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

📄 memwatch.c

📁 程序代码使用说明: (1)所有源代码目录下都提供了Makefile(非Qt)
💻 C
📖 第 1 页 / 共 5 页
字号:
			mwWrite("relink: mwTail (%p) is damaged, skipping reverse scan\n", mwTail );			mwTail = NULL;			goto analyze;		}		if( mwTail->next != NULL )		{			mwWrite("relink: the mwTail pointer's 'next' member is %p, not NULL\n", mwTail->next );		}        for( mw2=mwTail; mw2; mw2=mw2->prev )		{            if( mw2->prev )			{				if( !mwIsReadAddr(mw2->prev,mwDataSize) ||					!mw2->prev->check != CHKVAL(mw2) ||					mw2->prev->next != mw2 )				{					mwWrite("relink: reverse chain's last intact MW is MW-%p, %ld %sbytes at %s(%d)\n",						mw2, mw2->size, (mw->flag & MW_NML)?"NoMansLand ":"", mw2->file, mw2->line );					if( mwIsReadAddr(mw2->prev,mwDataSize ) )					{						mwWrite("relink: reverse chain's first damaged MW is MW-%p, %ld %sbytes at %s(%d)\n",							mw2->prev, mw2->size, (mw->flag & MW_NML)?"NoMansLand ":"",							mwIsReadAddr(mw2->file,16)?mw2->file:"<garbage-pointer>", mw2->line );					}					else					{						mwWrite("relink: the 'prev' pointer of this MW points to %p, which is out-of-legal-access\n",							mw2->prev );					}					break;				}			}        }	}analyze:	if( mwHead == NULL && mwTail == NULL )	{        mwWrite("relink: both head and tail pointers damaged, aborting program\n");        mwFlushW(1);        FLUSH();        abort();	}	if( mwHead == NULL )	{		mwHead = mw2;		mwWrite("relink: heap truncated, MW-%p designated as new mwHead\n", mw2 );		mw2->prev = NULL;		mw1 = mw2 = NULL;	}	if( mwTail == NULL )	{		mwTail = mw1;		mwWrite("relink: heap truncated, MW-%p designated as new mwTail\n", mw1 );		mw1->next = NULL;		mw1 = mw2 = NULL;	}    if( mw1 == NULL && mw2 == NULL &&        mwHead->prev == NULL && mwTail->next == NULL ) {        mwWrite("relink: verifying heap integrity...\n" );        FLUSH();        goto verifyok;        }    if( mw1 && mw2 && mw1 != mw2 ) {        mw1->next = mw2;        mw2->prev = mw1;        mwWrite("relink: emergency repairs successful, assessing damage...\n");        FLUSH();        }    else {        mwWrite("relink: heap totally destroyed, aborting program\n");        mwFlushW(1);        FLUSH();        abort();        }    /* Verify by checking that the number of active allocations */    /* match the number of entries in the chain */verifyok:    if( !mwIsHeapOK( NULL ) ) {        mwWrite("relink: heap verification FAILS - aborting program\n");        mwFlushW(1);        FLUSH();        abort();        }    for( size=count=0, mw1=mwHead; mw1; mw1=mw1->next ) {        count ++;        size += (long) mw1->size;        }    if( count == mwNumCurAlloc ) {        mwWrite("relink: successful, ");        if( size == mwStatCurAlloc ) {            mwWrite("no allocations lost\n");            }        else {            if( mw != NULL ) {                mwWrite("size information lost for MW-%p\n", mw);                mw->size = 0;                }            }        }    else {        mwWrite("relink: partial, %ld MW-blocks of %ld bytes lost\n",			mwNmlNumAlloc+mwNumCurAlloc-count, mwNmlCurAlloc+mwStatCurAlloc-size );        return 0;        }    return 1;    }/***  If mwData* is NULL:**      Returns 0 if heap chain is broken.**      Returns 1 if heap chain is intact.**  If mwData* is not NULL:**      Returns 0 if mwData* is missing or if chain is broken.**      Returns 1 if chain is intact and mwData* is found.*/static int mwIsHeapOK( mwData *includes_mw ) {    int found = 0;    mwData *mw;    for( mw = mwHead; mw; mw=mw->next ) {        if( includes_mw == mw ) found++;        if( !mwIsSafeAddr( mw, mwDataSize ) ) return 0;        if( mw->prev ) {            if( !mwIsSafeAddr( mw->prev, mwDataSize ) ) return 0;            if( mw==mwHead || mw->prev->next != mw ) return 0;            }        if( mw->next ) {            if( !mwIsSafeAddr( mw->next, mwDataSize ) ) return 0;            if( mw==mwTail || mw->next->prev != mw ) return 0;            }        else if( mw!=mwTail ) return 0;        }    if( includes_mw != NULL && !found ) return 0;    return 1;    }static int mwIsOwned( mwData* mw, const char *file, int line ) {    int retv;    mwStat *ms;    /* see if the address is legal according to OS */    if( !mwIsSafeAddr( mw, mwDataSize ) ) return 0;    /* make sure we have _anything_ allocated */    if( mwHead == NULL && mwTail == NULL && mwStatCurAlloc == 0 )        return 0;    /* calculate checksum */    if( mw->check != CHKVAL(mw) ) {        /* may be damaged checksum, see if block is in heap */        if( mwIsHeapOK( mw ) ) {            /* damaged checksum, repair it */            mwWrite( "internal: <%ld> %s(%d), checksum for MW-%p is incorrect\n",                mwCounter, file, line, mw );            mwIncErr();            if( mwIsReadAddr( mw->file, 1 ) ) {                ms = mwStatGet( mw->file, -1, 0 );                if( ms == NULL ) mw->file = "<relinked>";                }            else mw->file = "<unknown>";            mw->size = 0;            mw->check = CHKVAL(mw);            return 1;            }        /* no, it's just some garbage data */        return 0;        }	/* check that the non-NULL pointers are safe */	if( mw->prev && !mwIsSafeAddr( mw->prev, mwDataSize ) ) mwRelink( mw, file, line );	if( mw->next && !mwIsSafeAddr( mw->next, mwDataSize ) ) mwRelink( mw, file, line );    /* safe address, checksum OK, proceed with heap checks */    /* see if the block is in the heap */    retv = 0;    if( mw->prev ) { if( mw->prev->next == mw ) retv ++; }    else { if( mwHead == mw ) retv++; }    if( mw->next ) { if( mw->next->prev == mw ) retv ++; }    else { if( mwTail == mw ) retv++; }    if( mw->check == CHKVAL(mw) ) retv ++;    if( retv > 2 ) return 1;    /* block not in heap, check heap for corruption */    if( !mwIsHeapOK( mw ) ) {        if( mwRelink( mw, file, line ) )            return 1;        }    /* unable to repair */    mwWrite( "internal: <%ld> %s(%d), mwIsOwned fails for MW-%p\n",       mwCounter, file, line, mw );    mwIncErr();    return 0;    }/*** mwTestBuf:**  Checks a buffers links and pre/postfixes.**  Writes errors found to the log.**  Returns zero if no errors found.*/static int mwTestBuf( mwData* mw, const char* file, int line ) {    int retv = 0;    char *p;    if( file == NULL ) file = "unknown";    if( !mwIsSafeAddr( mw, mwDataSize + mwOverflowZoneSize ) ) {        mwWrite( "internal: <%ld> %s(%d): pointer MW-%p is invalid\n",            mwCounter, file, line, mw );        mwIncErr();        return 2;        }    if( mw->check != CHKVAL(mw) ) {        mwWrite( "internal: <%ld> %s(%d), info trashed; relinking\n",            mwCounter, file, line );        mwIncErr();        if( !mwRelink( mw, file, line ) ) return 2;        }    if( mw->prev && mw->prev->next != mw ) {        mwWrite( "internal: <%ld> %s(%d), buffer <%ld> %s(%d) link1 broken\n",            mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line );        mwIncErr();        if( !mwRelink( mw, file, line ) ) retv = 2;        }    if( mw->next && mw->next->prev != mw ) {        mwWrite( "internal: <%ld> %s(%d), buffer <%ld> %s(%d) link2 broken\n",            mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line );        mwIncErr();        if( !mwRelink( mw, file, line ) ) retv = 2;        }    p = ((char*)mw) + mwDataSize;    if( mwCheckOF( p ) ) {        mwWrite( "underflow: <%ld> %s(%d), %ld bytes alloc'd at <%ld> %s(%d)\n",            mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line );        mwIncErr();        retv = 1;        }    p += mwOverflowZoneSize + mw->size;    if( mwIsReadAddr( p, mwOverflowZoneSize ) && mwCheckOF( p ) ) {        mwWrite( "overflow: <%ld> %s(%d), %ld bytes alloc'd at <%ld> %s(%d)\n",            mwCounter,file,line, (long)mw->size, mw->count, mw->file, mw->line );        mwIncErr();        retv = 1;        }    return retv;    }static void mwDefaultOutFunc( int c ) {    if( mwLogR() ) fputc( c, mwLogR() );    }static void mwWrite( const char *format, ... ) {    int tot, oflow = 0;    va_list mark;    mwAutoInit();    if( mwOutFunction == NULL ) mwOutFunction = mwDefaultOutFunc;    va_start( mark, format );    tot = vsprintf( mwPrintBuf, format, mark );    va_end( mark );    if( tot >= MW_TRACE_BUFFER ) { mwPrintBuf[MW_TRACE_BUFFER] = 0; oflow = 1; }    for(tot=0;mwPrintBuf[tot];tot++)        (*mwOutFunction)( mwPrintBuf[tot] );    if( oflow ) {        mwWrite( "\ninternal: mwWrite(): WARNING! OUTPUT EXCEEDED %u CHARS: SYSTEM UNSTABLE\n", MW_TRACE_BUFFER-1 );        FLUSH();        }    return;    }static void mwLogFile( const char *name ) {    time_t tid;    (void) time( &tid );    if( mwLogR() != NULL ) {        fclose( mwLogR() );        mwLogW( NULL );        }    if( name == NULL ) return;    mwLogW( fopen( name, "a" COMMIT ) );    if( mwLogR() == NULL )        mwWrite( "logfile: failed to open/create file '%s'\n", name );    }/*** Try to free NML memory until a contiguous allocation of** 'needed' bytes can be satisfied. If this is not enough** and the 'urgent' parameter is nonzero, grabbed memory is** also freed.*/static size_t mwFreeUp( size_t needed, int urgent ) {    void *p;    mwData *mw, *mw2;    char *data;    /* free grabbed NML memory */    for(;;) {        if( mwDrop_( 1, MW_VAL_NML, 1 ) == 0 ) break;        p = malloc( needed );        if( p == NULL ) continue;        free( p );        return needed;        }    /* free normal NML memory */    mw = mwHead;    while( mw != NULL ) {        if( !(mw->flag & MW_NML) ) mw = mw->next;        else {            data = ((char*)mw)+mwDataSize+mwOverflowZoneSize;            if( mwTestMem( data, mw->size, MW_VAL_NML ) ) {                mwIncErr();                mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n",                    mw->count, data + mwOverflowZoneSize, mw->file, mw->line );                }            mw2 = mw->next;            mwUnlink( mw, "mwFreeUp", 0 );            free( mw );            mw = mw2;            p = malloc( needed );            if( p == NULL ) continue;            free( p );            return needed;            }        }    /* if not urgent (for internal purposes), fail */    if( !urgent ) return 0;    /* free grabbed memory */    for(;;) {        if( mwDrop_( 1, MW_VAL_GRB, 1 ) == 0 ) break;        p = malloc( needed );        if( p == NULL ) continue;        free( p );        return needed;        }    return 0;    }static const void * mwTestMem( const void *p, unsigned len, int c ) {    const unsigned char *ptr;    ptr = (const unsigned char *) p;    while( len-- ) {        if( *ptr != (unsigned char)c ) return (const void*)ptr;        ptr ++;        }    return NULL;    }static int mwStrCmpI( const char *s1, const char *s2 ) {    if( s1 == NULL || s2 == NULL ) return 0;    while( *s1 ) {        if( toupper(*s2) == toupper(*s1) ) { s1++; s2++; continue; }        return 1;        }    return 0;    }#define AIPH() if( always_invoked ) { mwWrite("autocheck: <%ld> %s(%d) ", mwCounter, file, line ); always_invoked = 0; }static int mwTestNow( const char *file, int line, int always_invoked ) {    int retv = 0;    mwData *mw;    char *data;    if( file && !always_invoked )        mwWrite("check: <%ld> %s(%d), checking %s%s%s\n",            mwCounter, file, line,			(mwTestFlags & MW_TEST_CHAIN) ? "chain ": "",		    (mwTestFlags & MW_TEST_ALLOC) ? "alloc ": "",		    (mwTestFlags & MW_TEST_NML) ? "nomansland ": ""			);    if( mwTestFlags & MW_TEST_CHAIN ) {        for( mw = mwHead; mw; mw=mw->next ) {			if( !mwIsSafeAddr(mw, mwDataSize) ) {				AIPH();				mwWrite("check: heap corruption detected\n");				mwIncErr();				return retv + 1;				}			if( mw->prev ) {				if( !mwIsSafeAddr(mw->prev, mwDataSize) ) {					AIPH();					mwWrite("check: heap corruption detected\n");					mwIncErr();					return retv + 1;					}				if( mw==mwHead || mw->prev->next != mw ) {					AIPH();					mwWrite("check: heap chain broken, prev link incorrect\n");					mwIncErr();					retv ++;					}				}			if( mw->next ) {				if( !mwIsSafeAddr(mw->next, mwDataSize) ) {					AIPH();					mwWrite("check: heap corruption detected\n");					mwIncErr();					return retv + 1;					}				if( mw==mwTail || mw->next->prev != mw ) {					AIPH();					mwWrite("check: heap chain broken, next link incorrect\n");					mwIncErr();					retv ++;					}				}			else if( mw!=mwTail ) {				AIPH();				mwWrite("check: heap chain broken, tail incorrect\n");				mwIncErr();				retv ++;				}            }        }    if( mwTestFlags & MW_TEST_ALLOC ) {        for( mw = mwHead; mw; mw=mw->next ) {            if( mwTestBuf( mw, file, line ) ) retv ++;            }        }    if( mwTestFlags & MW_TEST_NML ) {        for( mw = mwHead; mw; mw=mw->next ) {            if( (mw->flag & MW_NML) ) {                data = ((char*)mw)+mwDataSize+mwOverflowZoneSize;                if( mwTestMem( data, mw->size, MW_VAL_NML ) ) {                    mwIncErr();                    mwWrite( "wild pointer: <%ld> NoMansLand %p alloc'd at %s(%d)\n",                        mw-

⌨️ 快捷键说明

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