Index: glibc-2.12-2-gc4ccff1/malloc/arena.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/malloc/arena.c
+++ glibc-2.12-2-gc4ccff1/malloc/arena.c
@@ -870,7 +870,7 @@ heap_trim(heap, pad) heap_info *heap; si
heap = prev_heap;
if(!prev_inuse(p)) { /* consolidate backward */
p = prev_chunk(p);
- unlink(p, bck, fwd);
+ unlink(ar_ptr, p, bck, fwd);
}
assert(((unsigned long)((char*)p + new_size) & (pagesz-1)) == 0);
assert( ((char*)p + new_size) == ((char*)heap + heap->size) );
Index: glibc-2.12-2-gc4ccff1/malloc/hooks.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/malloc/hooks.c
+++ glibc-2.12-2-gc4ccff1/malloc/hooks.c
@@ -219,7 +219,9 @@ top_check()
(char*)t + chunksize(t) == mp_.sbrk_base + main_arena.system_mem)))
return 0;
+ mutex_unlock(&main_arena);
malloc_printerr (check_action, "malloc: top chunk is corrupt", t);
+ mutex_lock(&main_arena);
/* Try to set up a new top chunk. */
brk = MORECORE(0);
Index: glibc-2.12-2-gc4ccff1/malloc/malloc.c
===================================================================
--- glibc-2.12-2-gc4ccff1.orig/malloc/malloc.c
+++ glibc-2.12-2-gc4ccff1/malloc/malloc.c
@@ -2109,12 +2109,14 @@ typedef struct malloc_chunk* mbinptr;
#define last(b) ((b)->bk)
/* Take a chunk off a bin list */
-#define unlink(P, BK, FD) { \
+#define unlink(AV, P, BK, FD) { \
FD = P->fd; \
BK = P->bk; \
- if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \
+ if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) { \
+ mutex_unlock(&(AV)->mutex); \
malloc_printerr (check_action, "corrupted double-linked list", P); \
- else { \
+ mutex_lock(&(AV)->mutex); \
+ } else { \
FD->bk = BK; \
BK->fd = FD; \
if (!in_smallbin_range (P->size) \
@@ -3257,7 +3259,9 @@ static Void_t* sYSMALLOc(nb, av) INTERNA
else if (contiguous(av) && old_size && brk < old_end) {
/* Oops! Someone else killed our space.. Can't touch anything. */
+ mutex_unlock(&av->mutex);
malloc_printerr (3, "break adjusted to free malloc space", brk);
+ mutex_lock(&av->mutex);
}
/*
@@ -4305,7 +4309,9 @@ _int_malloc(mstate av, size_t bytes)
{
errstr = "malloc(): memory corruption (fast)";
errout:
+ mutex_unlock(&av->mutex);
malloc_printerr (check_action, errstr, chunk2mem (victim));
+ mutex_lock(&av->mutex);
return NULL;
}
#ifndef ATOMIC_FASTBINS
@@ -4393,8 +4399,12 @@ _int_malloc(mstate av, size_t bytes)
bck = victim->bk;
if (__builtin_expect (victim->size <= 2 * SIZE_SZ, 0)
|| __builtin_expect (victim->size > av->system_mem, 0))
- malloc_printerr (check_action, "malloc(): memory corruption",
- chunk2mem (victim));
+ {
+ void *p = chunk2mem(victim);
+ mutex_unlock(&av->mutex);
+ malloc_printerr (check_action, "malloc(): memory corruption", p);
+ mutex_lock(&av->mutex);
+ }
size = chunksize(victim);
/*
@@ -4535,7 +4545,7 @@ _int_malloc(mstate av, size_t bytes)
victim = victim->fd;
remainder_size = size - nb;
- unlink(victim, bck, fwd);
+ unlink(av, victim, bck, fwd);
/* Exhaust */
if (remainder_size < MINSIZE) {
@@ -4633,7 +4643,7 @@ _int_malloc(mstate av, size_t bytes)
remainder_size = size - nb;
/* unlink */
- unlink(victim, bck, fwd);
+ unlink(av, victim, bck, fwd);
/* Exhaust */
if (remainder_size < MINSIZE) {
@@ -4789,10 +4799,14 @@ _int_free(mstate av, mchunkptr p)
errstr = "free(): invalid pointer";
errout:
#ifdef ATOMIC_FASTBINS
- if (! have_lock && locked)
+ if (have_lock || locked)
(void)mutex_unlock(&av->mutex);
#endif
malloc_printerr (check_action, errstr, chunk2mem(p));
+#ifdef ATOMIC_FASTBINS
+ if (have_lock)
+ mutex_lock(&av->mutex);
+#endif
return;
}
/* We know that each chunk is at least MINSIZE bytes in size. */
@@ -4961,7 +4975,7 @@ _int_free(mstate av, mchunkptr p)
prevsize = p->prev_size;
size += prevsize;
p = chunk_at_offset(p, -((long) prevsize));
- unlink(p, bck, fwd);
+ unlink(av, p, bck, fwd);
}
if (nextchunk != av->top) {
@@ -4970,7 +4984,7 @@ _int_free(mstate av, mchunkptr p)
/* consolidate forward */
if (!nextinuse) {
- unlink(nextchunk, bck, fwd);
+ unlink(av, nextchunk, bck, fwd);
size += nextsize;
} else
clear_inuse_bit_at_offset(nextchunk, 0);
@@ -5158,7 +5172,7 @@ static void malloc_consolidate(av) mstat
prevsize = p->prev_size;
size += prevsize;
p = chunk_at_offset(p, -((long) prevsize));
- unlink(p, bck, fwd);
+ unlink(av, p, bck, fwd);
}
if (nextchunk != av->top) {
@@ -5166,7 +5180,7 @@ static void malloc_consolidate(av) mstat
if (!nextinuse) {
size += nextsize;
- unlink(nextchunk, bck, fwd);
+ unlink(av, nextchunk, bck, fwd);
} else
clear_inuse_bit_at_offset(nextchunk, 0);
@@ -5235,7 +5249,9 @@ _int_realloc(mstate av, mchunkptr oldp,
{
errstr = "realloc(): invalid old size";
errout:
+ mutex_unlock(&av->mutex);
malloc_printerr (check_action, errstr, chunk2mem(oldp));
+ mutex_lock(&av->mutex);
return NULL;
}
@@ -5282,7 +5298,7 @@ _int_realloc(mstate av, mchunkptr oldp,
(unsigned long)(newsize = oldsize + nextsize) >=
(unsigned long)(nb)) {
newp = oldp;
- unlink(next, bck, fwd);
+ unlink(av, next, bck, fwd);
}
/* allocate, copy, free */