1 /* 2 * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). 3 * You may copy, distribute, and use this software as long as this 4 * copyright statement is not removed. 5 */ 6 #include <stdio.h> 7 #include <fcntl.h> 8 #include "malloc.h" 9 10 /* 11 * Function: malloc_chain_check() 12 * 13 * Purpose: to verify malloc chain is intact 14 * 15 * Arguments: todo - 0 - just check and return status 16 * 1 - call malloc_warn if error detected 17 * 18 * Returns: 0 - malloc chain intact & no overflows 19 * other - problems detected in malloc chain 20 * 21 * Narrative: 22 * 23 * Notes: If todo is non-zero the malloc_warn function, when called 24 * may not return (i.e. it may exit) 25 * 26 */ 27 #ifndef lint 28 static 29 char rcs_hdr[] = "$Id: mlc_chn.c,v 1.1.1.1 2000-09-22 15:33:26 hr Exp $"; 30 #endif 31 32 33 int malloc_chain_check(todo)34malloc_chain_check(todo) 35 int todo; 36 { 37 char * func = "malloc_chain_check"; 38 int i; 39 extern char * malloc_data_start; 40 extern char * malloc_data_end; 41 extern struct mlist * malloc_end; 42 extern int malloc_errno; 43 extern struct mlist malloc_start; 44 struct mlist * oldptr; 45 struct mlist * ptr; 46 int rtn = 0; 47 48 oldptr = &malloc_start; 49 for(ptr = malloc_start.next; ; ptr = ptr->next) 50 { 51 /* 52 * Since the malloc chain is a forward only chain, any 53 * pointer that we get should always be positioned in 54 * memory following the previous pointer. If this is not 55 * so, we must have a corrupted chain. 56 */ 57 if( ptr ) 58 { 59 if(ptr < oldptr ) 60 { 61 malloc_errno = M_CODE_CHAIN_BROKE; 62 if( todo ) 63 { 64 malloc_fatal(func); 65 } 66 rtn++; 67 break; 68 } 69 oldptr = ptr; 70 } 71 else 72 { 73 if( oldptr != malloc_end ) 74 { 75 /* 76 * This should never happen. If it does, then 77 * we got a real problem. 78 */ 79 malloc_errno = M_CODE_NO_END; 80 if( todo ) 81 { 82 malloc_fatal(func); 83 } 84 rtn++; 85 } 86 break; 87 } 88 89 /* 90 * verify that ptr is within the malloc region... 91 * since we started within the malloc chain this should never 92 * happen. 93 */ 94 95 if( ((char *)ptr < malloc_data_start) || 96 ((char *)ptr > malloc_data_end) ) 97 { 98 malloc_errno = M_CODE_BAD_PTR; 99 if( todo ) 100 { 101 malloc_fatal(func); 102 } 103 rtn++; 104 break; 105 } 106 107 /* 108 * verify magic flag is set 109 */ 110 111 if( (ptr->flag&M_MAGIC) != M_MAGIC ) 112 { 113 malloc_errno = M_CODE_BAD_MAGIC; 114 if( todo ) 115 { 116 malloc_warning(func); 117 } 118 rtn++; 119 continue; 120 } 121 122 /* 123 * verify segments are correctly linked together 124 */ 125 126 if( (ptr->prev && (ptr->prev->next != ptr) ) || 127 (ptr->next && (ptr->next->prev != ptr) ) || 128 ((ptr->next == NULL) && (ptr->prev == NULL)) ) 129 { 130 malloc_errno = M_CODE_BAD_CONNECT; 131 if( todo ) 132 { 133 malloc_warning(func); 134 } 135 rtn++; 136 continue; 137 } 138 139 /* 140 * If this segment is allocated 141 */ 142 143 if( (ptr->flag & M_INUSE) != 0 ) 144 { 145 /* 146 * verify no overflow of data area 147 */ 148 149 for(i=ptr->r_size; i < ptr->s.size; i++) 150 { 151 if( ptr->data[i] != M_FILL ) 152 { 153 malloc_errno = M_CODE_OVERRUN; 154 if( todo ) 155 { 156 malloc_warning(func); 157 } 158 rtn++; 159 break; 160 } 161 } 162 } 163 else /* it's not allocated so */ 164 { 165 /* 166 * verify no reuse of freed data blocks 167 */ 168 169 for(i=0; i < ptr->s.size; i++) 170 { 171 if( ptr->data[i] != M_FREE_FILL ) 172 { 173 malloc_errno = M_CODE_REUSE; 174 if( todo ) 175 { 176 malloc_warning(func); 177 } 178 rtn++; 179 break; 180 } 181 } 182 } 183 184 } /* for(... */ 185 186 return(rtn); 187 188 } /* malloc_chain_check(... */ 189