X-Git-Url: http://git.csclub.uwaterloo.ca/?p=kopensolaris-gnu%2Fglibc.git;a=blobdiff_plain;f=malloc%2Fhooks.c;h=1e01b73afde89be6edf35e18182c5f31149e9da7;hp=7643e367149776a516848b9ad6a9208f659c5fc2;hb=4b69b20a6f55e974e80e2eff97f0c79257673d5e;hpb=b2ba94647d5b2af10fc4027982dda068ce5621b6 diff --git a/malloc/hooks.c b/malloc/hooks.c index 7643e36714..1e01b73afd 100644 --- a/malloc/hooks.c +++ b/malloc/hooks.c @@ -1,5 +1,5 @@ /* Malloc implementation for multiple threads without lock contention. - Copyright (C) 2001,02 Free Software Foundation, Inc. + Copyright (C) 2001-2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Wolfram Gloger , 2001. @@ -18,12 +18,6 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id$ */ - -#ifndef DEFAULT_CHECK_ACTION -#define DEFAULT_CHECK_ACTION 1 -#endif - /* What to do if the standard debugging hooks are in place and a corrupt pointer is detected: do nothing (0), print an error message (1), or call abort() (2). */ @@ -71,9 +65,6 @@ memalign_hook_ini(alignment, sz, caller) return public_mEMALIGn(alignment, sz); } - -static int check_action = DEFAULT_CHECK_ACTION; - /* Whether we are using malloc checking. */ static int using_malloc_checking; @@ -106,7 +97,7 @@ __malloc_check_init() __realloc_hook = realloc_check; __memalign_hook = memalign_check; if(check_action & 1) - fprintf(stderr, "malloc: using debugging hooks\n"); + malloc_printerr (5, "malloc: using debugging hooks", NULL); } /* A simple, standard set of debugging hooks. Overhead is `only' one @@ -153,33 +144,33 @@ mem2mem_check(ptr, sz) Void_t *ptr; size_t sz; static mchunkptr internal_function #if __STD_C -mem2chunk_check(Void_t* mem) +mem2chunk_check(Void_t* mem, unsigned char **magic_p) #else -mem2chunk_check(mem) Void_t* mem; +mem2chunk_check(mem, magic_p) Void_t* mem; unsigned char **magic_p; #endif { mchunkptr p; INTERNAL_SIZE_T sz, c; unsigned char magic; + if(!aligned_OK(mem)) return NULL; p = mem2chunk(mem); - if(!aligned_OK(p)) return NULL; - if( (char*)p>=mp_.sbrk_base && - (char*)p<(mp_.sbrk_base+main_arena.system_mem) ) { + if (!chunk_is_mmapped(p)) { /* Must be a chunk in conventional heap memory. */ - if(chunk_is_mmapped(p) || - ( (sz = chunksize(p)), - ((char*)p + sz)>=(mp_.sbrk_base+main_arena.system_mem) ) || + int contig = contiguous(&main_arena); + sz = chunksize(p); + if((contig && + ((char*)p=(mp_.sbrk_base+main_arena.system_mem) )) || szprev_size&MALLOC_ALIGN_MASK || - (long)prev_chunk(p)<(long)mp_.sbrk_base || + (contig && (char*)prev_chunk(p)=MINSIZE && + prev_inuse(t) && + (!contiguous(&main_arena) || + (char*)t + chunksize(t) == mp_.sbrk_base + main_arena.system_mem))) + return 0; - if(check_action & 1) - fprintf(stderr, "malloc: top chunk is corrupt\n"); - if(check_action & 2) - abort(); + malloc_printerr (check_action, "malloc: top chunk is corrupt", t); /* Try to set up a new top chunk. */ brk = MORECORE(0); @@ -236,7 +231,11 @@ top_check() sbrk_size = front_misalign + mp_.top_pad + MINSIZE; sbrk_size += pagesz - ((unsigned long)(brk + sbrk_size) & (pagesz - 1)); new_brk = (char*)(MORECORE (sbrk_size)); - if (new_brk == (char*)(MORECORE_FAILURE)) return -1; + if (new_brk == (char*)(MORECORE_FAILURE)) + { + MALLOC_FAILURE_ACTION; + return -1; + } /* Call the `morecore' hook if necessary. */ if (__after_morecore_hook) (*__after_morecore_hook) (); @@ -257,6 +256,11 @@ malloc_check(sz, caller) size_t sz; const Void_t *caller; { Void_t *victim; + if (sz+1 == 0) { + MALLOC_FAILURE_ACTION; + return NULL; + } + (void)mutex_lock(&main_arena.mutex); victim = (top_check() >= 0) ? _int_malloc(&main_arena, sz+1) : NULL; (void)mutex_unlock(&main_arena.mutex); @@ -274,13 +278,11 @@ free_check(mem, caller) Void_t* mem; const Void_t *caller; if(!mem) return; (void)mutex_lock(&main_arena.mutex); - p = mem2chunk_check(mem); + p = mem2chunk_check(mem, NULL); if(!p) { (void)mutex_unlock(&main_arena.mutex); - if(check_action & 1) - fprintf(stderr, "free(): invalid pointer %p!\n", mem); - if(check_action & 2) - abort(); + + malloc_printerr(check_action, "free(): invalid pointer", mem); return; } #if HAVE_MMAP @@ -308,16 +310,22 @@ realloc_check(oldmem, bytes, caller) mchunkptr oldp; INTERNAL_SIZE_T nb, oldsize; Void_t* newmem = 0; + unsigned char *magic_p; + if (bytes+1 == 0) { + MALLOC_FAILURE_ACTION; + return NULL; + } if (oldmem == 0) return malloc_check(bytes, NULL); + if (bytes == 0) { + free_check (oldmem, NULL); + return NULL; + } (void)mutex_lock(&main_arena.mutex); - oldp = mem2chunk_check(oldmem); + oldp = mem2chunk_check(oldmem, &magic_p); (void)mutex_unlock(&main_arena.mutex); if(!oldp) { - if(check_action & 1) - fprintf(stderr, "realloc(): invalid pointer %p!\n", oldmem); - if(check_action & 2) - abort(); + malloc_printerr(check_action, "realloc(): invalid pointer", oldmem); return malloc_check(bytes, NULL); } oldsize = chunksize(oldp); @@ -366,6 +374,12 @@ realloc_check(oldmem, bytes, caller) #if HAVE_MMAP } #endif + + /* mem2chunk_check changed the magic byte in the old chunk. + If newmem is NULL, then the old chunk will still be used though, + so we need to invert that change here. */ + if (newmem == NULL) *magic_p ^= 0xFF; + (void)mutex_unlock(&main_arena.mutex); return mem2mem_check(newmem, bytes); @@ -385,6 +399,10 @@ memalign_check(alignment, bytes, caller) if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes, NULL); if (alignment < MINSIZE) alignment = MINSIZE; + if (bytes+1 == 0) { + MALLOC_FAILURE_ACTION; + return NULL; + } checked_request2size(bytes+1, nb); (void)mutex_lock(&main_arena.mutex); mem = (top_check() >= 0) ? _int_memalign(&main_arena, alignment, bytes+1) : @@ -395,6 +413,17 @@ memalign_check(alignment, bytes, caller) #ifndef NO_THREADS +# ifdef _LIBC +# if USE___THREAD || !defined SHARED + /* These routines are never needed in this configuration. */ +# define NO_STARTER +# endif +# endif + +# ifdef NO_STARTER +# undef NO_STARTER +# else + /* The following hooks are used when the global initialization in ptmalloc_init() hasn't completed yet. */ @@ -412,6 +441,20 @@ malloc_starter(sz, caller) size_t sz; const Void_t *caller; return victim ? BOUNDED_N(victim, sz) : 0; } +static Void_t* +#if __STD_C +memalign_starter(size_t align, size_t sz, const Void_t *caller) +#else +memalign_starter(align, sz, caller) size_t align, sz; const Void_t *caller; +#endif +{ + Void_t* victim; + + victim = _int_memalign(&main_arena, align, sz); + + return victim ? BOUNDED_N(victim, sz) : 0; +} + static void #if __STD_C free_starter(Void_t* mem, const Void_t *caller) @@ -432,6 +475,7 @@ free_starter(mem, caller) Void_t* mem; const Void_t *caller; _int_free(&main_arena, mem); } +# endif /* !defiend NO_STARTER */ #endif /* NO_THREADS */ @@ -452,7 +496,7 @@ free_starter(mem, caller) Void_t* mem; const Void_t *caller; then the hooks are reset to 0. */ #define MALLOC_STATE_MAGIC 0x444c4541l -#define MALLOC_STATE_VERSION (0*0x100l + 2l) /* major*0x100 + minor */ +#define MALLOC_STATE_VERSION (0*0x100l + 3l) /* major*0x100 + minor */ struct malloc_save_state { long magic; @@ -538,7 +582,7 @@ public_sET_STATe(Void_t* msptr) (void)mutex_lock(&main_arena.mutex); /* There are no fastchunks. */ clear_fastchunks(&main_arena); - set_max_fast(&main_arena, DEFAULT_MXFAST); + set_max_fast(DEFAULT_MXFAST); for (i=0; iav[2*i+3] == 0); first(b) = last(b) = b; } else { - if(iav[2*i+2]))==i && - largebin_index(chunksize(ms->av[2*i+3]))==i)) { + if(ms->version >= 3 && + (iav[2*i+2]))==i && + largebin_index(chunksize(ms->av[2*i+3]))==i))) { first(b) = ms->av[2*i+2]; last(b) = ms->av[2*i+3]; /* Make sure the links to the bins within the heap are correct. */ @@ -572,6 +617,17 @@ public_sET_STATe(Void_t* msptr) } } } + if (ms->version < 3) { + /* Clear fd_nextsize and bk_nextsize fields. */ + b = unsorted_chunks(&main_arena)->fd; + while (b != unsorted_chunks(&main_arena)) { + if (!in_smallbin_range(chunksize(b))) { + b->fd_nextsize = NULL; + b->bk_nextsize = NULL; + } + b = b->fd; + } + } mp_.sbrk_base = ms->sbrk_base; main_arena.system_mem = ms->sbrked_mem_bytes; mp_.trim_threshold = ms->trim_threshold;