Browse Source

Improve malloc debugging support.

Miles Bader 22 years ago
parent
commit
4d952dfe77

+ 11 - 0
extra/Configs/Config.in

@@ -367,4 +367,15 @@ config SUPPORT_LD_DEBUG_EARLY
 	  to debug the uClibc shared library loader early initialization,
 	  to debug the uClibc shared library loader early initialization,
 	  answer Y.  Mere mortals answer N.
 	  answer Y.  Mere mortals answer N.
 
 
+config UCLIBC_MALLOC_DEBUGGING
+	bool "Build malloc with debugging support"
+	depends MALLOC
+	default n
+	help
+	  Answer Y here to compile extra debugging support code into malloc.
+	  Malloc debugging output may then be enabled at runtime using
+	  the MALLOC_DEBUG environment variable.  Because this increases
+	  the size of malloc appreciably (due to strings etc), you
+	  should say N unless you need to debug a malloc problem.
+
 endmenu
 endmenu

+ 12 - 2
libc/stdlib/malloc/Makefile

@@ -27,6 +27,16 @@ include $(TOPDIR)Rules.mak
 # calloc.c can be found at uClibc/libc/stdlib/calloc.c 
 # calloc.c can be found at uClibc/libc/stdlib/calloc.c 
 CSRC = malloc.c free.c realloc.c memalign.c \
 CSRC = malloc.c free.c realloc.c memalign.c \
 	heap_alloc.c heap_alloc_at.c heap_free.c
 	heap_alloc.c heap_alloc_at.c heap_free.c
+
+# Turn on malloc debugging if requested
+ifeq ($(UCLIBC_MALLOC_DEBUGGING),y)
+CSRC += malloc_debug.c heap_debug.c
+CFLAGS += -DMALLOC_DEBUGGING -DHEAP_DEBUGGING
+ifeq ($(UCLIBC_UCLINUX_BROKEN_MUNMAP),y)
+CFLAGS += -DMALLOC_MMB_DEBUGGING
+endif
+endif
+
 COBJS=$(patsubst %.c,%.o, $(CSRC))
 COBJS=$(patsubst %.c,%.o, $(CSRC))
 OBJS=$(COBJS)
 OBJS=$(COBJS)
 
 
@@ -37,10 +47,10 @@ $(LIBC): ar-target
 ar-target: $(OBJS)
 ar-target: $(OBJS)
 	$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
 	$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
 
 
-$(COBJS): %.o : %.c
+# Depend on uClinux_config.h to cache changes in __UCLIBC_MALLOC_DEBUGGING__
+$(COBJS): %.o : %.c ../../../include/bits/uClibc_config.h
 	$(CC) $(CFLAGS) -c $< -o $@
 	$(CC) $(CFLAGS) -c $< -o $@
 	$(STRIPTOOL) -x -R .note -R .comment $*.o
 	$(STRIPTOOL) -x -R .note -R .comment $*.o
 
 
 clean:
 clean:
 	rm -f *.[oa] *~ core
 	rm -f *.[oa] *~ core
-

+ 17 - 8
libc/stdlib/malloc/free.c

@@ -31,7 +31,7 @@ free_to_heap (void *mem, struct heap *heap)
 
 
   /* Normal free.  */
   /* Normal free.  */
 
 
-  MALLOC_DEBUG ("free: 0x%lx (base = 0x%lx, total_size = %d)\n",
+  MALLOC_DEBUG (1, "free: 0x%lx (base = 0x%lx, total_size = %d)",
 		(long)mem, (long)MALLOC_BASE (mem), MALLOC_SIZE (mem));
 		(long)mem, (long)MALLOC_BASE (mem), MALLOC_SIZE (mem));
 
 
   size = MALLOC_SIZE (mem);
   size = MALLOC_SIZE (mem);
@@ -76,7 +76,7 @@ free_to_heap (void *mem, struct heap *heap)
 	 reasonably cheap.  */
 	 reasonably cheap.  */
       if ((void *)end != sbrk (0))
       if ((void *)end != sbrk (0))
 	{
 	{
-	  MALLOC_DEBUG ("  not unmapping: 0x%lx - 0x%lx (%ld bytes)\n",
+	  MALLOC_DEBUG (-1, "not unmapping: 0x%lx - 0x%lx (%ld bytes)",
 			start, end, end - start);
 			start, end, end - start);
 	  __malloc_unlock_sbrk ();
 	  __malloc_unlock_sbrk ();
 	  __heap_unlock (heap);
 	  __heap_unlock (heap);
@@ -84,7 +84,7 @@ free_to_heap (void *mem, struct heap *heap)
 	}
 	}
 #endif
 #endif
 
 
