12745e
diff -Nru glibc-2.17-c758a686/malloc/arena.c glibc-2.17-c758a686/malloc/arena.c
12745e
--- glibc-2.17-c758a686/malloc/arena.c	2012-05-29 16:45:53.000000000 -0600
12745e
+++ glibc-2.17-c758a686/malloc/arena.c	2012-05-30 00:13:40.683514016 -0600
29e444
@@ -673,7 +673,7 @@ heap_trim(heap_info *heap, size_t pad)
29e444
     heap = prev_heap;
29e444
     if(!prev_inuse(p)) { /* consolidate backward */
29e444
       p = prev_chunk(p);
29e444
-      unlink(p, bck, fwd);
29e444
+      unlink(ar_ptr, p, bck, fwd);
29e444
     }
29e444
     assert(((unsigned long)((char*)p + new_size) & (pagesz-1)) == 0);
29e444
     assert( ((char*)p + new_size) == ((char*)heap + heap->size) );
12745e
diff -Nru glibc-2.17-c758a686/malloc/hooks.c glibc-2.17-c758a686/malloc/hooks.c
12745e
--- glibc-2.17-c758a686/malloc/hooks.c	2012-05-29 16:45:53.000000000 -0600
12745e
+++ glibc-2.17-c758a686/malloc/hooks.c	2012-05-30 00:13:40.684514011 -0600
29e444
@@ -191,7 +191,9 @@ top_check(void)
29e444
 	(char*)t + chunksize(t) == mp_.sbrk_base + main_arena.system_mem)))
29e444
     return 0;
29e444
 
29e444
+  mutex_unlock(&main_arena);
29e444
   malloc_printerr (check_action, "malloc: top chunk is corrupt", t);
29e444
+  mutex_lock(&main_arena);
29e444
 
29e444
   /* Try to set up a new top chunk. */
29e444
   brk = MORECORE(0);
12745e
diff -Nru glibc-2.17-c758a686/malloc/malloc.c glibc-2.17-c758a686/malloc/malloc.c
12745e
--- glibc-2.17-c758a686/malloc/malloc.c	2012-05-29 16:45:53.000000000 -0600
12745e
+++ glibc-2.17-c758a686/malloc/malloc.c	2012-05-30 00:13:40.686514001 -0600
29e444
@@ -1424,12 +1424,14 @@ typedef struct malloc_chunk* mbinptr;
29e444
 #define last(b)      ((b)->bk)
29e444
 
29e444
 /* Take a chunk off a bin list */
29e444
-#define unlink(P, BK, FD) {                                            \
29e444
+#define unlink(AV, P, BK, FD) {					       \
29e444
   FD = P->fd;                                                          \
29e444
   BK = P->bk;                                                          \
