bool mwide_free_do(t_memarena *arenactl, t_memwide *widectl, void *addr) { uintptr_t wide_addr; if (widectl->cipher != MCHUNK_CIPHER(*widectl)) malloc_fatal("free(): memory corruption (wide) at %p", widectl, true); wide_addr = (uintptr_t) widectl + sizeof(*widectl); if (wide_addr == (uintptr_t) addr) { if (wide_addr % MALLOC_ALIGNMENT != 0) malloc_fatal("free(): invalid pointer %p (wide)", addr, true); pthread_mutex_lock(&arenactl->mutex); widectl->used = false; widectl->cipher = MCHUNK_CIPHER(*widectl); arenactl->next_fit = mwide_join(widectl); pthread_mutex_unlock(&arenactl->mutex); return (true); } return (false); }
/* * 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; }
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; }