-      MALLOC_DEBUG ("  unmapping: 0x%lx - 0x%lx (%ld bytes)\n",
+      MALLOC_DEBUG (0, "unmapping: 0x%lx - 0x%lx (%ld bytes)",
 		    start, end, end - start);
 		    start, end, end - start);
 
 
       /* Remove FA from the heap.  */
       /* Remove FA from the heap.  */
@@ -119,7 +119,8 @@ free_to_heap (void *mem, struct heap *heap)
 	 exactly as we got them from mmap, so scan through our list of
 	 exactly as we got them from mmap, so scan through our list of
 	 mmapped blocks, and return them in order.  */
 	 mmapped blocks, and return them in order.  */
 
 
-      MALLOC_MMB_DEBUG ("  walking mmb list for region 0x%x[%d]...\n", start, end - start);
+      MALLOC_MMB_DEBUG (1, "walking mmb list for region 0x%x[%d]...",
+			start, end - start);
 
 
       prev_mmb = 0;
       prev_mmb = 0;
       mmb = __malloc_mmapped_blocks;
       mmb = __malloc_mmapped_blocks;
@@ -127,7 +128,7 @@ free_to_heap (void *mem, struct heap *heap)
 	     && ((mmb_end = (mmb_start = (unsigned long)mmb->mem) + mmb->size)
 	     && ((mmb_end = (mmb_start = (unsigned long)mmb->mem) + mmb->size)
 		 <= end))
 		 <= end))
 	{
 	{
-	  MALLOC_MMB_DEBUG ("    considering mmb at 0x%x: 0x%x[%d]\n",
+	  MALLOC_MMB_DEBUG (1, "considering mmb at 0x%x: 0x%x[%d]",
 			    (unsigned)mmb, mmb_start, mmb_end - mmb_start);
 			    (unsigned)mmb, mmb_start, mmb_end - mmb_start);
 
 
 	  if (mmb_start >= start
 	  if (mmb_start >= start
@@ -143,18 +144,20 @@ free_to_heap (void *mem, struct heap *heap)
 		   this block, so give up.  */
 		   this block, so give up.  */
 		break;
 		break;
 
 
-	      MALLOC_MMB_DEBUG ("      unmapping mmb at 0x%x: 0x%x[%d]\n",
+	      MALLOC_MMB_DEBUG (1, "unmapping mmb at 0x%x: 0x%x[%d]",
 				(unsigned)mmb, mmb_start, mmb_end - mmb_start);
 				(unsigned)mmb, mmb_start, mmb_end - mmb_start);
 
 
 	      if (mmb_start != start)
 	      if (mmb_start != start)
 		/* We're going to unmap a part of the heap that begins after
 		/* We're going to unmap a part of the heap that begins after
 		   start, so put the intervening region back into the heap.  */
 		   start, so put the intervening region back into the heap.  */
 		{
 		{
-		  MALLOC_MMB_DEBUG ("        putting intervening region back into heap: 0x%x[%d]\n",
+		  MALLOC_MMB_DEBUG (0, "putting intervening region back into heap: 0x%x[%d]",
 				    start, mmb_start - start);
 				    start, mmb_start - start);
 		  __heap_free (heap, (void *)start, mmb_start - start);
 		  __heap_free (heap, (void *)start, mmb_start - start);
 		}
 		}
 
 
+	      MALLOC_MMB_DEBUG_INDENT (-1);
+
 	      /* Unlink MMB from the list.  */
 	      /* Unlink MMB from the list.  */
 	      if (prev_mmb)
 	      if (prev_mmb)
 		prev_mmb->next = next_mmb;
 		prev_mmb->next = next_mmb;
@@ -194,17 +197,21 @@ free_to_heap (void *mem, struct heap *heap)
 	      prev_mmb = mmb;
 	      prev_mmb = mmb;
 	      mmb = mmb->next;
 	      mmb = mmb->next;
 	    }
 	    }
+
+	  MALLOC_MMB_DEBUG_INDENT (-1);
 	}
 	}
 
 
       if (start != end)
       if (start != end)
 	/* Hmm, well there's something we couldn't unmap, so put it back
 	/* Hmm, well there's something we couldn't unmap, so put it back
 	   into the heap.  */
 	   into the heap.  */
 	{
 	{
-	  MALLOC_MMB_DEBUG ("    putting tail region back into heap: 0x%x[%d]\n",
+	  MALLOC_MMB_DEBUG (0, "putting tail region back into heap: 0x%x[%d]",
 			    start, end - start);
 			    start, end - start);
 	  __heap_free (heap, (void *)start, end - start);
 	  __heap_free (heap, (void *)start, end - start);
 	}
 	}
 
 