29e444
-  if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                \
29e444
+  if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) {	       \
29e444
+    mutex_unlock(&(AV)->mutex);					       \
29e444
     malloc_printerr (check_action, "corrupted double-linked list", P); \
29e444
-  else {                                                               \
29e444
+    mutex_lock(&(AV)->mutex);					       \
29e444
+  } else {							       \
29e444
     FD->bk = BK;                                                       \
29e444
     BK->fd = FD;                                                       \
29e444
     if (!in_smallbin_range (P->size)				       \
29e444
@@ -2511,7 +2513,9 @@ static void* sysmalloc(INTERNAL_SIZE_T n
29e444
 
29e444
     else if (contiguous(av) && old_size && brk < old_end) {
29e444
       /* Oops!  Someone else killed our space..  Can't touch anything.  */
29e444
+      mutex_unlock(&av->mutex);
29e444
       malloc_printerr (3, "break adjusted to free malloc space", brk);
29e444
+      mutex_lock(&av->mutex);
29e444
     }
29e444
 
29e444
     /*
29e444
@@ -3345,7 +3349,9 @@ _int_malloc(mstate av, size_t bytes)
29e444
 	{
29e444
 	  errstr = "malloc(): memory corruption (fast)";
29e444
 	errout:
29e444
+	  mutex_unlock(&av->mutex);
29e444
 	  malloc_printerr (check_action, errstr, chunk2mem (victim));
29e444
+	  mutex_lock(&av->mutex);
29e444
 	  return NULL;
29e444
 	}
29e444
       check_remalloced_chunk(av, victim, nb);
29e444
@@ -3430,8 +3436,12 @@ _int_malloc(mstate av, size_t bytes)
29e444
       bck = victim->bk;
29e444
       if (__builtin_expect (victim->size <= 2 * SIZE_SZ, 0)
29e444
 	  || __builtin_expect (victim->size > av->system_mem, 0))
29e444
-	malloc_printerr (check_action, "malloc(): memory corruption",
29e444
-			 chunk2mem (victim));
29e444
+	{
29e444
+	  void *p = chunk2mem(victim);
29e444
+	  mutex_unlock(&av->mutex);
29e444
+	  malloc_printerr (check_action, "malloc(): memory corruption", p);
29e444
+	  mutex_lock(&av->mutex);
29e444
+	}
29e444
       size = chunksize(victim);
29e444
 
29e444
       /*
29e444
@@ -3572,7 +3582,7 @@ _int_malloc(mstate av, size_t bytes)
29e444
 	  victim = victim->fd;
29e444
 
29e444
 	remainder_size = size - nb;
29e444
-	unlink(victim, bck, fwd);
29e444
+	unlink(av, victim, bck, fwd);
29e444
 
29e444
 	/* Exhaust */
29e444
 	if (remainder_size < MINSIZE)  {
29e444
@@ -3670,7 +3680,7 @@ _int_malloc(mstate av, size_t bytes)
29e444
 	remainder_size = size - nb;
29e444
 
29e444
 	/* unlink */
29e444
-	unlink(victim, bck, fwd);
29e444
+	unlink(av, victim, bck, fwd);
29e444
 
29e444
 	/* Exhaust */
29e444
 	if (remainder_size < MINSIZE) {
29e444
@@ -3805,9 +3815,11 @@ _int_free(mstate av, mchunkptr p, int ha
29e444
     {
29e444
       errstr = "free(): invalid pointer";
29e444
     errout:
29e444
-      if (! have_lock && locked)
29e444
+      if (have_lock || locked)
29e444
 	(void)mutex_unlock(&av->mutex);
29e444
       malloc_printerr (check_action, errstr, chunk2mem(p));
29e444
+      if (have_lock)
29e444
+	mutex_lock(&av->mutex);
29e444
       return;
29e444
     }
29e444
   /* We know that each chunk is at least MINSIZE bytes in size or a
29e444
@@ -3952,7 +3964,7 @@ _int_free(mstate av, mchunkptr p, int ha
29e444
       prevsize = p->prev_size;
29e444
       size += prevsize;
29e444
       p = chunk_at_offset(p, -((long) prevsize));
29e444
-      unlink(p, bck, fwd);
29e444
+      unlink(av, p, bck, fwd);
29e444
     }
29e444
 
29e444
     if (nextchunk != av->top) {
29e444
@@ -3961,7 +3973,7 @@ _int_free(mstate av, mchunkptr p, int ha
29e444
 
29e444
       /* consolidate forward */
29e444
       if (!nextinuse) {
29e444
-	unlink(nextchunk, bck, fwd);
29e444
+	unlink(av, nextchunk, bck, fwd);
29e444
 	size += nextsize;
29e444
       } else
29e444
 	clear_inuse_bit_at_offset(nextchunk, 0);
29e444
@@ -4122,7 +4134,7 @@ static void malloc_consolidate(mstate av
29e444
 	    prevsize = p->prev_size;
29e444
 	    size += prevsize;
29e444
 	    p = chunk_at_offset(p, -((long) prevsize));
29e444
-	    unlink(p, bck, fwd);
29e444
+	    unlink(av, p, bck, fwd);
29e444
 	  }
29e444
 
29e444
 	  if (nextchunk != av->top) {
29e444
@@ -4130,7 +4142,7 @@ static void malloc_consolidate(mstate av
29e444
 
29e444
 	    if (!nextinuse) {
29e444
 	      size += nextsize;
29e444
-	      unlink(nextchunk, bck, fwd);
29e444
+	      unlink(av, nextchunk, bck, fwd);
29e444
 	    } else
29e444
 	      clear_inuse_bit_at_offset(nextchunk, 0);
29e444
 
29e444
@@ -4199,7 +4211,9 @@ _int_realloc(mstate av, mchunkptr oldp,
29e444
     {
29e444
       errstr = "realloc(): invalid old size";
29e444
     errout:
29e444
+      mutex_unlock(&av->mutex);
29e444
       malloc_printerr (check_action, errstr, chunk2mem(oldp));
29e444
+      mutex_lock(&av->mutex);
29e444
       return NULL;
29e444
     }
29e444
 
29e444
@@ -4241,7 +4255,7 @@ _int_realloc(mstate av, mchunkptr oldp,
29e444
 	     (unsigned long)(newsize = oldsize + nextsize) >=
29e444
 	     (unsigned long)(nb)) {
29e444
       newp = oldp;
29e444
-      unlink(next, bck, fwd);
29e444
+      unlink(av, next, bck, fwd);
29e444
     }
29e444
 
29e444
     /* allocate, copy, free */