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

📄 memwatch.c

📁 程序代码使用说明: (1)所有源代码目录下都提供了Makefile(非Qt)
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* stupid compilers from squeaking about differing return modes. */    /* Smart compilers instead say 'code unreachable...' */    /*lint -save -e527 */    return 0;    /*lint -restore */    }void mwTrace( const char *format, ... ) {    int tot, oflow = 0;    va_list mark;    mwAutoInit();	MW_MUTEX_LOCK();    TESTS(NULL,0);    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 ) {        mwIncErr();        mwTrace( " [WARNING: OUTPUT BUFFER OVERFLOW - SYSTEM UNSTABLE]\n" );        }    FLUSH();	MW_MUTEX_UNLOCK();    }/************************************************************************* Grab & Drop***********************************************************************/unsigned mwGrab( unsigned kb ) {    TESTS(NULL,0);    return mwGrab_( kb, MW_VAL_GRB, 0 );    }unsigned mwDrop( unsigned kb ) {    TESTS(NULL,0);    return mwDrop_( kb, MW_VAL_GRB, 0 );    }static void mwDropAll() {    TESTS(NULL,0);    (void) mwDrop_( 0, MW_VAL_GRB, 0 );    (void) mwDrop_( 0, MW_VAL_NML, 0 );    if( mwGrabList != NULL )        mwWrite( "internal: the grab list is not empty after mwDropAll()\n");    }static const char *mwGrabType( int type ) {    switch( type ) {        case MW_VAL_GRB:            return "grabbed";        case MW_VAL_NML:            return "no-mans-land";        default:            /* do nothing */            ;        }    return "<unknown type>";    }static unsigned mwGrab_( unsigned kb, int type, int silent ) {    unsigned i = kb;    mwGrabData *gd;    if( !kb ) i = kb = 65000U;    for(;kb;kb--) {        if( mwUseLimit &&            (mwStatCurAlloc + mwGrabSize + (long)sizeof(mwGrabData) > mwAllocLimit) ) {            if( !silent ) {                mwWrite("grabbed: all allowed memory to %s (%u kb)\n",                    mwGrabType(type), i-kb);                FLUSH();                }            return i-kb;            }        gd = (mwGrabData*) malloc( sizeof(mwGrabData) );        if( gd == NULL ) {            if( !silent ) {                mwWrite("grabbed: all available memory to %s (%u kb)\n",                    mwGrabType(type), i-kb);                FLUSH();                }            return i-kb;            }        mwGrabSize += (long) sizeof(mwGrabData);        gd->next = mwGrabList;        memset( gd->blob, type, sizeof(gd->blob) );        gd->type = type;        mwGrabList = gd;        }    if( !silent ) {        mwWrite("grabbed: %u kilobytes of %s memory\n", i, mwGrabType(type) );        FLUSH();        }    return i;    }static unsigned mwDrop_( unsigned kb, int type, int silent ) {    unsigned i = kb;    mwGrabData *gd,*tmp,*pr;    const void *p;    if( mwGrabList == NULL && kb == 0 ) return 0;    if( !kb ) i = kb = 60000U;    pr = NULL;    gd = mwGrabList;    for(;kb;) {        if( gd == NULL ) {            if( i-kb > 0 && !silent ) {                mwWrite("dropped: all %s memory (%u kb)\n", mwGrabType(type), i-kb);                FLUSH();                }            return i-kb;            }        if( gd->type == type ) {            if( pr ) pr->next = gd->next;            kb --;            tmp = gd;            if( mwGrabList == gd ) mwGrabList = gd->next;            gd = gd->next;            p = mwTestMem( tmp->blob, sizeof( tmp->blob ), type );            if( p != NULL ) {                mwWrite( "wild pointer: <%ld> %s memory hit at %p\n",                    mwCounter, mwGrabType(type), p );                FLUSH();                }            mwGrabSize -= (long) sizeof(mwGrabData);            free( tmp );            }        else {            pr = gd;            gd = gd->next;            }        }    if( !silent ) {        mwWrite("dropped: %u kilobytes of %s memory\n", i, mwGrabType(type) );        FLUSH();        }    return i;    }/************************************************************************* No-Mans-Land***********************************************************************/void mwNoMansLand( int level ) {    mwAutoInit();    TESTS(NULL,0);    switch( level ) {        case MW_NML_NONE:            (void) mwDrop_( 0, MW_VAL_NML, 0 );            break;        case MW_NML_FREE:            break;        case MW_NML_ALL:            (void) mwGrab_( 0, MW_VAL_NML, 0 );            break;        default:            return;        }    mwNML = level;    }/************************************************************************* Static functions***********************************************************************/static void mwAutoInit( void ){    if( mwInited ) return;    mwUseAtexit = 1;    mwInit();    return;}static FILE *mwLogR() {    if( (mwLog == mwLogB1) && (mwLog == mwLogB2) ) return mwLog;    if( mwLog == mwLogB1 ) mwLogB2 = mwLog;    if( mwLog == mwLogB2 ) mwLogB1 = mwLog;    if( mwLogB1 == mwLogB2 ) mwLog = mwLogB1;    if( (mwLog == mwLogB1) && (mwLog == mwLogB2) ) {        mwWrite("internal: log file handle damaged and recovered\n");        FLUSH();        return mwLog;        }    fprintf(mwSTDERR,"\nMEMWATCH: log file handle destroyed, using mwSTDERR\n" );    mwLog = mwLogB1 = mwLogB2 = mwSTDERR;    return mwSTDERR;    }static void mwLogW( FILE *p ) {    mwLog = mwLogB1 = mwLogB2 = p;    }static int mwFlushR() {    if( (mwFlushing == mwFlushingB1) && (mwFlushing == mwFlushingB2) ) return mwFlushing;    if( mwFlushing == mwFlushingB1 ) mwFlushingB2 = mwFlushing;    if( mwFlushing == mwFlushingB2 ) mwFlushingB1 = mwFlushing;    if( mwFlushingB1 == mwFlushingB2 ) mwFlushing = mwFlushingB1;    if( (mwFlushing == mwFlushingB1) && (mwFlushing == mwFlushingB2) ) {        mwWrite("internal: flushing flag damaged and recovered\n");        FLUSH();        return mwFlushing;        }    mwWrite("internal: flushing flag destroyed, so set to true\n");    mwFlushing = mwFlushingB1 = mwFlushingB2 = 1;    return 1;    }static void mwFlushW( int n ) {    mwFlushing = mwFlushingB1 = mwFlushingB2 = n;    }static void mwIncErr() {    mwErrors++;    mwFlushW( mwFlushR()+1 );    FLUSH();    }static void mwFlush() {    if( mwLogR() == NULL ) return;#ifdef MW_FLUSH    fflush( mwLogR() );#else    if( mwFlushR() ) fflush( mwLogR() );#endif    return;    }static void mwUnlink( mwData* mw, const char* file, int line ) {    if( mw->prev == NULL ) {        if( mwHead != mw )            mwWrite( "internal: <%ld> %s(%d), MW-%p: link1 NULL, but not head\n",                mwCounter, file, line, mw );        mwHead = mw->next;        }    else {        if( mw->prev->next != mw )            mwWrite( "internal: <%ld> %s(%d), MW-%p: link1 failure\n",                mwCounter, file, line, mw );        else mw->prev->next = mw->next;        }    if( mw->next == NULL ) {        if( mwTail != mw )            mwWrite( "internal: <%ld> %s(%d), MW-%p: link2 NULL, but not tail\n",                mwCounter, file, line, mw );        mwTail = mw->prev;        }    else {        if( mw->next->prev != mw )            mwWrite( "internal: <%ld> %s(%d), MW-%p: link2 failure\n",                mwCounter, file, line, mw );        else mw->next->prev = mw->prev;        }    }/*** Relinking tries to repair a damaged mw block.** Returns nonzero if it thinks it successfully** repaired the heap chain.*/static int mwRelink( mwData* mw, const char* file, int line ) {    int fails;    mwData *mw1, *mw2;    long count, size;    mwStat *ms;	if( file == NULL ) file = "unknown";    if( mw == NULL ) {        mwWrite("relink: cannot repair MW at NULL\n");        FLUSH();        goto emergency;        }    if( !mwIsSafeAddr(mw, mwDataSize) ) {        mwWrite("relink: MW-%p is a garbage pointer\n", mw);        FLUSH();        goto emergency;        }    mwWrite("relink: <%ld> %s(%d) attempting to repair MW-%p...\n", mwCounter, file, line, mw );    FLUSH();    fails = 0;    /* Repair from head */    if( mwHead != mw ) {        if( !mwIsSafeAddr( mwHead, mwDataSize ) ) {            mwWrite("relink: failed for MW-%p; head pointer destroyed\n", mw );            FLUSH();            goto emergency;            }        for( mw1=mwHead; mw1; mw1=mw1->next ) {            if( mw1->next == mw ) {                mw->prev = mw1;                break;                }            if( mw1->next &&                ( !mwIsSafeAddr(mw1->next, mwDataSize ) || mw1->next->prev != mw1) ) {                mwWrite("relink: failed for MW-%p; forward chain fragmented at MW-%p: 'next' is %p\n", mw, mw1, mw1->next );                FLUSH();                goto emergency;                }            }        if( mw1 == NULL ) {            mwWrite("relink: MW-%p not found in forward chain search\n", mw );            FLUSH();            fails ++;            }        }	else	{		mwWrite( "relink: MW-%p is the head (first) allocation\n", mw );		if( mw->prev != NULL )		{			mwWrite( "relink: MW-%p prev pointer is non-NULL, you have a wild pointer\n", mw );			mw->prev = NULL;		}	}    /* Repair from tail */    if( mwTail != mw ) {        if( !mwIsSafeAddr( mwTail, mwDataSize ) ) {            mwWrite("relink: failed for MW-%p; tail pointer destroyed\n", mw );            FLUSH();            goto emergency;            }        for( mw1=mwTail; mw1; mw1=mw1->prev ) {            if( mw1->prev == mw ) {                mw->next = mw1;                break;                }            if( mw1->prev && (!mwIsSafeAddr(mw1->prev, mwDataSize ) || mw1->prev->next != mw1) ) {                mwWrite("relink: failed for MW-%p; reverse chain fragmented at MW-%p, 'prev' is %p\n", mw, mw1, mw1->prev );                FLUSH();                goto emergency;                }            }        if( mw1 == NULL ) {            mwWrite("relink: MW-%p not found in reverse chain search\n", mw );            FLUSH();            fails ++;            }        }	else	{		mwWrite( "relink: MW-%p is the tail (last) allocation\n", mw );		if( mw->next != NULL )		{			mwWrite( "relink: MW-%p next pointer is non-NULL, you have a wild pointer\n", mw );			mw->next = NULL;		}	}    if( fails > 1 ) {        mwWrite("relink: heap appears intact, MW-%p probably garbage pointer\n", mw );        FLUSH();        goto verifyok;        }    /* restore MW info where possible */    if( mwIsReadAddr( mw->file, 1 ) ) {        ms = mwStatGet( mw->file, -1, 0 );        if( ms == NULL ) mw->file = "<relinked>";        }    mw->check = CHKVAL(mw);    goto verifyok;    /* Emergency repair */    emergency:    if( mwHead == NULL && mwTail == NULL )    {        if( mwStatCurAlloc == 0 )            mwWrite("relink: <%ld> %s(%d) heap is empty, nothing to repair\n", mwCounter, file, line );        else            mwWrite("relink: <%ld> %s(%d) heap damaged beyond repair\n", mwCounter, file, line );        FLUSH();        return 0;    }    mwWrite("relink: <%ld> %s(%d) attempting emergency repairs...\n", mwCounter, file, line );    FLUSH();	if( mwHead == NULL || mwTail == NULL )	{		if( mwHead == NULL ) mwWrite("relink: mwHead is NULL, but mwTail is %p\n", mwTail );		else mwWrite("relink: mwTail is NULL, but mwHead is %p\n", mwHead );	}    mw1=NULL;    if( mwHead != NULL )	{		if( !mwIsReadAddr( mwHead, mwDataSize ) || mwHead->check != CHKVAL(mwHead) )		{			mwWrite("relink: mwHead (MW-%p) is damaged, skipping forward scan\n", mwHead );			mwHead = NULL;			goto scan_reverse;		}		if( mwHead->prev != NULL )		{			mwWrite("relink: the mwHead pointer's 'prev' member is %p, not NULL\n", mwHead->prev );		}        for( mw1=mwHead; mw1; mw1=mw1->next )		{			if( mw1->next )			{				if( !mwIsReadAddr(mw1->next,mwDataSize) ||					!mw1->next->check != CHKVAL(mw1) ||					mw1->next->prev != mw1 )				{					mwWrite("relink: forward chain's last intact MW is MW-%p, %ld %sbytes at %s(%d)\n",						mw1, mw1->size, (mw->flag & MW_NML)?"NoMansLand ":"", mw1->file, mw1->line );					if( mwIsReadAddr(mw1->next,mwDataSize ) )					{						mwWrite("relink: forward chain's first damaged MW is MW-%p, %ld %sbytes at %s(%d)\n",							mw1->next, mw1->size, (mw->flag & MW_NML)?"NoMansLand ":"",							mwIsReadAddr(mw1->file,16)?mw1->file:"<garbage-pointer>", mw1->line );					}					else					{						mwWrite("relink: the 'next' pointer of this MW points to %p, which is out-of-legal-access\n",							mw1->next );					}					break;				}			}        }	}scan_reverse:    mw2=NULL;    if( mwTail != NULL )	{		if( !mwIsReadAddr(mwTail,mwDataSize) || mwTail->check != CHKVAL(mwTail) )		{

⌨️ 快捷键说明

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