|
|
8a8cfb |
commit e621246ec6393ea08ae50310f9d5e72500f8c9bc
|
|
|
8a8cfb |
Author: Carlos O'Donell <carlos@redhat.com>
|
|
|
8a8cfb |
Date: Mon Apr 8 17:35:05 2019 -0400
|
|
|
8a8cfb |
|
|
|
8a8cfb |
malloc: Set and reset all hooks for tracing (Bug 16573)
|
|
|
8a8cfb |
|
|
|
8a8cfb |
If an error occurs during the tracing operation, particularly during a
|
|
|
8a8cfb |
call to lock_and_info() which calls _dl_addr, we may end up calling back
|
|
|
8a8cfb |
into the malloc-subsystem and relock the loader lock and deadlock. For
|
|
|
8a8cfb |
all intents and purposes the call to _dl_addr can call any of the malloc
|
|
|
8a8cfb |
family API functions and so we should disable all tracing before calling
|
|
|
8a8cfb |
such loader functions. This is similar to the strategy that the new
|
|
|
8a8cfb |
malloc tracer takes when calling the real malloc, namely that all
|
|
|
8a8cfb |
tracing ceases at the boundary to the real function and any faults at
|
|
|
8a8cfb |
that point are the purvue of the library (though the new tracer does
|
|
|
8a8cfb |
this on a per-thread basis in an MT-safe fashion). Since the new tracer
|
|
|
8a8cfb |
and the hook deprecation are not yet complete we must fix these issues
|
|
|
8a8cfb |
where we can.
|
|
|
8a8cfb |
|
|
|
8a8cfb |
Tested on x86_64 with no regressions.
|
|
|
8a8cfb |
|
|
|
8a8cfb |
Co-authored-by: Kwok Cheung Yeung <kcy@codesourcery.com>
|
|
|
8a8cfb |
Reviewed-by: DJ Delorie <dj@redhat.com>
|
|
|
8a8cfb |
|
|
|
8a8cfb |
diff --git a/malloc/mtrace.c b/malloc/mtrace.c
|
|
|
8a8cfb |
index 9064f209ec3b24c6..546d37a26018bf41 100644
|
|
|
8a8cfb |
--- a/malloc/mtrace.c
|
|
|
8a8cfb |
+++ b/malloc/mtrace.c
|
|
|
8a8cfb |
@@ -121,6 +121,41 @@ lock_and_info (const void *caller, Dl_info *mem)
|
|
|
8a8cfb |
return res;
|
|
|
8a8cfb |
}
|
|
|
8a8cfb |
|
|
|
8a8cfb |
+static void tr_freehook (void *, const void *);
|
|
|
8a8cfb |
+static void * tr_mallochook (size_t, const void *);
|
|
|
8a8cfb |
+static void * tr_reallochook (void *, size_t, const void *);
|
|
|
8a8cfb |
+static void * tr_memalignhook (size_t, size_t, const void *);
|
|
|
8a8cfb |
+
|
|
|
8a8cfb |
+/* Set all the default non-trace hooks. */
|
|
|
8a8cfb |
+static __always_inline void
|
|
|
8a8cfb |
+set_default_hooks (void)
|
|
|
8a8cfb |
+{
|
|
|
8a8cfb |
+ __free_hook = tr_old_free_hook;
|
|
|
8a8cfb |
+ __malloc_hook = tr_old_malloc_hook;
|
|
|
8a8cfb |
+ __realloc_hook = tr_old_realloc_hook;
|
|
|
8a8cfb |
+ __memalign_hook = tr_old_memalign_hook;
|
|
|
8a8cfb |
+}
|
|
|
8a8cfb |
+
|
|
|
8a8cfb |
+/* Set all of the tracing hooks used for mtrace. */
|
|
|
8a8cfb |
+static __always_inline void
|
|
|
8a8cfb |
+set_trace_hooks (void)
|
|
|
8a8cfb |
+{
|
|
|
8a8cfb |
+ __free_hook = tr_freehook;
|
|
|
8a8cfb |
+ __malloc_hook = tr_mallochook;
|
|
|
8a8cfb |
+ __realloc_hook = tr_reallochook;
|
|
|
8a8cfb |
+ __memalign_hook = tr_memalignhook;
|
|
|
8a8cfb |
+}
|
|
|
8a8cfb |
+
|
|
|
8a8cfb |
+/* Save the current set of hooks as the default hooks. */
|
|
|
8a8cfb |
+static __always_inline void
|
|
|
8a8cfb |
+save_default_hooks (void)
|
|
|
8a8cfb |
+{
|
|
|
8a8cfb |
+ tr_old_free_hook = __free_hook;
|
|
|
8a8cfb |
+ tr_old_malloc_hook = __malloc_hook;
|
|
|
8a8cfb |
+ tr_old_realloc_hook = __realloc_hook;
|
|
|
8a8cfb |
+ tr_old_memalign_hook = __memalign_hook;
|
|
|
8a8cfb |
+}
|
|
|
8a8cfb |
+
|
|
|
8a8cfb |
static void
|
|
|
8a8cfb |
tr_freehook (void *ptr, const void *caller)
|
|
|
8a8cfb |
{
|
|
|
8a8cfb |
@@ -138,12 +173,12 @@ tr_freehook (void *ptr, const void *caller)
|
|
|
8a8cfb |
tr_break ();
|
|
|
8a8cfb |
__libc_lock_lock (lock);
|
|
|
8a8cfb |
}
|
|
|
8a8cfb |
- __free_hook = tr_old_free_hook;
|
|
|
8a8cfb |
+ set_default_hooks ();
|
|
|
8a8cfb |
if (tr_old_free_hook != NULL)
|
|
|
8a8cfb |
(*tr_old_free_hook)(ptr, caller);
|
|
|
8a8cfb |
else
|
|
|
8a8cfb |
free (ptr);
|
|
|
8a8cfb |
- __free_hook = tr_freehook;
|
|
|
8a8cfb |
+ set_trace_hooks ();
|
|
|
8a8cfb |
__libc_lock_unlock (lock);
|
|
|
8a8cfb |
}
|
|
|
8a8cfb |
|
|
|
8a8cfb |
@@ -155,12 +190,12 @@ tr_mallochook (size_t size, const void *caller)
|
|
|
8a8cfb |
Dl_info mem;
|
|
|
8a8cfb |
Dl_info *info = lock_and_info (caller, &mem;;
|
|
|
8a8cfb |
|
|
|
8a8cfb |
- __malloc_hook = tr_old_malloc_hook;
|
|
|
8a8cfb |
+ set_default_hooks ();
|
|
|
8a8cfb |
if (tr_old_malloc_hook != NULL)
|
|
|
8a8cfb |
hdr = (void *) (*tr_old_malloc_hook)(size, caller);
|
|
|
8a8cfb |
else
|
|
|
8a8cfb |
hdr = (void *) malloc (size);
|
|
|
8a8cfb |
- __malloc_hook = tr_mallochook;
|
|
|
8a8cfb |
+ set_trace_hooks ();
|
|
|
8a8cfb |
|
|
|
8a8cfb |
tr_where (caller, info);
|
|
|
8a8cfb |
/* We could be printing a NULL here; that's OK. */
|
|
|
8a8cfb |
@@ -185,16 +220,12 @@ tr_reallochook (void *ptr, size_t size, const void *caller)
|
|
|
8a8cfb |
Dl_info mem;
|
|
|
8a8cfb |
Dl_info *info = lock_and_info (caller, &mem;;
|
|
|
8a8cfb |
|
|
|
8a8cfb |
- __free_hook = tr_old_free_hook;
|
|
|
8a8cfb |
- __malloc_hook = tr_old_malloc_hook;
|
|
|
8a8cfb |
- __realloc_hook = tr_old_realloc_hook;
|
|
|
8a8cfb |
+ set_default_hooks ();
|
|
|
8a8cfb |
if (tr_old_realloc_hook != NULL)
|
|
|
8a8cfb |
hdr = (void *) (*tr_old_realloc_hook)(ptr, size, caller);
|
|
|
8a8cfb |
else
|
|
|
8a8cfb |
hdr = (void *) realloc (ptr, size);
|
|
|
8a8cfb |
- __free_hook = tr_freehook;
|
|
|
8a8cfb |
- __malloc_hook = tr_mallochook;
|
|
|
8a8cfb |
- __realloc_hook = tr_reallochook;
|
|
|
8a8cfb |
+ set_trace_hooks ();
|
|
|
8a8cfb |
|
|
|
8a8cfb |
tr_where (caller, info);
|
|
|
8a8cfb |
if (hdr == NULL)
|
|
|
8a8cfb |
@@ -230,14 +261,12 @@ tr_memalignhook (size_t alignment, size_t size, const void *caller)
|
|
|
8a8cfb |
Dl_info mem;
|
|
|
8a8cfb |
Dl_info *info = lock_and_info (caller, &mem;;
|
|
|
8a8cfb |
|
|
|
8a8cfb |
- __memalign_hook = tr_old_memalign_hook;
|
|
|
8a8cfb |
- __malloc_hook = tr_old_malloc_hook;
|
|
|
8a8cfb |
+ set_default_hooks ();
|
|
|
8a8cfb |
if (tr_old_memalign_hook != NULL)
|
|
|
8a8cfb |
hdr = (void *) (*tr_old_memalign_hook)(alignment, size, caller);
|
|
|
8a8cfb |
else
|
|
|
8a8cfb |
hdr = (void *) memalign (alignment, size);
|
|
|
8a8cfb |
- __memalign_hook = tr_memalignhook;
|
|
|
8a8cfb |
- __malloc_hook = tr_mallochook;
|
|
|
8a8cfb |
+ set_trace_hooks ();
|
|
|
8a8cfb |
|
|
|
8a8cfb |
tr_where (caller, info);
|
|
|
8a8cfb |
/* We could be printing a NULL here; that's OK. */
|
|
|
8a8cfb |
@@ -305,14 +334,8 @@ mtrace (void)
|
|
|
8a8cfb |
malloc_trace_buffer = mtb;
|
|
|
8a8cfb |
setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE);
|
|
|
8a8cfb |
fprintf (mallstream, "= Start\n");
|
|
|
8a8cfb |
- tr_old_free_hook = __free_hook;
|
|
|
8a8cfb |
- __free_hook = tr_freehook;
|
|
|
8a8cfb |
- tr_old_malloc_hook = __malloc_hook;
|
|
|
8a8cfb |
- __malloc_hook = tr_mallochook;
|
|
|
8a8cfb |
- tr_old_realloc_hook = __realloc_hook;
|
|
|
8a8cfb |
- __realloc_hook = tr_reallochook;
|
|
|
8a8cfb |
- tr_old_memalign_hook = __memalign_hook;
|
|
|
8a8cfb |
- __memalign_hook = tr_memalignhook;
|
|
|
8a8cfb |
+ save_default_hooks ();
|
|
|
8a8cfb |
+ set_trace_hooks ();
|
|
|
8a8cfb |
#ifdef _LIBC
|
|
|
8a8cfb |
if (!added_atexit_handler)
|
|
|
8a8cfb |
{
|
|
|
8a8cfb |
@@ -338,10 +361,7 @@ muntrace (void)
|
|
|
8a8cfb |
file. */
|
|
|
8a8cfb |
FILE *f = mallstream;
|
|
|
8a8cfb |
mallstream = NULL;
|
|
|
8a8cfb |
- __free_hook = tr_old_free_hook;
|
|
|
8a8cfb |
- __malloc_hook = tr_old_malloc_hook;
|
|
|
8a8cfb |
- __realloc_hook = tr_old_realloc_hook;
|
|
|
8a8cfb |
- __memalign_hook = tr_old_memalign_hook;
|
|
|
8a8cfb |
+ set_default_hooks ();
|
|
|
8a8cfb |
|
|
|
8a8cfb |
fprintf (f, "= End\n");
|
|
|
8a8cfb |
fclose (f);
|