188 lines
4.6 KiB
C
188 lines
4.6 KiB
C
/*
|
|
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
|
* You may copy, distribute, and use this software as long as this
|
|
* copyright statement is not removed.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
#include "malloc.h"
|
|
|
|
/*
|
|
* Function: malloc_chain_check()
|
|
*
|
|
* Purpose: to verify malloc chain is intact
|
|
*
|
|
* Arguments: todo - 0 - just check and return status
|
|
* 1 - call malloc_warn if error detected
|
|
*
|
|
* Returns: 0 - malloc chain intact & no overflows
|
|
* other - problems detected in malloc chain
|
|
*
|
|
* Narrative:
|
|
*
|
|
* Notes: If todo is non-zero the malloc_warn function, when called
|
|
* may not return (i.e. it may exit)
|
|
*
|
|
*/
|
|
#ifndef lint
|
|
static
|
|
char rcs_hdr[] = "$Id: mlc_chn.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $";
|
|
#endif
|
|
|
|
|
|
int
|
|
malloc_chain_check(todo)
|
|
int todo;
|
|
{
|
|
char * func = "malloc_chain_check";
|
|
int i;
|
|
extern char * malloc_data_start;
|
|
extern char * malloc_data_end;
|
|
extern struct mlist * malloc_end;
|
|
extern int malloc_errno;
|
|
extern struct mlist malloc_start;
|
|
struct mlist * oldptr;
|
|
struct mlist * ptr;
|
|
int rtn = 0;
|
|
|
|
oldptr = &malloc_start;
|
|
for(ptr = malloc_start.next; ; ptr = ptr->next)
|
|
{
|
|
/*
|
|
* Since the malloc chain is a forward only chain, any
|
|
* pointer that we get should always be positioned in
|
|
* memory following the previous pointer. If this is not
|
|
* so, we must have a corrupted chain.
|
|
*/
|
|
if( ptr )
|
|
{
|
|
if(ptr < oldptr )
|
|
{
|
|
malloc_errno = M_CODE_CHAIN_BROKE;
|
|
if( todo )
|
|
{
|
|
malloc_fatal(func);
|
|
}
|
|
rtn++;
|
|
break;
|
|
}
|
|
oldptr = ptr;
|
|
}
|
|
else
|
|
{
|
|
if( oldptr != malloc_end )
|
|
{
|
|
/*
|
|
* This should never happen. If it does, then
|
|
* we got a real problem.
|
|
*/
|
|
malloc_errno = M_CODE_NO_END;
|
|
if( todo )
|
|
{
|
|
malloc_fatal(func);
|
|
}
|
|
rtn++;
|
|
}
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* verify that ptr is within the malloc region...
|
|
* since we started within the malloc chain this should never
|
|
* happen.
|
|
*/
|
|
|
|
if( ((char *)ptr < malloc_data_start) ||
|
|
((char *)ptr > malloc_data_end) )
|
|
{
|
|
malloc_errno = M_CODE_BAD_PTR;
|
|
if( todo )
|
|
{
|
|
malloc_fatal(func);
|
|
}
|
|
rtn++;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* verify magic flag is set
|
|
*/
|
|
|
|
if( (ptr->flag&M_MAGIC) != M_MAGIC )
|
|
{
|
|
malloc_errno = M_CODE_BAD_MAGIC;
|
|
if( todo )
|
|
{
|
|
malloc_warning(func);
|
|
}
|
|
rtn++;
|
|
continue;
|
|
}
|
|
|
|
/*
|
|
* verify segments are correctly linked together
|
|
*/
|
|
|
|
if( (ptr->prev && (ptr->prev->next != ptr) ) ||
|
|
(ptr->next && (ptr->next->prev != ptr) ) ||
|
|
((ptr->next == NULL) && (ptr->prev == NULL)) )
|
|
{
|
|
malloc_errno = M_CODE_BAD_CONNECT;
|
|
if( todo )
|
|
{
|
|
malloc_warning(func);
|
|
}
|
|
rtn++;
|
|
continue;
|
|
}
|
|
|
|
/*
|
|
* If this segment is allocated
|
|
*/
|
|
|
|
if( (ptr->flag & M_INUSE) != 0 )
|
|
{
|
|
/*
|
|
* verify no overflow of data area
|
|
*/
|
|
|
|
for(i=ptr->r_size; i < ptr->s.size; i++)
|
|
{
|
|
if( ptr->data[i] != M_FILL )
|
|
{
|
|
malloc_errno = M_CODE_OVERRUN;
|
|
if( todo )
|
|
{
|
|
malloc_warning(func);
|
|
}
|
|
rtn++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else /* it's not allocated so */
|
|
{
|
|
/*
|
|
* verify no reuse of freed data blocks
|
|
*/
|
|
|
|
for(i=0; i < ptr->s.size; i++)
|
|
{
|
|
if( ptr->data[i] != M_FREE_FILL )
|
|
{
|
|
malloc_errno = M_CODE_REUSE;
|
|
if( todo )
|
|
{
|
|
malloc_warning(func);
|
|
}
|
|
rtn++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
} /* for(... */
|
|
|
|
return(rtn);
|
|
|
|
} /* malloc_chain_check(... */
|