home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
dbmalloc-1.14-src.tgz
/
tar.out
/
contrib
/
dbmalloc
/
mcheck.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
11KB
|
460 lines
/*
* (c) Copyright 1990, 1991, 1992 Conor P. Cahill (cpcahil@virtech.vti.com)
*
* This software may be distributed freely as long as the following conditions
* are met:
* * the distribution, or any derivative thereof, may not be
* included as part of a commercial product
* * full source code is provided including this copyright
* * there is no charge for the software itself (there may be
* a minimal charge for the copying or distribution effort)
* * this copyright notice is not modified or removed from any
* source file
*/
#include <stdio.h>
#include "mallocin.h"
#include "debug.h"
#ifndef lint
static
char rcs_hdr[] = "$Id: mcheck.c,v 1.22 1992/08/22 16:27:13 cpcahil Exp $";
#endif
#define malloc_in_arena(ptr) ( ((DATATYPE*)(ptr) >= malloc_data_start) \
&& ((DATATYPE*)(ptr) <= malloc_data_end) )
/*
* Function: malloc_check_str()
*
* Arguments: func - name of function calling this routine
* str - pointer to area to check
*
* Purpose: to verify that if str is within the malloc arena, the data
* it points to does not extend beyond the applicable region.
*
* Returns: Nothing of any use (function is void).
*
* Narrative:
* IF pointer is within malloc arena
* determin length of string
* call malloc_verify() to verify data is withing applicable region
* return
*
* Mod History:
* 90/01/24 cpcahil Initial revision.
* 90/01/29 cpcahil Added code to ignore recursive calls.
*/
VOIDTYPE
malloc_check_str(func,file,line,str)
CONST char * func;
CONST char * file;
int line;
CONST char * str;
{
static int layers;
register CONST char * s;
MALLOC_INIT();
/*
* if we are already in the malloc library somewhere, don't check
* things again.
*/
if( in_malloc_code || (! (malloc_opts & MOPT_CKDATA) ) )
{
return;
}
if( (layers++ == 0) && malloc_in_arena(str) )
{
for( s=str; *s; s++)
{
}
malloc_verify(func,file,line,str,(SIZETYPE)(s-str+1));
}
layers--;
}
/*
* Function: malloc_check_strn()
*
* Arguments: func - name of function calling this routine
* str - pointer to area to check
* len - max length of string
*
* Purpose: to verify that if str is within the malloc arena, the data
* it points to does not extend beyond the applicable region.
*
* Returns: Nothing of any use (function is void).
*
* Narrative:
* IF pointer is within malloc arena
* determin length of string
* call malloc_verify() to verify data is withing applicable region
* return
*
* Mod History:
* 90/01/24 cpcahil Initial revision.
* 90/01/29 cpcahil Added code to ignore recursive calls.
* 90/08/29 cpcahil added length (for strn* functions)
*/
VOIDTYPE
malloc_check_strn(func,file,line,str,len)
CONST char * func;
CONST char * file;
int line;
CONST char * str;
STRSIZE len;
{
register STRSIZE i;
static int layers;
register CONST char * s;
MALLOC_INIT();
/*
* if we are already in the malloc library somewhere, don't check
* things again.
*/
if( in_malloc_code || (! (malloc_opts & MOPT_CKDATA) ) )
{
return;
}
if( (layers++ == 0) && malloc_in_arena(str) )
{
for( s=str,i=0; (i < len) && (*s != '\0'); i++,s++)
{
}
/*
* if we found a null byte before len, add one to s so
* that we ensure that the null is counted in the bytes to
* check.
*/
if( i < len )
{
s++;
}
malloc_verify(func,file,line,str,(SIZETYPE)(s-str));
}
layers--;
}
/*
* Function: malloc_check_data()
*
* Arguments: func - name of function calling this routine
* ptr - pointer to area to check
* len - length to verify
*
* Purpose: to verify that if ptr is within the malloc arena, the data
* it points to does not extend beyond the applicable region.
*
* Returns: Nothing of any use (function is void).
*
* Narrative:
* IF pointer is within malloc arena
* call malloc_verify() to verify data is withing applicable region
* return
*
* Mod History:
* 90/01/24 cpcahil Initial revision.
* 90/01/29 cpcahil Added code to ignore recursive calls.
*/
VOIDTYPE
malloc_check_data(func,file,line,ptr,len)
CONST char * func;
CONST char * file;
int line;
CONST DATATYPE * ptr;
SIZETYPE len;
{
static int layers;
MALLOC_INIT();
/*
* if we are already in the malloc library somewhere, don't check
* things again.
*/
if( in_malloc_code || (! (malloc_opts & MOPT_CKDATA) ) )
{
return;
}
if( layers++ == 0 )
{
DEBUG3(40,"malloc_check_data(%s,0x%x,%d) called...",
func,ptr,len);
if( malloc_in_arena(ptr) )
{
DEBUG0(10,"pointer in malloc arena, verifying...");
malloc_verify(func,file,line,ptr,len);
}
}
layers--;
}
/*
* Function: malloc_verify()
*
* Arguments: func - name of function calling the malloc check routines
* ptr - pointer to area to check
* len - length to verify
*
* Purpose: to verify that the data ptr points to does not extend beyond
* the applicable malloc region. This function is only called
* if it has been determined that ptr points into the malloc arena.
*
* Returns: Nothing of any use (function is void).
*
* Narrative:
*
* Mod History:
* 90/01/24 cpcahil Initial revision.
*/
VOIDTYPE
malloc_verify(func,file,line,ptr,len)
CONST char * func;
CONST char * file;
int line;
register CONST DATATYPE * ptr;
register SIZETYPE len;
{
register CONST struct mlist * mptr = NULL;
DEBUG5(40,"malloc_verify(%s, %s, %s, 0x%x,%d) called...",
func, file, line, ptr, len);
/*
* since we know we have a pointer that is somewhere within the
* malloc region, let's take a guess that the current pointer is
* at the begining of a region and see if it has the correct values
*/
/*
* if we are on the correct boundry for a malloc data area pointer
*/
if( (((long)ptr) & malloc_round) == 0 )
{
mptr = (CONST struct mlist *)(((CONST char *) ptr ) - M_SIZE);
if( ! GoodMlist(mptr) )
{
mptr = (CONST struct mlist *) NULL;
}
}
/*
* if we haven't found it yet, let's try to look back just a few bytes
* to see if it is nearby
*/
if( mptr == (struct mlist *) NULL)
{
register long * lptr;
register int i;
lptr = (long *) (((long)ptr) & ~malloc_round);
for(i=0; i < MAX_KLUDGE_CHECKS; i++)
{
lptr--;
if( ! malloc_in_arena(lptr) )
{
mptr = (CONST struct mlist *) NULL;
break;
}
/*
* if we found the magic number
*/
if( ((*lptr) & M_MAGIC_BITS) == M_MAGIC )
{
mptr = (CONST struct mlist *)
(((CONST char *)lptr) - M_FLAGOFF);
/*
* if the pointer is good.
*/
if( GoodMlist(mptr) )
{
break;
}
}
}
/*
* if we didn't find an entry, make sure mptr is null
*/
if( i == MAX_KLUDGE_CHECKS )
{
mptr = (CONST struct mlist *) NULL;
}
}
/*
* if we still haven't found the right segment, we have to do it the
* hard way and search along the malloc list
*/
if( mptr == (CONST struct mlist *) NULL)
{
/*
* Find the malloc block that includes this pointer
*/
mptr = &malloc_start;
while( mptr
&& ! ((((CONST DATATYPE *)mptr) < (CONST DATATYPE *)ptr)
&& (((DATATYPE *)(mptr->data+mptr->s.size)) > ptr) ) )
{
mptr = mptr->next;
}
}
/*
* if ptr was not in a malloc block, it must be part of
* some direct sbrk() stuff, so just return.
*/
if( ! mptr )
{
DEBUG1(10,"ptr (0x%x) not found in malloc search", ptr);
return;
}
/*
* Now we have a valid malloc block that contains the indicated
* pointer. We must verify that it is withing the requested block
* size (as opposed to the real block size which is rounded up to
* allow for correct alignment).
*/
DEBUG4(60,"Checking 0x%x-0x%x, 0x%x-0x%x",
ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
if( (ptr < (DATATYPE *)mptr->data)
|| ((((CONST char *)ptr)+len) > (char *)(mptr->data+mptr->r_size)) )
{
DEBUG4(0,"pointer not within region 0x%x-0x%x, 0x%x-0x%x",
ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
malloc_errno = M_CODE_OUTOF_BOUNDS;
malloc_warning(func,file,line,mptr);
}
else if ( (mptr->flag&M_INUSE) == 0 )
{
DEBUG4(0,"segment not in use 0x%x-0x%x, 0x%x-0x%x",
ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
malloc_errno = M_CODE_NOT_INUSE;
malloc_warning(func,file,line,mptr);
}
return;
}
/*
* GoodMlist() - return true if mptr appears to point to a valid segment
*/
int
GoodMlist(mptr)
register CONST struct mlist * mptr;
{
/*
* return true if
* 1. the segment has a valid magic number
* 2. the inuse flag is set
* 3. the previous linkage is set correctly
* 4. the next linkage is set correctly
* 5. either next and prev is not null
*/
return( ((mptr->flag&M_MAGIC_BITS) == M_MAGIC)
&& ((mptr->flag&M_INUSE) != 0 )
&& (mptr->prev ?
(malloc_in_arena(mptr->prev) && (mptr->prev->next == mptr)) : 1 )
&& (mptr->next ?
(malloc_in_arena(mptr->next) && (mptr->next->prev == mptr)) : 1 )
&& ((mptr->next == NULL) || (mptr->prev == NULL)) );
} /* GoodMlist(... */
/*
* $Log: mcheck.c,v $
* Revision 1.22 1992/08/22 16:27:13 cpcahil
* final changes for pl14
*
* Revision 1.21 1992/06/27 22:48:48 cpcahil
* misc fixes per bug reports from first week of reviews
*
* Revision 1.20 1992/06/22 23:40:10 cpcahil
* many fixes for working on small int systems
*
* Revision 1.19 1992/05/09 00:16:16 cpcahil
* port to hpux and lots of fixes
*
* Revision 1.18 1992/05/08 02:30:35 cpcahil
* minor cleanups from minix/atari port
*
* Revision 1.17 1992/05/08 01:44:11 cpcahil
* more performance enhancements
*
* Revision 1.16 1992/05/06 04:53:29 cpcahil
* performance enhancments
*
* Revision 1.15 1992/04/13 03:06:33 cpcahil
* Added Stack support, marking of non-leaks, auto-config, auto-testing
*
* Revision 1.14 1992/03/01 12:42:38 cpcahil
* added support for managing freed areas and fixed doublword bndr problems
*
* Revision 1.13 1992/01/30 12:23:06 cpcahil
* renamed mallocint.h -> mallocin.h
*
* Revision 1.12 1992/01/10 17:51:03 cpcahil
* more void stuff that slipped by
*
* Revision 1.11 1992/01/10 17:28:03 cpcahil
* Added support for overriding void datatype
*
* Revision 1.10 1991/12/31 02:23:29 cpcahil
* fixed verify bug of strncpy when len was exactly same as strlen
*
* Revision 1.9 91/12/02 19:10:12 cpcahil
* changes for patch release 5
*
* Revision 1.8 91/11/25 14:42:01 cpcahil
* Final changes in preparation for patch 4 release
*
* Revision 1.7 91/11/24 00:49:29 cpcahil
* first cut at patch 4
*
* Revision 1.6 91/11/20 11:54:11 cpcahil
* interim checkin
*
* Revision 1.5 90/08/29 22:23:48 cpcahil
* added new function to check on strings up to a specified length
* and used it within several strn* functions.
*
* Revision 1.4 90/05/11 00:13:09 cpcahil
* added copyright statment
*
* Revision 1.3 90/02/24 21:50:22 cpcahil
* lots of lint fixes
*
* Revision 1.2 90/02/24 17:29:38 cpcahil
* changed $Header to $Id so full path wouldnt be included as part of rcs
* id string
*
* Revision 1.1 90/02/24 14:57:03 cpcahil
* Initial revision
*
*/