[5/8] mtrace: Wean away from malloc hooks

Message ID 20210624182312.236596-6-siddhesh@sourceware.org
State Superseded
Headers
Series Remove malloc hooks |

Checks

Context Check Description
dj/TryBot-apply_patch fail Patch failed to apply to master at the time it was sent

Commit Message

Siddhesh Poyarekar June 24, 2021, 6:23 p.m. UTC
  Split mtrace hooks into before and after and adapt to the new internal
debugging hooks infrastructure.  With this, the malloc hooks are
unused internally and can be removed from the main library.

This also eliminates the only use of memalign through a PLT in the
library, so checklocalplt data needs to be updated to reflect that.
---
 include/malloc.h                              |   1 +
 malloc/hooks.c                                |  38 ++-
 malloc/mtrace-hooks.c                         | 137 ++++++++++
 malloc/mtrace.c                               | 233 +-----------------
 sysdeps/generic/localplt.data                 |   1 -
 sysdeps/mach/hurd/i386/localplt.data          |   1 -
 sysdeps/unix/sysv/linux/aarch64/localplt.data |   1 -
 sysdeps/unix/sysv/linux/alpha/localplt.data   |   1 -
 sysdeps/unix/sysv/linux/arc/localplt.data     |   1 -
 sysdeps/unix/sysv/linux/arm/localplt.data     |   1 -
 sysdeps/unix/sysv/linux/csky/localplt.data    |   1 -
 sysdeps/unix/sysv/linux/hppa/localplt.data    |   1 -
 sysdeps/unix/sysv/linux/i386/localplt.data    |   1 -
 sysdeps/unix/sysv/linux/ia64/localplt.data    |   1 -
 .../sysv/linux/m68k/coldfire/localplt.data    |   1 -
 .../unix/sysv/linux/m68k/m680x0/localplt.data |   1 -
 .../unix/sysv/linux/microblaze/localplt.data  |   1 -
 sysdeps/unix/sysv/linux/nios2/localplt.data   |   1 -
 .../linux/powerpc/powerpc32/fpu/localplt.data |   1 -
 .../powerpc/powerpc32/nofpu/localplt.data     |   1 -
 .../linux/powerpc/powerpc64/localplt.data     |   1 -
 sysdeps/unix/sysv/linux/riscv/localplt.data   |   1 -
 sysdeps/unix/sysv/linux/s390/localplt.data    |   1 -
 sysdeps/unix/sysv/linux/sh/localplt.data      |   1 -
 .../sysv/linux/sparc/sparc32/localplt.data    |   1 -
 .../sysv/linux/sparc/sparc64/localplt.data    |   1 -
 sysdeps/x86_64/localplt.data                  |   1 -
 27 files changed, 180 insertions(+), 252 deletions(-)
 create mode 100644 malloc/mtrace-hooks.c
  

Comments

DJ Delorie June 24, 2021, 11:13 p.m. UTC | #1
Siddhesh Poyarekar <siddhesh@sourceware.org> writes:
> Split mtrace hooks into before and after and adapt to the new internal
> debugging hooks infrastructure.  With this, the malloc hooks are
> unused internally and can be removed from the main library.
>
> This also eliminates the only use of memalign through a PLT in the
> library, so checklocalplt data needs to be updated to reflect that.

> diff --git a/include/malloc.h b/include/malloc.h
> index bb1123d9d3..6169d486f5 100644
> --- a/include/malloc.h
> +++ b/include/malloc.h
> @@ -15,6 +15,7 @@ typedef struct malloc_state *mstate;
>  #define __malloc_initialized __libc_malloc_initialized
>  /* Nonzero if the malloc is already initialized.  */
>  extern int __malloc_initialized attribute_hidden;
> +extern FILE *__mtrace_mallstream attribute_hidden;

Ok.

> diff --git a/malloc/hooks.c b/malloc/hooks.c
> index b517a98ea2..492e9aac63 100644
> --- a/malloc/hooks.c
> +++ b/malloc/hooks.c
> @@ -37,6 +37,7 @@ enum malloc_debug_hooks
>    MALLOC_NONE_HOOK = 0,
>    MALLOC_CHECK_HOOK = 1 << 0,	/* MALLOC_CHECK_ or glibc.malloc.check.  */
>    MALLOC_MCHECK_HOOK = 1 << 1,	/* mcheck()  */
> +  MALLOC_MTRACE_HOOK = 1 << 2,	/* mtrace()  */
>  };
>  static unsigned __malloc_debugging_hooks;

Ok.

> @@ -111,8 +113,13 @@ _malloc_debug_before (size_t *bytesp, void **victimp, const void *address)
>  static __always_inline void *
>  _malloc_debug_after (void *mem, size_t bytes, const void *address)
>  {
> -  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
> -    mem = malloc_mcheck_after (mem, bytes);
> +  if (__glibc_unlikely (__malloc_debugging_hooks))
> +    {
> +      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
> +	mem = malloc_mcheck_after (mem, bytes);
> +      if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
> +	mem = malloc_mtrace_after (mem, bytes, address);
> +    }
>    return mem;
>  }

