projects
/
kopensolaris-gnu
/
glibc.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Replace lll_private_futex_* (*) with lll_futex_* (*, LLL_PRIVATE).
[kopensolaris-gnu/glibc.git]
/
malloc
/
hooks.c
diff --git
a/malloc/hooks.c
b/malloc/hooks.c
index
cf6642c
..
1e01b73
100644
(file)
--- a/
malloc/hooks.c
+++ b/
malloc/hooks.c
@@
-1,5
+1,5
@@
/* Malloc implementation for multiple threads without lock contention.
/* Malloc implementation for multiple threads without lock contention.
- Copyright (C) 2001
, 2002, 2003
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 <wg@malloc.de>, 2001.
This file is part of the GNU C Library.
Contributed by Wolfram Gloger <wg@malloc.de>, 2001.
@@
-18,12
+18,6
@@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
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). */
/* 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);
}
return public_mEMALIGn(alignment, sz);
}
-
-static int check_action = DEFAULT_CHECK_ACTION;
-
/* Whether we are using malloc checking. */
static int using_malloc_checking;
/* 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)
__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
}
/* A simple, standard set of debugging hooks. Overhead is `only' one
@@
-153,9
+144,9
@@
mem2mem_check(ptr, sz) Void_t *ptr; size_t sz;
static mchunkptr
internal_function
#if __STD_C
static mchunkptr
internal_function
#if __STD_C
-mem2chunk_check(Void_t* mem)
+mem2chunk_check(Void_t* mem
, unsigned char **magic_p
)
#else
#else
-mem2chunk_check(mem
) Void_t* mem
;
+mem2chunk_check(mem
, magic_p) Void_t* mem; unsigned char **magic_p
;
#endif
{
mchunkptr p;
#endif
{
mchunkptr p;
@@
-164,22
+155,22
@@
mem2chunk_check(mem) Void_t* mem;
if(!aligned_OK(mem)) return NULL;
p = mem2chunk(mem);
if(!aligned_OK(mem)) return NULL;
p = mem2chunk(mem);
- 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. */
/* 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 ||
+ ((char*)p + sz)>=(mp_.sbrk_base+main_arena.system_mem) )) ||
sz<MINSIZE || sz&MALLOC_ALIGN_MASK || !inuse(p) ||
( !prev_inuse(p) && (p->prev_size&MALLOC_ALIGN_MASK ||
sz<MINSIZE || sz&MALLOC_ALIGN_MASK || !inuse(p) ||
( !prev_inuse(p) && (p->prev_size&MALLOC_ALIGN_MASK ||
- (
long)prev_chunk(p)<(long)mp_.sbrk_base
||
+ (
contig && (char*)prev_chunk(p)<mp_.sbrk_base)
||
next_chunk(prev_chunk(p))!=p) ))
return NULL;
magic = MAGICBYTE(p);
for(sz += SIZE_SZ-1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
}
next_chunk(prev_chunk(p))!=p) ))
return NULL;
magic = MAGICBYTE(p);
for(sz += SIZE_SZ-1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
}
- ((unsigned char*)p)[sz] ^= 0xFF;
} else {
unsigned long offset, page_mask = malloc_getpagesize-1;
} else {
unsigned long offset, page_mask = malloc_getpagesize-1;
@@
-199,8
+190,10
@@
mem2chunk_check(mem) Void_t* mem;
for(sz -= 1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
}
for(sz -= 1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
}
- ((unsigned char*)p)[sz] ^= 0xFF;
}
}
+ ((unsigned char*)p)[sz] ^= 0xFF;
+ if (magic_p)
+ *magic_p = (unsigned char *)p + sz;
return p;
}
return p;
}
@@
-220,13
+213,15
@@
top_check()
INTERNAL_SIZE_T front_misalign, sbrk_size;
unsigned long pagesz = malloc_getpagesize;
INTERNAL_SIZE_T front_misalign, sbrk_size;
unsigned long pagesz = malloc_getpagesize;
- if((char*)t + chunksize(t) == mp_.sbrk_base + main_arena.system_mem ||
- t == initial_top(&main_arena)) return 0;
+ if (t == initial_top(&main_arena) ||
+ (!chunk_is_mmapped(t) &&
+ chunksize(t)>=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);
/* 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));
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) ();
/* 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;
{
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);
(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);
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(!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
return;
}
#if HAVE_MMAP
@@
-308,16
+310,22
@@
realloc_check(oldmem, bytes, caller)
mchunkptr oldp;
INTERNAL_SIZE_T nb, oldsize;
Void_t* newmem = 0;
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 (oldmem == 0) return malloc_check(bytes, NULL);
+ if (bytes == 0) {
+ free_check (oldmem, NULL);
+ return NULL;
+ }
(void)mutex_lock(&main_arena.mutex);
(void)mutex_lock(&main_arena.mutex);
- oldp = mem2chunk_check(oldmem);
+ oldp = mem2chunk_check(oldmem
, &magic_p
);
(void)mutex_unlock(&main_arena.mutex);
if(!oldp) {
(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);
return malloc_check(bytes, NULL);
}
oldsize = chunksize(oldp);
@@
-366,6
+374,12
@@
realloc_check(oldmem, bytes, caller)
#if HAVE_MMAP
}
#endif
#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);
(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 (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) :
checked_request2size(bytes+1, nb);
(void)mutex_lock(&main_arena.mutex);
mem = (top_check() >= 0) ? _int_memalign(&main_arena, alignment, bytes+1) :
@@
-396,7
+414,7
@@
memalign_check(alignment, bytes, caller)
#ifndef NO_THREADS
# ifdef _LIBC
#ifndef NO_THREADS
# ifdef _LIBC
-# if USE___THREAD ||
(defined USE_TLS && !defined SHARED)
+# if USE___THREAD ||
!defined SHARED
/* These routines are never needed in this configuration. */
# define NO_STARTER
# endif
/* These routines are never needed in this configuration. */
# define NO_STARTER
# endif
@@
-478,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
then the hooks are reset to 0. */
#define MALLOC_STATE_MAGIC 0x444c4541l
-#define MALLOC_STATE_VERSION (0*0x100l +
2
l) /* major*0x100 + minor */
+#define MALLOC_STATE_VERSION (0*0x100l +
3
l) /* major*0x100 + minor */
struct malloc_save_state {
long magic;
struct malloc_save_state {
long magic;
@@
-564,7
+582,7
@@
public_sET_STATe(Void_t* msptr)
(void)mutex_lock(&main_arena.mutex);
/* There are no fastchunks. */
clear_fastchunks(&main_arena);
(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; i<NFASTBINS; ++i)
main_arena.fastbins[i] = 0;
for (i=0; i<BINMAPSIZE; ++i)
for (i=0; i<NFASTBINS; ++i)
main_arena.fastbins[i] = 0;
for (i=0; i<BINMAPSIZE; ++i)
@@
-577,8
+595,9
@@
public_sET_STATe(Void_t* msptr)
assert(ms->av[2*i+3] == 0);
first(b) = last(b) = b;
} else {
assert(ms->av[2*i+3] == 0);
first(b) = last(b) = b;
} else {
- if(i<NSMALLBINS || (largebin_index(chunksize(ms->av[2*i+2]))==i &&
- largebin_index(chunksize(ms->av[2*i+3]))==i)) {
+ if(ms->version >= 3 &&
+ (i<NSMALLBINS || (largebin_index(chunksize(ms->av[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. */
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. */
@@
-598,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;
mp_.sbrk_base = ms->sbrk_base;
main_arena.system_mem = ms->sbrked_mem_bytes;
mp_.trim_threshold = ms->trim_threshold;