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

📄 memwatch.c

📁 最近在UNIX下开发代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        }    mw = (mwData*) malloc( needed );    if( mw == NULL ) {        if( mwFreeUp(needed,0) >= needed ) {            mw = (mwData*) malloc(needed);            if( mw == NULL ) {                mwWrite( "internal: mwFreeUp(%u) reported success, but malloc() fails\n", needed );                mwIncErr();                FLUSH();                }            }        if( mw == NULL ) {            mwWrite( "fail: <%ld> %s(%d), %ld wanted %ld allocated\n",                mwCounter, file, line, (long)size, mwStatCurAlloc );            mwIncErr();            FLUSH();			MW_MUTEX_UNLOCK();            return NULL;            }        }    mw->count = mwCounter;    mw->prev = NULL;    mw->next = mwHead;    mw->file = file;    mw->size = size;    mw->line = line;    mw->flag = 0;    mw->check = CHKVAL(mw);    if( mwHead ) mwHead->prev = mw;    mwHead = mw;    if( mwTail == NULL ) mwTail = mw;    ptr = ((char*)mw) + mwDataSize;	mwWriteOF( ptr ); /* '*(long*)ptr = PRECHK;' */    ptr += mwOverflowZoneSize;    p = ptr;    memset( ptr, MW_VAL_NEW, size );    ptr += size;    mwWriteOF( ptr ); /* '*(long*)ptr = POSTCHK;' */    mwNumCurAlloc ++;    mwStatCurAlloc += (long) size;    mwStatTotAlloc += (long) size;    if( mwStatCurAlloc > mwStatMaxAlloc )        mwStatMaxAlloc = mwStatCurAlloc;    mwStatNumAlloc ++;    if( mwStatLevel ) mwStatAlloc( size, file, line );	MW_MUTEX_UNLOCK();    return p;    }void* mwRealloc( void *p, size_t size, const char* file, int line) {    int oldUseLimit, i;    mwData *mw;    char *ptr;    mwAutoInit();    if( p == NULL ) return mwMalloc( size, file, line );    if( size == 0 ) { mwFree( p, file, line ); return NULL; }	MW_MUTEX_LOCK();    /* do the quick ownership test */    mw = (mwData*) mwBUFFER_TO_MW( p );    if( mwIsOwned( mw, file, line ) ) {		/* if the buffer is an NML, treat this as a double-free */		if( mw->flag & MW_NML )		{            mwIncErr();			if( *((unsigned char*)(mw)+mwDataSize+mwOverflowZoneSize) != MW_VAL_NML )			{				mwWrite( "internal: <%ld> %s(%d), no-mans-land MW-%p is corrupted\n",					mwCounter, file, line, mw );			}			goto check_dbl_free;		}        /* if this allocation would violate the limit, fail it */        if( mwUseLimit && ((long)size + mwStatCurAlloc - (long)mw->size > mwAllocLimit) ) {            TESTS(file,line);            mwCounter ++;            mwWrite( "limit fail: <%ld> %s(%d), %ld wanted %ld available\n",                mwCounter, file, line, (unsigned long)size - mw->size, mwAllocLimit - mwStatCurAlloc );            mwIncErr();            FLUSH();			MW_MUTEX_UNLOCK();            return NULL;            }        /* fake realloc operation */        oldUseLimit = mwUseLimit;        mwUseLimit = 0;        ptr = (char*) mwMalloc( size, file, line );        if( ptr != NULL ) {            if( size < mw->size )                memcpy( ptr, p, size );            else                memcpy( ptr, p, mw->size );            mwFree( p, file, line );            }        mwUseLimit = oldUseLimit;		MW_MUTEX_UNLOCK();        return (void*) ptr;        }    /* Unknown pointer! */    /* using free'd pointer? */check_dbl_free:    for(i=0;i<MW_FREE_LIST;i++) {        if( mwLastFree[i] == p ) {            mwIncErr();            mwWrite( "realloc: <%ld> %s(%d), %p was"                " freed from %s(%d)\n",                mwCounter, file, line, p,                mwLFfile[i], mwLFline[i] );            FLUSH();			MW_MUTEX_UNLOCK();            return NULL;            }        }    /* some weird pointer */    mwIncErr();    mwWrite( "realloc: <%ld> %s(%d), unknown pointer %p\n",        mwCounter, file, line, p );    FLUSH();	MW_MUTEX_UNLOCK();    return NULL;    }char *mwStrdup( const char* str, const char* file, int line ) {    size_t len;    char *newstring;	MW_MUTEX_LOCK();    if( str == NULL ) {        mwIncErr();        mwWrite( "strdup: <%ld> %s(%d), strdup(NULL) called\n",            mwCounter, file, line );        FLUSH();		MW_MUTEX_UNLOCK();        return NULL;        }    len = strlen( str ) + 1;    newstring = (char*) mwMalloc( len, file, line );    if( newstring != NULL ) memcpy( newstring, str, len );	MW_MUTEX_UNLOCK();    return newstring;    }void mwFree( void* p, const char* file, int line ) {    int i;    mwData* mw;    char buffer[ sizeof(mwData) + (mwROUNDALLOC*3) + 64 ];    /* this code is in support of C++ delete */    if( file == NULL ) {        mwFree_( p );		MW_MUTEX_UNLOCK();        return;        }    mwAutoInit();	MW_MUTEX_LOCK();    TESTS(file,line);    mwCounter ++;    /* on NULL free, write a warning and return */    if( p == NULL ) {        mwWrite( "NULL free: <%ld> %s(%d), NULL pointer free'd\n",            mwCounter, file, line );        FLUSH();		MW_MUTEX_UNLOCK();        return;        }    /* do the quick ownership test */    mw = (mwData*) mwBUFFER_TO_MW( p );    if( mwIsOwned( mw, file, line ) ) {        (void) mwTestBuf( mw, file, line );		/* if the buffer is an NML, treat this as a double-free */		if( mw->flag & MW_NML )		{			if( *(((unsigned char*)mw)+mwDataSize+mwOverflowZoneSize) != MW_VAL_NML )			{				mwWrite( "internal: <%ld> %s(%d), no-mans-land MW-%p is corrupted\n",					mwCounter, file, line, mw );			}			goto check_dbl_free;		}        /* update the statistics */        mwNumCurAlloc --;        mwStatCurAlloc -= (long) mw->size;        if( mwStatLevel ) mwStatFree( mw->size, mw->file, mw->line );        /* we should either free the allocation or keep it as NML */        if( mwNML ) {            mw->flag |= MW_NML;			mwNmlNumAlloc ++;			mwNmlCurAlloc += (long) mw->size;            memset( ((char*)mw)+mwDataSize+mwOverflowZoneSize, MW_VAL_NML, mw->size );            }        else {            /* unlink the allocation, and enter the post-free data */            mwUnlink( mw, file, line );            memset( mw, MW_VAL_DEL,                mw->size + mwDataSize+mwOverflowZoneSize+mwOverflowZoneSize );            if( mwFBI ) {                memset( mw, '.', mwDataSize + mwOverflowZoneSize );                sprintf( buffer, "FBI<%ld>%s(%d)", mwCounter, file, line );                strncpy( (char*)(void*)mw, buffer, mwDataSize + mwOverflowZoneSize );                }            free( mw );            }        /* add the pointer to the last-free track */        mwLFfile[ mwLFcur ] = file;        mwLFline[ mwLFcur ] = line;        mwLastFree[ mwLFcur++ ] = p;        if( mwLFcur == MW_FREE_LIST ) mwLFcur = 0;		MW_MUTEX_UNLOCK();        return;        }    /* check for double-freeing */check_dbl_free:    for(i=0;i<MW_FREE_LIST;i++) {        if( mwLastFree[i] == p ) {            mwIncErr();            mwWrite( "double-free: <%ld> %s(%d), %p was"                " freed from %s(%d)\n",                mwCounter, file, line, p,                mwLFfile[i], mwLFline[i] );            FLUSH();			MW_MUTEX_UNLOCK();            return;            }        }    /* some weird pointer... block the free */    mwIncErr();    mwWrite( "WILD free: <%ld> %s(%d), unknown pointer %p\n",        mwCounter, file, line, p );    FLUSH();	MW_MUTEX_UNLOCK();    return;    }void* mwCalloc( size_t a, size_t b, const char *file, int line ) {    void *p;    size_t size = a * b;    p = mwMalloc( size, file, line );    if( p == NULL ) return NULL;    memset( p, 0, size );    return p;    }void mwFree_( void *p ) {	MW_MUTEX_LOCK();    TESTS(NULL,0);	MW_MUTEX_UNLOCK();    free(p);    }void* mwMalloc_( size_t size ) {	MW_MUTEX_LOCK();    TESTS(NULL,0);	MW_MUTEX_UNLOCK();    return malloc( size );    }void* mwRealloc_( void *p, size_t size ) {	MW_MUTEX_LOCK();    TESTS(NULL,0);	MW_MUTEX_UNLOCK();    return realloc( p, size );    }void* mwCalloc_( size_t a, size_t b ) {	MW_MUTEX_LOCK();    TESTS(NULL,0);	MW_MUTEX_UNLOCK();    return calloc( a, b );    }void mwFlushNow( void ) {    if( mwLogR() ) fflush( mwLogR() );    return;    }void mwDoFlush( int onoff ) {    mwFlushW( onoff<1?0:onoff );    if( onoff ) if( mwLogR() ) fflush( mwLogR() );    return;    }void mwLimit( long lim ) {    TESTS(NULL,0);    mwWrite("limit: old limit = ");    if( !mwAllocLimit ) mwWrite( "none" );    else mwWrite( "%ld bytes", mwAllocLimit );    mwWrite( ", new limit = ");    if( !lim ) {        mwWrite( "none\n" );        mwUseLimit = 0;        }    else {        mwWrite( "%ld bytes\n", lim );        mwUseLimit = 1;        }    mwAllocLimit = lim;    FLUSH();    }void mwSetAriAction( int action ) {	MW_MUTEX_LOCK();    TESTS(NULL,0);    mwAriAction = action;	MW_MUTEX_UNLOCK();    return;    }int mwAssert( int exp, const char *exps, const char *fn, int ln ) {    int i;    char buffer[MW_TRACE_BUFFER+8];    if( exp ) {    	return 0;    	}    mwAutoInit();	MW_MUTEX_LOCK();    TESTS(fn,ln);    mwIncErr();    mwCounter++;    mwWrite( "assert trap: <%ld> %s(%d), %s\n", mwCounter, fn, ln, exps );    if( mwAriFunction != NULL ) {        sprintf( buffer, "MEMWATCH: assert trap: %s(%d), %s", fn, ln, exps );        i = (*mwAriFunction)(buffer);		switch( i ) {			case MW_ARI_IGNORE:	           	mwWrite( "assert trap: <%ld> IGNORED - execution continues\n", mwCounter );				MW_MUTEX_UNLOCK();    	        return 0;			case MW_ARI_RETRY:            	mwWrite( "assert trap: <%ld> RETRY - executing again\n", mwCounter );				MW_MUTEX_UNLOCK();            	return 1;			}        }    else {        if( mwAriAction & MW_ARI_IGNORE ) {            mwWrite( "assert trap: <%ld> AUTO IGNORED - execution continues\n", mwCounter );			MW_MUTEX_UNLOCK();            return 0;            }        fprintf(mwSTDERR,"\nMEMWATCH: assert trap: %s(%d), %s\n", fn, ln, exps );        }    FLUSH();    (void) mwTestNow( fn, ln, 1 );    FLUSH();	if( mwAriAction & MW_ARI_NULLREAD ) {		/* This is made in an attempt to kick in */		/* any debuggers or OS stack traces */	    FLUSH();		/*lint -save -e413 */		i = *((int*)NULL);		mwDummy( (char)i );		/*lint -restore */		}	MW_MUTEX_UNLOCK();    exit(255);    /* NOT REACHED - the return statement is in to keep */    /* stupid compilers from squeaking about differing return modes. */    /* Smart compilers instead say 'code unreachable...' */    /*lint -save -e527 */    return 0;    /*lint -restore */    }int mwVerify( int exp, const char *exps, const char *fn, int ln ) {    int i;    char buffer[MW_TRACE_BUFFER+8];    if( exp ) {    	return 0;    	}    mwAutoInit();	MW_MUTEX_LOCK();    TESTS(fn,ln);    mwIncErr();    mwCounter++;    mwWrite( "verify trap: <%ld> %s(%d), %s\n", mwCounter, fn, ln, exps );    if( mwAriFunction != NULL ) {        sprintf( buffer, "MEMWATCH: verify trap: %s(%d), %s", fn, ln, exps );        i = (*mwAriFunction)(buffer);        if( i == 0 ) {            mwWrite( "verify trap: <%ld> IGNORED - execution continues\n", mwCounter );			MW_MUTEX_UNLOCK();            return 0;            }        if( i == 1 ) {            mwWrite( "verify trap: <%ld> RETRY - executing again\n", mwCounter );			MW_MUTEX_UNLOCK();            return 1;            }        }    else {        if( mwAriAction & MW_ARI_NULLREAD ) {            /* This is made in an attempt to kick in */            /* any debuggers or OS stack traces */		    FLUSH();            /*lint -save -e413 */            i = *((int*)NULL);			mwDummy( (char)i );            /*lint -restore */            }        if( mwAriAction & MW_ARI_IGNORE ) {            mwWrite( "verify trap: <%ld> AUTO IGNORED - execution continues\n", mwCounter );			MW_MUTEX_UNLOCK();            return 0;            }        fprintf(mwSTDERR,"\nMEMWATCH: verify trap: %s(%d), %s\n", fn, ln, exps );        }    FLUSH();    (void) mwTestNow( fn, ln, 1 );    FLUSH();	MW_MUTEX_UNLOCK();	exit(255);    /* NOT REACHED - the return statement is in to keep */

⌨️ 快捷键说明

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