+      MALLOC_MMB_DEBUG_INDENT (-1);
+
 # else /* !__UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
 # else /* !__UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
 
 
       /* MEM/LEN may not be page-aligned, so we have to page-align them,
       /* MEM/LEN may not be page-aligned, so we have to page-align them,
@@ -241,6 +248,8 @@ free_to_heap (void *mem, struct heap *heap)
 
 
 #endif /* MALLOC_USE_SBRK */
 #endif /* MALLOC_USE_SBRK */
     }
     }
+
+  MALLOC_DEBUG_INDENT (-1);
 }
 }
 
 
 void
 void

+ 15 - 10
libc/stdlib/malloc/heap_debug.c

@@ -16,6 +16,7 @@
 #include <stdarg.h>
 #include <stdarg.h>
 #include <string.h>
 #include <string.h>
 
 
+#include "malloc.h"
 #include "heap.h"
 #include "heap.h"
 
 
 
 
@@ -29,14 +30,14 @@ __heap_dump_freelist (struct heap *heap)
 {
 {
   struct heap_free_area *fa;
   struct heap_free_area *fa;
   for (fa = heap->free_areas; fa; fa = fa->next)
   for (fa = heap->free_areas; fa; fa = fa->next)
-    fprintf (stderr,
+    __malloc_debug_printf (0,
-	     "    0x%lx:  0x%lx - 0x%lx  (%d)\tP=0x%lx, N=0x%lx\n",
+			   "0x%lx:  0x%lx - 0x%lx  (%d)\tP=0x%lx, N=0x%lx",
-	     (long)fa,
+			   (long)fa,
-	     (long)HEAP_FREE_AREA_START (fa),
+			   (long)HEAP_FREE_AREA_START (fa),
-	     (long)HEAP_FREE_AREA_END (fa),
+			   (long)HEAP_FREE_AREA_END (fa),
-	     fa->size,
+			   fa->size,
-	     (long)fa->prev,
+			   (long)fa->prev,
-	     (long)fa->next);
+			   (long)fa->next);
 }
 }
 
 
 /* Output a text representation of HEAP to stderr, labelling it with STR.  */
 /* Output a text representation of HEAP to stderr, labelling it with STR.  */
@@ -51,8 +52,9 @@ __heap_dump (struct heap *heap, const char *str)
 
 
       recursed = 1;
       recursed = 1;
 
 
-      fprintf (stderr, "  %s: heap @0x%lx:\n", str, (long)heap);
+      __malloc_debug_printf (1, "%s: heap @0x%lx:", str, (long)heap);
       __heap_dump_freelist (heap);
       __heap_dump_freelist (heap);
+      __malloc_debug_indent (-1);
 
 
       recursed = 0;
       recursed = 0;
     }
     }
