static int find_marked_nodes_helper(const char *func, const char *file, int line, int todo, arena_range_t *rp) { Flink *oldptr; Flink *ptr; DebugInfo_t *mptr; chain_t *chain = rp->r_type == RANGE_ARENA ? &rp->un.r_arena->a_malloc_chain : &rp->un.r_block->malloc_chain; oldptr = (Flink *)_malloc_start; for(ptr = chain->head; ; oldptr = ptr, ptr = ptr->f_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 0 if((ulong_t)ptr < (ulong_t)oldptr) { malloc_errno = M_CODE_CHAIN_BROKE; if( todo ) { malloc_fatal(func,file,line,oldptr); } break; } #endif } else { if( chain->tail && (oldptr != chain->tail) ) { /* * This should never happen. If it does, then * we got a real problem. */ malloc_errno = M_CODE_NO_END; if( todo ) { malloc_fatal(func,file,line,oldptr); } } break; } /* * verify that ptr is within the malloc region... * since we started within the malloc chain this should never * happen. */ if( ((ulong_t)ptr < (ulong_t)rp->r_start) || ((ulong_t)ptr > (ulong_t)rp->r_end) ) { malloc_errno = M_CODE_BAD_PTR; if( todo ) { malloc_fatal(func,file,line,oldptr); } break; } mptr = &((Dhead *)ptr)->d_debug; /* * verify magic flag is set */ if (!MAGIC_MATCH(mptr)) { malloc_errno = M_CODE_BAD_MAGIC; if( todo ) { malloc_warning(func,file,line, NULL); } continue; } /* * verify segments are correctly linked together */ if( (ptr->f_prev && (ptr->f_prev->f_next != ptr) ) || (ptr->f_next && (ptr->f_next->f_prev != ptr) ) ) { malloc_errno = M_CODE_BAD_CONNECT; if( todo ) { malloc_warning(func,file,line,ptr); } continue; } /* * If this segment is allocated */ if( (mptr->flag & M_INUSE) != 0 ) { char *data = (char *)((Dhead *)ptr + 1); ulong_t start = (ulong_t)data; ulong_t end = (ulong_t)(data + DH_ULEN(ptr)); Block *bp = (Block *)data; /* * If this segment is a Block, skip it */ if (bp->magic == BLOCK_MAGIC) continue; if ( (mptr->flag & M_REFERENCED) != 0) { /* it's marked */ ulong_t child = start; Dhead *dh; arena_range_t range; /* * scan through the block on dword-aligned * boundaries looking for unmarked children */ do { if ((child = find_child((ulong_t)child, (ulong_t)end, &dh, &range)) != NULL) { child += 4; if ((dh->d_debug.flag & M_REFERENCED) == 0) { /* if we found an unmarked child, add the parent to * the mark stack. */ _mark_stack_push(start, end); break; } } } while (child != 0); } } } /* for(... */ return 0; }
/* * Must be called with the mutex locked! */ static int DBFmalloc_chain_check_helper(const char *func,const char *file,int line, int todo, arena_range_t *rp, int *cont) { void * oldptr; Flink * ptr; DebugInfo_t * mptr; chain_t * chain = rp->r_type == RANGE_ARENA ? &rp->un.r_arena->a_malloc_chain : &rp->un.r_block->malloc_chain; int rtn = 0; oldptr = NULL; for(ptr = chain->head; ptr; oldptr = ptr, ptr = ptr->f_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 0 if((ulong_t)ptr < (ulong_t)oldptr ) { malloc_errno = M_CODE_CHAIN_BROKE; if( todo ) { malloc_fatal(func,file,line,oldptr); } rtn++; *cont = 0; break; } #endif } else { if( chain->tail && (oldptr != chain->tail) ) { /* * This should never happen. If it does, then * we got a real problem. */ malloc_errno = M_CODE_NO_END; if( todo ) { malloc_fatal(func,file,line,oldptr); } rtn++; } *cont = 0; break; } /* * verify that ptr is within the malloc region... * since we started within the malloc chain this should never * happen. */ if( ((ulong_t)ptr < (ulong_t)rp->r_start) || ((ulong_t)ptr > (ulong_t)rp->r_end) ) { malloc_errno = M_CODE_BAD_PTR; if( todo ) { malloc_fatal(func,file,line,oldptr); } rtn++; *cont = 0; break; } mptr = &((Dhead *)ptr)->d_debug; /* * verify magic flag is set */ if( ((Dhead *)ptr)->d_crc != LinkCRC(ptr)) { malloc_errno = M_CODE_BAD_CRC; malloc_warning(func,file,line,(void *)ptr); rtn++; continue; } if (!MAGIC_MATCH(mptr)) { malloc_errno = M_CODE_BAD_MAGIC; if( todo ) { malloc_warning(func,file,line, NULL); } rtn++; continue; } /* * verify segments are correctly linked together */ if( (ptr->f_prev && ptr->f_prev->f_next != ptr) || (ptr->f_next && ptr->f_next->f_prev != ptr) ) { malloc_errno = M_CODE_BAD_CONNECT; if( todo ) { malloc_warning(func,file,line,ptr); } rtn++; continue; } /* * If this segment is allocated */ if( (mptr->flag & M_INUSE) != 0 ) { /* * verify no overflow of data area */ // FIX: if (_malloc_fill_area && _malloc_fill_area < mptr->hist_id) { if (todo) { if (malloc_check_fill(func,file,line,(Dhead *)ptr) != 0) { rtn++; *cont = 0; break; } } } } } /* for(... */ return rtn; }
SIZETYPE DBmalloc_size( CONST char * file, int line, CONST DATATYPE * cptr ) { char *func = "malloc_size"; register struct mlist *ptr; // initialize the malloc sub-system. MALLOC_INIT(); #ifdef MALLOC_PTHREAD if ( !malloc_preamble ) pthread_mutex_lock( &malloc_mutex ); #endif // IF malloc chain checking is on, go do it. if (malloc_opts & MOPT_CKCHAIN) { VOIDCAST DBFmalloc_chain_check(func, file, line, 1); } // // verify that cptr is within the malloc region and that it is on // the correct alignment // if ( (cptr < malloc_data_start) || (cptr > malloc_data_end) || ((((long) cptr) & malloc_round) != 0)) { malloc_errno = M_CODE_BAD_PTR; malloc_warning(func, file, line, (struct mlist *) NULL); #ifdef MALLOC_PTHREAD if ( !malloc_preamble ) pthread_mutex_unlock( &malloc_mutex ); #endif return( (SIZETYPE) -1 ); } // // convert pointer to mlist struct pointer. To do this we must // move the pointer backwards the correct number of bytes... // ptr = DATATOMLIST(cptr); // check the magic number if ((ptr->flag & M_MAGIC_BITS) != M_MAGIC) { malloc_errno = M_CODE_BAD_MAGIC; malloc_warning(func, file, line, (struct mlist *) NULL); #ifdef MALLOC_PTHREAD if ( !malloc_preamble ) pthread_mutex_unlock( &malloc_mutex ); #endif return( (SIZETYPE) -1 ); } // if this segment is not flagged as being in use if (!(ptr->flag & M_INUSE)) { malloc_errno = M_CODE_NOT_INUSE; malloc_warning(func, file, line, ptr); #ifdef MALLOC_PTHREAD if ( !malloc_preamble ) pthread_mutex_unlock( &malloc_mutex ); #endif return( (SIZETYPE) -1 ); } // check to see that the pointers are still connected 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; malloc_warning(func, file, line, ptr); #ifdef MALLOC_PTHREAD if ( !malloc_preamble ) pthread_mutex_unlock( &malloc_mutex ); #endif return( (SIZETYPE) -1 ); } // check fill regions for overflow VOIDCAST FILLCHECK(func, file, line, ptr, SHOWERRORS); #ifdef MALLOC_PTHREAD if ( !malloc_preamble ) pthread_mutex_unlock( &malloc_mutex ); #endif return( ptr->r_size ); } // end of DBmalloc_size(...)