diff -pruN a/malloc/arena.c b/malloc/arena.c --- a/malloc/arena.c 2014-01-07 07:07:47.000000000 +0530 +++ b/malloc/arena.c 2014-01-07 14:11:40.093628218 +0530 @@ -702,7 +702,7 @@ heap_trim (heap_info *heap, size_t pad) 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)); diff -pruN a/malloc/hooks.c b/malloc/hooks.c --- a/malloc/hooks.c 2014-01-07 07:07:47.000000000 +0530 +++ b/malloc/hooks.c 2014-01-07 14:12:41.804625603 +0530 @@ -237,7 +237,9 @@ top_check (void) (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); diff -pruN a/malloc/malloc.c b/malloc/malloc.c --- a/malloc/malloc.c 2014-01-07 07:07:47.000000000 +0530 +++ b/malloc/malloc.c 2014-01-07 14:29:53.370581893 +0530 @@ -1404,11 +1404,15 @@ 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)) \ - malloc_printerr (check_action, "corrupted double-linked list", P); \ + { \ + mutex_unlock(&(AV)->mutex); \ + malloc_printerr (check_action, "corrupted double-linked list", P); \ + mutex_lock(&(AV)->mutex); \ + } \ else { \ FD->bk = BK; \ BK->fd = FD; \ @@ -2524,7 +2528,9 @@ sysmalloc (INTERNAL_SIZE_T nb, mstate av 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); } /* @@ -3353,7 +3359,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; } check_remalloced_chunk (av, victim, nb); @@ -3441,8 +3449,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); /* @@ -3589,7 +3601,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) @@ -3694,7 +3706,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) @@ -3832,9 +3844,11 @@ _int_free (mstate av, mchunkptr p, int h { errstr = "free(): invalid pointer"; errout: - if (!have_lock && locked) + if (have_lock || locked) (void) mutex_unlock (&av->mutex); malloc_printerr (check_action, errstr, chunk2mem (p)); + if (have_lock) + mutex_lock(&av->mutex); return; } /* We know that each chunk is at least MINSIZE bytes in size or a @@ -3981,7 +3995,7 @@ _int_free (mstate av, mchunkptr p, int h 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) { @@ -3990,7 +4004,7 @@ _int_free (mstate av, mchunkptr p, int h /* consolidate forward */ if (!nextinuse) { - unlink(nextchunk, bck, fwd); + unlink(av, nextchunk, bck, fwd); size += nextsize; } else clear_inuse_bit_at_offset(nextchunk, 0); @@ -4151,7 +4165,7 @@ static void malloc_consolidate(mstate av 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) { @@ -4159,7 +4173,7 @@ static void malloc_consolidate(mstate av if (!nextinuse) { size += nextsize; - unlink(nextchunk, bck, fwd); + unlink(av, nextchunk, bck, fwd); } else clear_inuse_bit_at_offset(nextchunk, 0); @@ -4228,7 +4242,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; } @@ -4274,7 +4290,7 @@ _int_realloc(mstate av, mchunkptr oldp, (unsigned long) (nb)) { newp = oldp; - unlink (next, bck, fwd); + unlink (av, next, bck, fwd); } /* allocate, copy, free */