@@ -76,7 +78,10 @@ __heap_check_failure (struct heap *heap, struct heap_free_area *fa,
   vfprintf (stderr, fmt, val);
   vfprintf (stderr, fmt, val);
   va_end (val);
   va_end (val);
 
 
-  fprintf (stderr, "\nheap dump:\n");
+  putc ('\n', stderr);
+
+  __malloc_debug_set_indent (0);
+  __malloc_debug_printf (1, "heap dump:");
   __heap_dump_freelist (heap);
   __heap_dump_freelist (heap);
 
 
   exit (22);
   exit (22);

+ 19 - 12
libc/stdlib/malloc/malloc.c

@@ -29,10 +29,6 @@ struct heap __malloc_heap = HEAP_INIT_WITH_FA (initial_fa);
 malloc_mutex_t __malloc_sbrk_lock;
 malloc_mutex_t __malloc_sbrk_lock;
 #endif /* MALLOC_USE_LOCKING && MALLOC_USE_SBRK */
 #endif /* MALLOC_USE_LOCKING && MALLOC_USE_SBRK */
 
 
-#ifdef MALLOC_DEBUGGING
-int __malloc_debug = 0;
-#endif
-
 
 
 #ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__
 #ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__
 /* A list of all malloc_mmb structures describing blocsk that
 /* A list of all malloc_mmb structures describing blocsk that
@@ -44,10 +40,6 @@ struct malloc_mmb *__malloc_mmapped_blocks = 0;
    annoying ways.  */
    annoying ways.  */
 HEAP_DECLARE_STATIC_FREE_AREA (initial_mmb_fa, 48); /* enough for 3 mmbs */
 HEAP_DECLARE_STATIC_FREE_AREA (initial_mmb_fa, 48); /* enough for 3 mmbs */
 struct heap __malloc_mmb_heap = HEAP_INIT_WITH_FA (initial_mmb_fa);
 struct heap __malloc_mmb_heap = HEAP_INIT_WITH_FA (initial_mmb_fa);
-
-# ifdef MALLOC_MMB_DEBUGGING
-int __malloc_mmb_debug = 0;
-# endif
 #endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
 #endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
 
 
 
 
@@ -56,7 +48,7 @@ malloc_from_heap (size_t size, struct heap *heap)
 {
 {
   void *mem;
   void *mem;
 
 
-  MALLOC_DEBUG ("malloc: %d bytes\n", size);
+  MALLOC_DEBUG (1, "malloc: %d bytes", size);
 
 
   /* Include extra space to record the size of the allocated block.  */
   /* Include extra space to record the size of the allocated block.  */
   size += MALLOC_HEADER_SIZE;
   size += MALLOC_HEADER_SIZE;
@@ -121,7 +113,7 @@ malloc_from_heap (size_t size, struct heap *heap)
 	  struct malloc_mmb *mmb, *prev_mmb, *new_mmb;
 	  struct malloc_mmb *mmb, *prev_mmb, *new_mmb;
 #endif
 #endif
 
 
-	  MALLOC_DEBUG ("  adding memory: 0x%lx - 0x%lx (%d bytes)\n",
+	  MALLOC_DEBUG (1, "adding system memroy to heap: 0x%lx - 0x%lx (%d bytes)",
 			(long)block, (long)block + block_size, block_size);
 			(long)block, (long)block + block_size, block_size);
 
 
 	  /* Get back the heap lock.  */
 	  /* Get back the heap lock.  */
@@ -130,6 +122,8 @@ malloc_from_heap (size_t size, struct heap *heap)
 	  /* Put BLOCK into the heap.  */
 	  /* Put BLOCK into the heap.  */
 	  __heap_free (heap, block, block_size);
 	  __heap_free (heap, block, block_size);
 
 
+	  MALLOC_DEBUG_INDENT (-1);
+
 	  /* Try again to allocate.  */
 	  /* Try again to allocate.  */
 	  mem = __heap_alloc (heap, &size);
 	  mem = __heap_alloc (heap, &size);
 
 
@@ -155,7 +149,7 @@ malloc_from_heap (size_t size, struct heap *heap)
 	  else
 	  else
 	    __malloc_mmapped_blocks = new_mmb;
 	    __malloc_mmapped_blocks = new_mmb;
 
 
-	  MALLOC_MMB_DEBUG ("  new mmb at 0x%x: 0x%x[%d]\n",
+	  MALLOC_MMB_DEBUG (0, "new mmb at 0x%x: 0x%x[%d]",
 			    (unsigned)new_mmb,
 			    (unsigned)new_mmb,
 			    (unsigned)new_mmb->mem, block_size);
 			    (unsigned)new_mmb->mem, block_size);
 #endif /* !MALLOC_USE_SBRK && __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
 #endif /* !MALLOC_USE_SBRK && __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
@@ -167,9 +161,11 @@ malloc_from_heap (size_t size, struct heap *heap)
     {
     {
       mem = MALLOC_SETUP (mem, size);
       mem = MALLOC_SETUP (mem, size);
 
 
-      MALLOC_DEBUG ("  malloc: returning 0x%lx (base:0x%lx, total_size:%d)\n",
+      MALLOC_DEBUG (-1, "malloc: returning 0x%lx (base:0x%lx, total_size:%ld)",
 		    (long)mem, (long)MALLOC_BASE(mem), (long)MALLOC_SIZE(mem));
 		    (long)mem, (long)MALLOC_BASE(mem), (long)MALLOC_SIZE(mem));
     }
     }
+  else
+    MALLOC_DEBUG (-1, "malloc: returning 0");
 
 
   return mem;
   return mem;
 }
 }
@@ -177,5 +173,16 @@ malloc_from_heap (size_t size, struct heap *heap)
 void *
 void *
 malloc (size_t size)
 malloc (size_t size)
 {
 {
+#ifdef MALLOC_DEBUGGING
+  static int debugging_initialized = 0;
+  if (! debugging_initialized)
+    {
+      debugging_initialized = 1;
+      __malloc_debug_init ();
+    }
+  if (__malloc_check)
+    __heap_check (&__malloc_heap, "malloc");
+#endif
+
   return malloc_from_heap (size, &__malloc_heap);
   return malloc_from_heap (size, &__malloc_heap);
 }
 }

+ 34 - 11
libc/stdlib/malloc/malloc.h

@@ -78,12 +78,18 @@ extern struct heap __malloc_mmb_heap;
    about mmap block allocation/freeing by the `uclinux broken munmap' code
    about mmap block allocation/freeing by the `uclinux broken munmap' code
    to stderr, when the variable __malloc_mmb_debug is set to true. */
    to stderr, when the variable __malloc_mmb_debug is set to true. */
 #ifdef MALLOC_MMB_DEBUGGING
 #ifdef MALLOC_MMB_DEBUGGING
-#include <stdio.h>
+# include <stdio.h>
 extern int __malloc_mmb_debug;
 extern int __malloc_mmb_debug;
-#define MALLOC_MMB_DEBUG(fmt, args...) \
+# define MALLOC_MMB_DEBUG(indent, fmt, args...)				      \
-  (__malloc_mmb_debug ? fprintf (stderr, fmt , ##args) : 0)
+   (__malloc_mmb_debug ? __malloc_debug_printf (indent, fmt , ##args) : 0)
+# define MALLOC_MMB_DEBUG_INDENT(indent)				      \
+   (__malloc_mmb_debug ? __malloc_debug_indent (indent) : 0)
+# ifndef MALLOC_DEBUGGING
+#  define MALLOC_DEBUGGING
+# endif
 #else /* !MALLOC_MMB_DEBUGGING */
 #else /* !MALLOC_MMB_DEBUGGING */
-#define MALLOC_MMB_DEBUG(fmt, args...) (void)0
+# define MALLOC_MMB_DEBUG(fmt, args...) (void)0
+# define MALLOC_MMB_DEBUG_INDENT(indent) (void)0
 #endif /* MALLOC_MMB_DEBUGGING */
 #endif /* MALLOC_MMB_DEBUGGING */
 
 
 #endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
 #endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
@@ -158,13 +164,30 @@ extern malloc_mutex_t __malloc_sbrk_lock;
 /* Define MALLOC_DEBUGGING to cause malloc to emit debugging info to stderr
 /* Define MALLOC_DEBUGGING to cause malloc to emit debugging info to stderr
    when the variable __malloc_debug is set to true. */
    when the variable __malloc_debug is set to true. */
 #ifdef MALLOC_DEBUGGING
 #ifdef MALLOC_DEBUGGING
-#include <stdio.h>
+
-extern int __malloc_debug;
+extern int __malloc_debug, __malloc_check;
-#define MALLOC_DEBUG(fmt, args...) \
+
-  (__malloc_debug ? fprintf (stderr, fmt , ##args) : 0)
+# define MALLOC_DEBUG(indent, fmt, args...)				      \
-#else
+   (__malloc_debug ? __malloc_debug_printf (indent, fmt , ##args) : 0)
-#define MALLOC_DEBUG(fmt, args...) (void)0
+# define MALLOC_DEBUG_INDENT(indent)					      \
-#endif
+   (__malloc_debug ? __malloc_debug_indent (indent) : 0)
+
+extern int __malloc_debug_cur_indent;
+
+/* Print FMT and args indented at the current debug print level, followed
+   by a newline, and change the level by INDENT.  */
+extern void __malloc_debug_printf (int indent, const char *fmt, ...);
+
+/* Change the current debug print level by INDENT.  */
+#define __malloc_debug_indent(indent) (__malloc_debug_cur_indent += indent)
+
+/* Set the current debug print level to LEVEL.  */
+#define __malloc_debug_set_indent(level) (__malloc_debug_cur_indent = level)
+
+#else /* !MALLOC_DEBUGGING */
+# define MALLOC_DEBUG(fmt, args...) (void)0
+# define MALLOC_DEBUG_INDENT(indent) (void)0
+#endif /* MALLOC_DEBUGGING */
 
 
 
 
 /* Return SZ rounded down to POWER_OF_2_SIZE (which must be power of 2).  */
 /* Return SZ rounded down to POWER_OF_2_SIZE (which must be power of 2).  */

+ 85 - 0
libc/stdlib/malloc/malloc_debug.c

@@ -0,0 +1,85 @@
+/*
+ * libc/stdlib/malloc/malloc_debug.c -- malloc debugging support
+ *
+ *  Copyright (C) 2002  NEC Corporation
+ *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License.  See the file COPYING.LIB in the main
+ * directory of this archive for more details.
+ * 
+ * Written by Miles Bader <miles@gnu.org>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "malloc.h"
+#include "heap.h"
+
+#ifdef MALLOC_DEBUGGING
+int __malloc_debug = 0, __malloc_check = 0;
+#endif
+
+#ifdef MALLOC_MMB_DEBUGGING
+int __malloc_mmb_debug = 0;
+#endif
+
+/* Debugging output is indented this may levels.  */
+int __malloc_debug_cur_indent = 0;
+
+
+/* Print FMT and args indented at the current debug print level, followed
+   by a newline, and change the level by INDENT.  */
+void
+__malloc_debug_printf (int indent, const char *fmt, ...)
+{
+  int i;
+  va_list val;
+
+  for (i = 0; i < __malloc_debug_cur_indent; i++)
+    fputs ("   ", stderr);
+
+  va_start (val, fmt);
+  vfprintf (stderr, fmt, val);
+  va_end (val);
+
+  putc ('\n', stderr);
+
+  __malloc_debug_indent (indent);
+}
+
+void
+__malloc_debug_init (void)
+{
+  char *ev = getenv ("MALLOC_DEBUG");
+  if (ev)
+    {
+      int val = atoi (ev);
+      if (val & 1)
+	__malloc_check = 1;
+
+#ifdef MALLOC_DEBUGGING
+      if (val & 2)
+	__malloc_debug = 1;
+#endif
+#ifdef MALLOC_MMB_DEBUGGING
+      if (val & 4)
+	__malloc_mmb_debug = 1;
+#endif
+
+#ifdef HEAP_DEBUGGING
+      if (val & 8)
+	__heap_debug = 1;
+#endif
+
+      if (val)
+	__malloc_debug_printf
+	  (0, "malloc_debug: initialized to %d (check = %d, dump = %d, dump_mmb = %d, dump_heap = %d)",
+	   val,
+	   !!(val & 1), !!(val & 2),
+	   !!(val & 4), !!(val & 8));
+    }
+}

+ 4 - 3
libc/stdlib/malloc/realloc.c

@@ -43,7 +43,7 @@ realloc (void *mem, size_t new_size)
      allocation unit (SIZE is already guaranteed to be so).*/
      allocation unit (SIZE is already guaranteed to be so).*/
   new_size = HEAP_ADJUST_SIZE (new_size + MALLOC_HEADER_SIZE);
   new_size = HEAP_ADJUST_SIZE (new_size + MALLOC_HEADER_SIZE);
 
 
-  MALLOC_DEBUG ("realloc: 0x%lx, %d (base = 0x%lx, total_size = %d)\n",
+  MALLOC_DEBUG (1, "realloc: 0x%lx, %d (base = 0x%lx, total_size = %d)",
 		(long)mem, new_size, (long)base_mem, size);
 		(long)mem, new_size, (long)base_mem, size);
 
 
   if (new_size > size)
   if (new_size > size)
@@ -81,9 +81,10 @@ realloc (void *mem, size_t new_size)
     }
     }
 
 
   if (mem)
   if (mem)
-    MALLOC_DEBUG ("  realloc: returning 0x%lx"
+    MALLOC_DEBUG (-1, "realloc: returning 0x%lx (base:0x%lx, total_size:%d)",
-		  " (base:0x%lx, total_size:%d)\n",
 		  (long)mem, (long)MALLOC_BASE(mem), (long)MALLOC_SIZE(mem));
 		  (long)mem, (long)MALLOC_BASE(mem), (long)MALLOC_SIZE(mem));
+  else
+    MALLOC_DEBUG (-1, "realloc: returning 0");
 
 
   return mem;
   return mem;
 }
 }