I suspect this should have been in part 4, but ok.

> @@ -129,6 +136,8 @@ _free_debug_before (void **mem, const void *address)
>  
>    if (__glibc_unlikely (__malloc_debugging_hooks))
>      {
> +      if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
> +	free_mtrace (mem, address);
>        if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
>  	*mem = free_mcheck (*mem);
>        if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))

Ok.

> @@ -171,8 +180,13 @@ static __always_inline void *
>  _realloc_debug_after (void *mem, void *oldmem, size_t bytes, size_t oldsize,
>  		      const void *address)
>  {
> -  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
> -    mem = realloc_mcheck_after (mem, oldmem, bytes, oldsize);
> +  if (__glibc_unlikely (__malloc_debugging_hooks))
> +    {
> +      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
> +	mem = realloc_mcheck_after (mem, oldmem, bytes, oldsize);
> +      if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
> +	mem = realloc_mtrace_after (mem, oldmem, bytes, address);
> +    }
>    return mem;
>  }

Part 4, but ok.

> @@ -206,8 +220,13 @@ static __always_inline void *
>  _memalign_debug_after (void *mem, size_t alignment, size_t bytes,
>  		       const void *address)
>  {
> -  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
> -    mem = memalign_mcheck_after (mem, alignment, bytes);
> +  if (__glibc_unlikely (__malloc_debugging_hooks))
> +    {
> +      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
> +	mem = memalign_mcheck_after (mem, alignment, bytes);
> +      if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
> +	mem = memalign_mtrace_after (mem, bytes, address);
> +    }
>    return mem;
>  }

Likewise.  Ok.

> @@ -243,11 +262,14 @@ _calloc_debug_before (size_t *bytesp, void **victimp, const void *address)
>  static __always_inline void *
>  _calloc_debug_after (void *mem, size_t bytes, const void *address)
>  {
> -  if (__glibc_unlikely (__malloc_debugging_hooks) && mem != NULL)
> +  if (__glibc_unlikely (__malloc_debugging_hooks))
>      {
>        if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
>  	mem = malloc_mcheck_after (mem, bytes);
> -      memset (mem, 0, bytes);
> +      if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
> +	mem = malloc_mtrace_after (mem, bytes, address);
> +      else if (mem != NULL)
> +	memset (mem, 0, bytes);
>      }

Why "else memset" ? We don't zero memory when tracing?  Or it's zero'd
elsewhere?  What if we have both hooks set?

Regardless, deserves a comment here.

> diff --git a/malloc/mtrace-hooks.c b/malloc/mtrace-hooks.c
> new file mode 100644
> index 0000000000..c1c6d6a6e9
> --- /dev/null
> +++ b/malloc/mtrace-hooks.c

Still missing makefile dependency.

Mostly just a copy-paste from mtrace.c, so OK.

> diff --git a/malloc/mtrace.c b/malloc/mtrace.c
> index 6c2c58b706..2cc4507e25 100644
> --- a/malloc/mtrace.c
> +++ b/malloc/mtrace.c
> @@ -22,7 +22,6 @@
>  # define _MALLOC_INTERNAL
>  # include <malloc.h>
>  # include <mcheck.h>
> -# include <libc-lock.h>
>  #endif

Lots of deletions moved to mtrace-hooks.c, ok.

> @@ -276,7 +71,7 @@ static void __libc_freeres_fn_section
>  release_libc_mem (void)
>  {
>    /* Only call the free function if we still are running in mtrace mode.  */
> -  if (mallstream != NULL)
> +  if (__mtrace_mallstream != NULL)
>      __libc_freeres ();
>  }

Ok.

> @@ -293,7 +88,7 @@ mtrace (void)
>    char *mallfile;
>  
>    /* Don't panic if we're called more than once.  */
> -  if (mallstream != NULL)
> +  if (__mtrace_mallstream != NULL)
>      return;

Ok.

>  #ifdef _LIBC
> @@ -310,15 +105,15 @@ mtrace (void)
>        if (mtb == NULL)
>          return;
>  
> -      mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "wce");
> -      if (mallstream != NULL)
> +      __mtrace_mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null",
> +				   "wce");
> +      if (__mtrace_mallstream != NULL)

Ok.

>          {
>            /* Be sure it doesn't malloc its buffer!  */
>            malloc_trace_buffer = mtb;
> -          setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
> -          fprintf (mallstream, "= Start\n");
> -	  save_default_hooks ();
> -	  set_trace_hooks ();
> +          setvbuf (__mtrace_mallstream, malloc_trace_buffer, _IOFBF,
> +		   TRACE_BUFFER_SIZE);
> +          fprintf (__mtrace_mallstream, "= Start\n");

Ok.

> @@ -336,15 +131,11 @@ mtrace (void)
>  void
>  muntrace (void)
>  {
> -  if (mallstream == NULL)
> +  if (__mtrace_mallstream == NULL)
>      return;

Ok.

> -  /* Do the reverse of what done in mtrace: first reset the hooks and
> -     MALLSTREAM, and only after that write the trailer and close the
> -     file.  */
> -  FILE *f = mallstream;
> -  mallstream = NULL;
> -  set_default_hooks ();
> +  FILE *f = __mtrace_mallstream;
> +  __mtrace_mallstream = NULL;
>  
>    fprintf (f, "= End\n");
>    fclose (f);

Ok.
  
Siddhesh Poyarekar June 28, 2021, 6:25 a.m. UTC | #2
On 6/25/21 4:43 AM, DJ Delorie via Libc-alpha wrote:
>> @@ -243,11 +262,14 @@ _calloc_debug_before (size_t *bytesp, void **victimp, const void *address)
>>   static __always_inline void *
>>   _calloc_debug_after (void *mem, size_t bytes, const void *address)
>>   {
>> -  if (__glibc_unlikely (__malloc_debugging_hooks) && mem != NULL)
>> +  if (__glibc_unlikely (__malloc_debugging_hooks))
>>       {
>>         if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
>>   	mem = malloc_mcheck_after (mem, bytes);
>> -      memset (mem, 0, bytes);
>> +      if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
>> +	mem = malloc_mtrace_after (mem, bytes, address);
>> +      else if (mem != NULL)
>> +	memset (mem, 0, bytes);
>>       }
> 
> Why "else memset" ? We don't zero memory when tracing?  Or it's zero'd
> elsewhere?  What if we have both hooks set?
> 
> Regardless, deserves a comment here.

Ahh yes, that will break if mtrace hook is enabled along with another 
hook.  Mtrace itself does not need zeroing because it defers allocation 
and zeroing to glibc malloc.

I'll fix it up and also add a comment.

>> diff --git a/malloc/mtrace-hooks.c b/malloc/mtrace-hooks.c
>> new file mode 100644
>> index 0000000000..c1c6d6a6e9
>> --- /dev/null
>> +++ b/malloc/mtrace-hooks.c
> 
> Still missing makefile dependency.
> 
> Mostly just a copy-paste from mtrace.c, so OK.
> 

Fixed.

Thanks,
Siddhesh
  

Patch

diff --git a/include/malloc.h b/include/malloc.h
index bb1123d9d3..6169d486f5 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -15,6 +15,7 @@  typedef struct malloc_state *mstate;
 #define __malloc_initialized __libc_malloc_initialized
 /* Nonzero if the malloc is already initialized.  */
 extern int __malloc_initialized attribute_hidden;
+extern FILE *__mtrace_mallstream attribute_hidden;
 
 enum mcheck_status __mcheck_checkptr (const void *) attribute_hidden;
 extern int __mcheck_initialize (void (*) (enum mcheck_status), bool)
diff --git a/malloc/hooks.c b/malloc/hooks.c
index b517a98ea2..492e9aac63 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -37,6 +37,7 @@  enum malloc_debug_hooks
   MALLOC_NONE_HOOK = 0,
   MALLOC_CHECK_HOOK = 1 << 0,	/* MALLOC_CHECK_ or glibc.malloc.check.  */
   MALLOC_MCHECK_HOOK = 1 << 1,	/* mcheck()  */
+  MALLOC_MTRACE_HOOK = 1 << 2,	/* mtrace()  */
 };
 static unsigned __malloc_debugging_hooks;
 
@@ -79,6 +80,7 @@  __malloc_debug_disable (enum malloc_debug_hooks flag)
 
 #include "malloc-check.c"
 #include "mcheck-hooks.c"
+#include "mtrace-hooks.c"
 
 static __always_inline bool
 _malloc_debug_before (size_t *bytesp, void **victimp, const void *address)
@@ -111,8 +113,13 @@  _malloc_debug_before (size_t *bytesp, void **victimp, const void *address)
 static __always_inline void *
 _malloc_debug_after (void *mem, size_t bytes, const void *address)
 {
-  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
-    mem = malloc_mcheck_after (mem, bytes);
+  if (__glibc_unlikely (__malloc_debugging_hooks))
+    {
+      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
+	mem = malloc_mcheck_after (mem, bytes);
+      if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
+	mem = malloc_mtrace_after (mem, bytes, address);
+    }
   return mem;
 }
 
@@ -129,6 +136,8 @@  _free_debug_before (void **mem, const void *address)
 
   if (__glibc_unlikely (__malloc_debugging_hooks))
     {
+      if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
+	free_mtrace (mem, address);
       if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
 	*mem = free_mcheck (*mem);
       if (__is_malloc_debug_enabled (MALLOC_CHECK_HOOK))
@@ -171,8 +180,13 @@  static __always_inline void *
 _realloc_debug_after (void *mem, void *oldmem, size_t bytes, size_t oldsize,
 		      const void *address)
 {
-  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
-    mem = realloc_mcheck_after (mem, oldmem, bytes, oldsize);
+  if (__glibc_unlikely (__malloc_debugging_hooks))
+    {
+      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
+	mem = realloc_mcheck_after (mem, oldmem, bytes, oldsize);
+      if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
+	mem = realloc_mtrace_after (mem, oldmem, bytes, address);
+    }
   return mem;
 }
 
@@ -206,8 +220,13 @@  static __always_inline void *
 _memalign_debug_after (void *mem, size_t alignment, size_t bytes,
 		       const void *address)
 {
-  if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
-    mem = memalign_mcheck_after (mem, alignment, bytes);
+  if (__glibc_unlikely (__malloc_debugging_hooks))
+    {
+      if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK) && mem != NULL)
+	mem = memalign_mcheck_after (mem, alignment, bytes);
+      if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
+	mem = memalign_mtrace_after (mem, bytes, address);
+    }
   return mem;
 }
 
@@ -243,11 +262,14 @@  _calloc_debug_before (size_t *bytesp, void **victimp, const void *address)
 static __always_inline void *
 _calloc_debug_after (void *mem, size_t bytes, const void *address)
 {
-  if (__glibc_unlikely (__malloc_debugging_hooks) && mem != NULL)
+  if (__glibc_unlikely (__malloc_debugging_hooks))
     {
       if (__is_malloc_debug_enabled (MALLOC_MCHECK_HOOK))
 	mem = malloc_mcheck_after (mem, bytes);
-      memset (mem, 0, bytes);
+      if (__is_malloc_debug_enabled (MALLOC_MTRACE_HOOK))
+	mem = malloc_mtrace_after (mem, bytes, address);
+      else if (mem != NULL)
+	memset (mem, 0, bytes);
     }
   return mem;
 }
diff --git a/malloc/mtrace-hooks.c b/malloc/mtrace-hooks.c
new file mode 100644
index 0000000000..c1c6d6a6e9
--- /dev/null
+++ b/malloc/mtrace-hooks.c
@@ -0,0 +1,137 @@ 
+
+# include <libc-lock.h>
+
+#include <kernel-features.h>
+
+FILE *__mtrace_mallstream;
+
+__libc_lock_define_initialized (static, lock);
+
+static void
+tr_where (const void *caller, Dl_info *info)
+{
+  if (caller != NULL)
+    {
+      if (info != NULL)
+        {
+          char *buf = (char *) "";
+          if (info->dli_sname != NULL)
+            {
+              size_t len = strlen (info->dli_sname);
+              buf = alloca (len + 6 + 2 * sizeof (void *));
+
+              buf[0] = '(';
+              __stpcpy (_fitoa (caller >= (const void *) info->dli_saddr
+                                ? caller - (const void *) info->dli_saddr
+                                : (const void *) info->dli_saddr - caller,
+                                __stpcpy (__mempcpy (buf + 1, info->dli_sname,
+                                                     len),
+                                          caller >= (void *) info->dli_saddr
+                                          ? "+0x" : "-0x"),
+                                16, 0),
+                        ")");
+            }
+
+          fprintf (__mtrace_mallstream, "@ %s%s%s[%p] ",
+                   info->dli_fname ? : "", info->dli_fname ? ":" : "",
+                   buf, caller);
+        }
+      else
+        fprintf (__mtrace_mallstream, "@ [%p] ", caller);
+    }
+}
+
+static Dl_info *
+lock_and_info (const void *caller, Dl_info *mem)
+{
+  if (caller == NULL)
+    return NULL;
+
+  Dl_info *res = _dl_addr (caller, mem, NULL, NULL) ? mem : NULL;
+
+  __libc_lock_lock (lock);
+
+  return res;
+}
+
+static bool
+free_mtrace (void *ptr, const void *caller)
+{
+  if (ptr == NULL)
+    return true;
+
+  Dl_info mem;
+  Dl_info *info = lock_and_info (caller, &mem);
+  tr_where (caller, info);
+  /* Be sure to print it first.  */
+  fprintf (__mtrace_mallstream, "- %p\n", ptr);
+  __libc_lock_unlock (lock);
+
+  /* Continue on to free.  */
+  return false;
+}
+
+static void *
+malloc_mtrace_after (void *block, size_t size, const void *caller)
+{
+  Dl_info mem;
+  Dl_info *info = lock_and_info (caller, &mem);
+
+  tr_where (caller, info);
+  /* We could be printing a NULL here; that's OK.  */
+  fprintf (__mtrace_mallstream, "+ %p %#lx\n", block,
+	   (unsigned long int) size);
+
+  __libc_lock_unlock (lock);
+
+  return block;
+}
+
+static void *
+realloc_mtrace_after (void *block, const void *oldptr, size_t size,
+		      const void *caller)
+{
+  Dl_info mem;
+  Dl_info *info = lock_and_info (caller, &mem);
+
+  tr_where (caller, info);
+  if (block == NULL)
+    {
+      if (size != 0)
+        /* Failed realloc.  */
+        fprintf (__mtrace_mallstream, "! %p %#lx\n", oldptr,
+		 (unsigned long int) size);
+      else
+        fprintf (__mtrace_mallstream, "- %p\n", oldptr);
+    }
+  else if (oldptr == NULL)
+    fprintf (__mtrace_mallstream, "+ %p %#lx\n", block,
+	     (unsigned long int) size);
+  else
+    {
+      fprintf (__mtrace_mallstream, "< %p\n", oldptr);
+      tr_where (caller, info);
+      fprintf (__mtrace_mallstream, "> %p %#lx\n", block,
+	       (unsigned long int) size);
+    }
+
+  __libc_lock_unlock (lock);
+
+  return block;
+}
+
+static void *
+memalign_mtrace_after (void *block, size_t size, const void *caller)
+{
+  Dl_info mem;
+  Dl_info *info = lock_and_info (caller, &mem);
+
+  tr_where (caller, info);
+  /* We could be printing a NULL here; that's OK.  */
+  fprintf (__mtrace_mallstream, "+ %p %#lx\n", block,
+	   (unsigned long int) size);
+
+  __libc_lock_unlock (lock);
+
+  return block;
+}
diff --git a/malloc/mtrace.c b/malloc/mtrace.c
index 6c2c58b706..2cc4507e25 100644
--- a/malloc/mtrace.c
+++ b/malloc/mtrace.c
@@ -22,7 +22,6 @@ 
 # define _MALLOC_INTERNAL
 # include <malloc.h>
 # include <mcheck.h>
-# include <libc-lock.h>
 #endif
 
 #include <dlfcn.h>
@@ -35,20 +34,14 @@ 
 
 #include <libc-internal.h>
 #include <dso_handle.h>
-
 #include <libio/iolibio.h>
 #define setvbuf(s, b, f, l) _IO_setvbuf (s, b, f, l)
 #define fwrite(buf, size, count, fp) _IO_fwrite (buf, size, count, fp)
 
-#include <kernel-features.h>
-
 #define TRACE_BUFFER_SIZE 512
 
-static FILE *mallstream;
-static const char mallenv[] = "MALLOC_TRACE";
 static char *malloc_trace_buffer;
-
-__libc_lock_define_initialized (static, lock);
+static const char mallenv[] = "MALLOC_TRACE";
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_34)
 /* Compatibility symbols that were introduced to help break at allocation sites
@@ -69,204 +62,6 @@  tr_break (void)
 compat_symbol (libc, tr_break, tr_break, GLIBC_2_0);
 #endif
 
-
-/* Old hook values.  */
-static void (*tr_old_free_hook) (void *ptr, const void *);
-static void *(*tr_old_malloc_hook) (size_t size, const void *);
-static void *(*tr_old_realloc_hook) (void *ptr, size_t size,
-				     const void *);
-static void *(*tr_old_memalign_hook) (size_t __alignment, size_t __size,
-				      const void *);
-
-static void
-tr_where (const void *caller, Dl_info *info)
-{
-  if (caller != NULL)
-    {
-      if (info != NULL)
-        {
-          char *buf = (char *) "";
-          if (info->dli_sname != NULL)
-            {
-              size_t len = strlen (info->dli_sname);
-              buf = alloca (len + 6 + 2 * sizeof (void *));
-
-              buf[0] = '(';
-              __stpcpy (_fitoa (caller >= (const void *) info->dli_saddr
-                                ? caller - (const void *) info->dli_saddr
-                                : (const void *) info->dli_saddr - caller,
-                                __stpcpy (__mempcpy (buf + 1, info->dli_sname,
-                                                     len),
-                                          caller >= (void *) info->dli_saddr
-                                          ? "+0x" : "-0x"),
-                                16, 0),
-                        ")");
-            }
-
-          fprintf (mallstream, "@ %s%s%s[%p] ",
-                   info->dli_fname ? : "", info->dli_fname ? ":" : "",
-                   buf, caller);
-        }
-      else
-        fprintf (mallstream, "@ [%p] ", caller);
-    }
-}
-
-static Dl_info *
-lock_and_info (const void *caller, Dl_info *mem)
-{
-  if (caller == NULL)
-    return NULL;
-
-  Dl_info *res = _dl_addr (caller, mem, NULL, NULL) ? mem : NULL;
-
-  __libc_lock_lock (lock);
-
-  return res;
-}
-
-static void tr_freehook (void *, const void *);
-static void * tr_mallochook (size_t, const void *);
-static void * tr_reallochook (void *, size_t, const void *);
-static void * tr_memalignhook (size_t, size_t, const void *);
-
-/* Set all the default non-trace hooks.  */
-static __always_inline void
-set_default_hooks (void)
-{
-  __free_hook = tr_old_free_hook;
-  __malloc_hook = tr_old_malloc_hook;
-  __realloc_hook = tr_old_realloc_hook;
-  __memalign_hook = tr_old_memalign_hook;
-}
-
-/* Set all of the tracing hooks used for mtrace.  */
-static __always_inline void
-set_trace_hooks (void)
-{
-  __free_hook = tr_freehook;
-  __malloc_hook = tr_mallochook;
-  __realloc_hook = tr_reallochook;
-  __memalign_hook = tr_memalignhook;
-}
-
-/* Save the current set of hooks as the default hooks.  */
-static __always_inline void
-save_default_hooks (void)
-{
-  tr_old_free_hook = __free_hook;
-  tr_old_malloc_hook = __malloc_hook;
-  tr_old_realloc_hook = __realloc_hook;
-  tr_old_memalign_hook = __memalign_hook;
-}
-
-static void
-tr_freehook (void *ptr, const void *caller)
-{
-  if (ptr == NULL)
-    return;
-
-  Dl_info mem;
-  Dl_info *info = lock_and_info (caller, &mem);
-  tr_where (caller, info);
-  /* Be sure to print it first.  */
-  fprintf (mallstream, "- %p\n", ptr);
-  set_default_hooks ();
-  if (tr_old_free_hook != NULL)
-    (*tr_old_free_hook)(ptr, caller);
-  else
-    free (ptr);
-  set_trace_hooks ();
-  __libc_lock_unlock (lock);
-}
-
-static void *
-tr_mallochook (size_t size, const void *caller)
-{
-  void *hdr;
-
-  Dl_info mem;
-  Dl_info *info = lock_and_info (caller, &mem);
-
-  set_default_hooks ();
-  if (tr_old_malloc_hook != NULL)
-    hdr = (void *) (*tr_old_malloc_hook)(size, caller);
-  else
-    hdr = (void *) malloc (size);
-  set_trace_hooks ();
-
-  tr_where (caller, info);
-  /* We could be printing a NULL here; that's OK.  */
-  fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
-
-  __libc_lock_unlock (lock);
-
-  return hdr;
-}
-
-static void *
-tr_reallochook (void *ptr, size_t size, const void *caller)
-{
-  void *hdr;
-
-  Dl_info mem;
-  Dl_info *info = lock_and_info (caller, &mem);
-
-  set_default_hooks ();
-  if (tr_old_realloc_hook != NULL)
-    hdr = (void *) (*tr_old_realloc_hook)(ptr, size, caller);
-  else
-    hdr = (void *) realloc (ptr, size);
-  set_trace_hooks ();
-
-  tr_where (caller, info);
-  if (hdr == NULL)
-    {
-      if (size != 0)
-        /* Failed realloc.  */
-        fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long int) size);
-      else
-        fprintf (mallstream, "- %p\n", ptr);
-    }
-  else if (ptr == NULL)
-    fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
-  else
-    {
-      fprintf (mallstream, "< %p\n", ptr);
-      tr_where (caller, info);
-      fprintf (mallstream, "> %p %#lx\n", hdr, (unsigned long int) size);
-    }
-
-  __libc_lock_unlock (lock);
-
-  return hdr;
-}
-
-static void *
-tr_memalignhook (size_t alignment, size_t size, const void *caller)
-{
-  void *hdr;
-
-  Dl_info mem;
-  Dl_info *info = lock_and_info (caller, &mem);
-
-  set_default_hooks ();
-  if (tr_old_memalign_hook != NULL)
-    hdr = (void *) (*tr_old_memalign_hook)(alignment, size, caller);
-  else
-    hdr = (void *) memalign (alignment, size);
-  set_trace_hooks ();
-
-  tr_where (caller, info);
-  /* We could be printing a NULL here; that's OK.  */
-  fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
-
-  __libc_lock_unlock (lock);
-
-  return hdr;
-}
-
-
 #ifdef _LIBC
 
 /* This function gets called to make sure all memory the library
@@ -276,7 +71,7 @@  static void __libc_freeres_fn_section
 release_libc_mem (void)
 {
   /* Only call the free function if we still are running in mtrace mode.  */
-  if (mallstream != NULL)
+  if (__mtrace_mallstream != NULL)
     __libc_freeres ();
 }
 #endif
@@ -293,7 +88,7 @@  mtrace (void)
   char *mallfile;
 
   /* Don't panic if we're called more than once.  */
-  if (mallstream != NULL)
+  if (__mtrace_mallstream != NULL)
     return;
 
 #ifdef _LIBC
@@ -310,15 +105,15 @@  mtrace (void)
       if (mtb == NULL)
         return;
 
-      mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "wce");
-      if (mallstream != NULL)
+      __mtrace_mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null",
+				   "wce");
+      if (__mtrace_mallstream != NULL)
         {
           /* Be sure it doesn't malloc its buffer!  */
           malloc_trace_buffer = mtb;
-          setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
-          fprintf (mallstream, "= Start\n");
-	  save_default_hooks ();
-	  set_trace_hooks ();
+          setvbuf (__mtrace_mallstream, malloc_trace_buffer, _IOFBF,
+		   TRACE_BUFFER_SIZE);
+          fprintf (__mtrace_mallstream, "= Start\n");
 #ifdef _LIBC
           if (!added_atexit_handler)
             {
@@ -336,15 +131,11 @@  mtrace (void)
 void
 muntrace (void)
 {
-  if (mallstream == NULL)
+  if (__mtrace_mallstream == NULL)
     return;
 
-  /* Do the reverse of what done in mtrace: first reset the hooks and
-     MALLSTREAM, and only after that write the trailer and close the
-     file.  */
-  FILE *f = mallstream;
-  mallstream = NULL;
-  set_default_hooks ();
+  FILE *f = __mtrace_mallstream;
+  __mtrace_mallstream = NULL;
 
   fprintf (f, "= End\n");
   fclose (f);
diff --git a/sysdeps/generic/localplt.data b/sysdeps/generic/localplt.data
index e2083c0ce6..9b4f35786a 100644
--- a/sysdeps/generic/localplt.data
+++ b/sysdeps/generic/localplt.data
@@ -4,7 +4,6 @@ 
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/mach/hurd/i386/localplt.data b/sysdeps/mach/hurd/i386/localplt.data
index 94064ecbc5..47fbe1e2a7 100644
--- a/sysdeps/mach/hurd/i386/localplt.data
+++ b/sysdeps/mach/hurd/i386/localplt.data
@@ -6,7 +6,6 @@ 
 libc.so: calloc + REL R_386_GLOB_DAT
 libc.so: free + REL R_386_GLOB_DAT
 libc.so: malloc + REL R_386_GLOB_DAT
-libc.so: memalign + REL R_386_GLOB_DAT
 libc.so: realloc + REL R_386_GLOB_DAT
 libm.so: matherr + REL R_386_GLOB_DAT
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/unix/sysv/linux/aarch64/localplt.data b/sysdeps/unix/sysv/linux/aarch64/localplt.data
index 2c14b652ef..348b3f3793 100644
--- a/sysdeps/unix/sysv/linux/aarch64/localplt.data
+++ b/sysdeps/unix/sysv/linux/aarch64/localplt.data
@@ -4,7 +4,6 @@ 
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # If outline atomics are used, libgcc (built outside of glibc) may
diff --git a/sysdeps/unix/sysv/linux/alpha/localplt.data b/sysdeps/unix/sysv/linux/alpha/localplt.data
index 43f6fdaea1..44bf36f4f1 100644
--- a/sysdeps/unix/sysv/linux/alpha/localplt.data
+++ b/sysdeps/unix/sysv/linux/alpha/localplt.data
@@ -18,7 +18,6 @@  libc.so: _Unwind_Find_FDE
 libc.so: calloc + RELA R_ALPHA_GLOB_DAT
 libc.so: free + RELA R_ALPHA_GLOB_DAT
 libc.so: malloc + RELA R_ALPHA_GLOB_DAT
-libc.so: memalign + RELA R_ALPHA_GLOB_DAT
 libc.so: realloc + RELA R_ALPHA_GLOB_DAT
 libm.so: matherr + RELA R_ALPHA_GLOB_DAT
 # We used to offer inline functions that used this, so it must be exported.
diff --git a/sysdeps/unix/sysv/linux/arc/localplt.data b/sysdeps/unix/sysv/linux/arc/localplt.data
index 4479e8ee8a..ac5332caf7 100644
--- a/sysdeps/unix/sysv/linux/arc/localplt.data
+++ b/sysdeps/unix/sysv/linux/arc/localplt.data
@@ -1,6 +1,5 @@ 
 libc.so: realloc
 libc.so: malloc
-libc.so: memalign
 libc.so: calloc
 libc.so: free
 # At -Os, a struct assignment in libgcc-static pulls this in
diff --git a/sysdeps/unix/sysv/linux/arm/localplt.data b/sysdeps/unix/sysv/linux/arm/localplt.data
index eb315da2f1..78896444c6 100644
--- a/sysdeps/unix/sysv/linux/arm/localplt.data
+++ b/sysdeps/unix/sysv/linux/arm/localplt.data
@@ -1,7 +1,6 @@ 
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: raise
 libc.so: realloc
 libm.so: matherr
diff --git a/sysdeps/unix/sysv/linux/csky/localplt.data b/sysdeps/unix/sysv/linux/csky/localplt.data
index 0ed8650b65..817ab2659a 100644
--- a/sysdeps/unix/sysv/linux/csky/localplt.data
+++ b/sysdeps/unix/sysv/linux/csky/localplt.data
@@ -4,7 +4,6 @@ 
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 # The TLS-enabled version of these functions is interposed from libc.so.
 ld.so: _dl_signal_error
diff --git a/sysdeps/unix/sysv/linux/hppa/localplt.data b/sysdeps/unix/sysv/linux/hppa/localplt.data
index 09893d4dcf..baf857a750 100644
--- a/sysdeps/unix/sysv/linux/hppa/localplt.data
+++ b/sysdeps/unix/sysv/linux/hppa/localplt.data
@@ -4,7 +4,6 @@ 
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libc.so: __sigsetjmp
 libc.so: _IO_funlockfile
diff --git a/sysdeps/unix/sysv/linux/i386/localplt.data b/sysdeps/unix/sysv/linux/i386/localplt.data
index 5334875b4b..f9bf7fb410 100644
--- a/sysdeps/unix/sysv/linux/i386/localplt.data
+++ b/sysdeps/unix/sysv/linux/i386/localplt.data
@@ -4,7 +4,6 @@  libc.so: _Unwind_Find_FDE + REL R_386_GLOB_DAT
 libc.so: calloc + REL R_386_GLOB_DAT
 libc.so: free + REL R_386_GLOB_DAT
 libc.so: malloc + REL R_386_GLOB_DAT
-libc.so: memalign + REL R_386_GLOB_DAT
 libc.so: realloc + REL R_386_GLOB_DAT
 libm.so: matherr + REL R_386_GLOB_DAT
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/unix/sysv/linux/ia64/localplt.data b/sysdeps/unix/sysv/linux/ia64/localplt.data
index 1c566a503e..174fb88128 100644
--- a/sysdeps/unix/sysv/linux/ia64/localplt.data
+++ b/sysdeps/unix/sysv/linux/ia64/localplt.data
@@ -1,7 +1,6 @@ 
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 libm.so: matherrf
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/localplt.data b/sysdeps/unix/sysv/linux/m68k/coldfire/localplt.data
index 3c5efb7204..42fa90508c 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/localplt.data
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/localplt.data
@@ -2,7 +2,6 @@  libc.so: __m68k_read_tp
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/localplt.data b/sysdeps/unix/sysv/linux/m68k/m680x0/localplt.data
index 843f4e25f2..34bd4c1aca 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/localplt.data
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/localplt.data
@@ -3,7 +3,6 @@  libc.so: __m68k_read_tp
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/unix/sysv/linux/microblaze/localplt.data b/sysdeps/unix/sysv/linux/microblaze/localplt.data
index 0e98d5251e..c3801314c9 100644
--- a/sysdeps/unix/sysv/linux/microblaze/localplt.data
+++ b/sysdeps/unix/sysv/linux/microblaze/localplt.data
@@ -2,7 +2,6 @@  libc.so: __errno_location
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The dynamic loader needs __tls_get_addr for TLS.
diff --git a/sysdeps/unix/sysv/linux/nios2/localplt.data b/sysdeps/unix/sysv/linux/nios2/localplt.data
index b37987c7c0..17fcfdd4db 100644
--- a/sysdeps/unix/sysv/linux/nios2/localplt.data
+++ b/sysdeps/unix/sysv/linux/nios2/localplt.data
@@ -6,7 +6,6 @@  libc.so: __gedf2
 libc.so: malloc
 libc.so: __gtsf2 ?
 libc.so: __nesf2
-libc.so: memalign
 libc.so: __mulsf3
 libc.so: __floatunsisf
 libc.so: __addsf3
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
index a02dd5cc24..c0af84eef7 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/localplt.data
@@ -2,7 +2,6 @@  libc.so: _Unwind_Find_FDE
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
index d8072597b7..581e54b95c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/localplt.data
@@ -30,7 +30,6 @@  libc.so: abort ?
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: memset ?
 libc.so: realloc
 libm.so: copysignl ?
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
index bb498fbe3a..d69b7ae646 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/localplt.data
@@ -1,7 +1,6 @@ 
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/unix/sysv/linux/riscv/localplt.data b/sysdeps/unix/sysv/linux/riscv/localplt.data
index 0a235592c3..e6d5330d5b 100644
--- a/sysdeps/unix/sysv/linux/riscv/localplt.data
+++ b/sysdeps/unix/sysv/linux/riscv/localplt.data
@@ -4,7 +4,6 @@ 
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: memset ?
 libc.so: realloc
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/unix/sysv/linux/s390/localplt.data b/sysdeps/unix/sysv/linux/s390/localplt.data
index a02dd5cc24..c0af84eef7 100644
--- a/sysdeps/unix/sysv/linux/s390/localplt.data
+++ b/sysdeps/unix/sysv/linux/s390/localplt.data
@@ -2,7 +2,6 @@  libc.so: _Unwind_Find_FDE
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/unix/sysv/linux/sh/localplt.data b/sysdeps/unix/sysv/linux/sh/localplt.data
index 3225177c50..6491b9e37b 100644
--- a/sysdeps/unix/sysv/linux/sh/localplt.data
+++ b/sysdeps/unix/sysv/linux/sh/localplt.data
@@ -4,7 +4,6 @@ 
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libc.so: _Unwind_Find_FDE
 libc.so: _exit
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data b/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
index be51efd566..38309a1393 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/localplt.data
@@ -16,7 +16,6 @@  libc.so: _Unwind_Find_FDE
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data b/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
index 809062d46c..6a216f3a5a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/localplt.data
@@ -15,7 +15,6 @@  libc.so: _Unwind_Find_FDE
 libc.so: calloc
 libc.so: free
 libc.so: malloc
-libc.so: memalign
 libc.so: realloc
 libm.so: matherr
 # The TLS-enabled version of these functions is interposed from libc.so.
diff --git a/sysdeps/x86_64/localplt.data b/sysdeps/x86_64/localplt.data
index 8f41e92870..d1f2e26612 100644
--- a/sysdeps/x86_64/localplt.data
+++ b/sysdeps/x86_64/localplt.data
@@ -6,7 +6,6 @@ 
 libc.so: calloc + RELA R_X86_64_GLOB_DAT
 libc.so: free + RELA R_X86_64_GLOB_DAT
 libc.so: malloc + RELA R_X86_64_GLOB_DAT
-libc.so: memalign + RELA R_X86_64_GLOB_DAT
 libc.so: realloc + RELA R_X86_64_GLOB_DAT
 libm.so: matherr + RELA R_X86_64_GLOB_DAT
 # The TLS-enabled version of these functions is interposed from libc.so.