Avoid potential deadlock in mtrace

The _dl_addr function might have to call malloc which would lead
to a deadlock.  Avoid by calling _dl_addr early.
This commit is contained in:
Ulrich Drepper 2011-05-16 00:58:33 -04:00
parent 6ce7537960
commit 56e5eb4619
3 changed files with 59 additions and 31 deletions

View File

@ -1,5 +1,15 @@
2011-05-16 Ulrich Drepper <drepper@gmail.com>
[BZ #6420]
* malloc/mtrace.c (tr_where): Add additional parameter to point to
symbol info. Use it instead of calling _dl_addr locally.
(lock_and_info): New function.
(tr_freehook): Call lock_and_info and pass symbol info as additional
parameter to tr_where.
(tr_mallochook): Likewise.
(tr_reallochook): Likewise.
(tr_memalignhook): Likewise.
* malloc/mtrace.c: Remove support for USE_MTRACE_FILE. It is not
used and couldn't be at all thread-safe.

16
NEWS
View File

@ -1,4 +1,4 @@
GNU C Library NEWS -- history of user-visible changes. 2011-5-15
GNU C Library NEWS -- history of user-visible changes. 2011-5-16
Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc.
See the end for copying conditions.
@ -9,13 +9,13 @@ Version 2.14
* The following bugs are resolved with this release:
386, 7101, 9730, 9732, 9809, 10138, 10149, 10157, 11257, 11258, 11487,
11532, 11578, 11653, 11668, 11724, 11901, 11945, 11947, 11952, 12052,
12083, 12158, 12178, 12200, 12346, 12393, 12420, 12432, 12445, 12449,
12453, 12454, 12460, 12469, 12489, 12509, 12510, 12511, 12518, 12527,
12541, 12545, 12551, 12582, 12583, 12587, 12597, 12601, 12611, 12625,
12626, 12631, 12650, 12653, 12655, 12660, 12681, 12685, 12711, 12713,
12714, 12717, 12723, 12724, 12734, 12738
386, 6420, 7101, 9730, 9732, 9809, 10138, 10149, 10157, 11257, 11258,
11487, 11532, 11578, 11653, 11668, 11724, 11901, 11945, 11947, 11952,
12052, 12083, 12158, 12178, 12200, 12346, 12393, 12420, 12432, 12445,
12449, 12453, 12454, 12460, 12469, 12489, 12509, 12510, 12511, 12518,
12527, 12541, 12545, 12551, 12582, 12583, 12587, 12597, 12601, 12611,
12625, 12626, 12631, 12650, 12653, 12655, 12660, 12681, 12685, 12711,
12713, 12714, 12717, 12723, 12724, 12734, 12738
* The RPC implementation in libc is obsoleted. Old programs keep working
but new programs cannot be linked with the routines in libc anymore.

View File

@ -79,46 +79,59 @@ tr_break ()
}
libc_hidden_def (tr_break)
static void tr_where (const __ptr_t) __THROW internal_function;
static void tr_where (const __ptr_t, Dl_info *) __THROW internal_function;
static void
internal_function
tr_where (caller)
tr_where (caller, info)
const __ptr_t caller;
Dl_info *info;
{
if (caller != NULL)
{
#ifdef HAVE_ELF
Dl_info info;
if (_dl_addr (caller, &info, NULL, NULL))
if (info != NULL)
{
char *buf = (char *) "";
if (info.dli_sname != NULL)
if (info->dli_sname != NULL)
{
size_t len = strlen (info.dli_sname);
size_t len = strlen (info->dli_sname);
buf = alloca (len + 6 + 2 * sizeof (void *));
buf[0] = '(';
__stpcpy (_fitoa (caller >= (const __ptr_t) info.dli_saddr
? caller - (const __ptr_t) info.dli_saddr
: (const __ptr_t) info.dli_saddr - caller,
__stpcpy (__mempcpy (buf + 1, info.dli_sname,
__stpcpy (_fitoa (caller >= (const __ptr_t) info->dli_saddr
? caller - (const __ptr_t) info->dli_saddr
: (const __ptr_t) info->dli_saddr - caller,
__stpcpy (__mempcpy (buf + 1, info->dli_sname,
len),
caller >= (__ptr_t) info.dli_saddr
caller >= (__ptr_t) info->dli_saddr
? "+0x" : "-0x"),
16, 0),
")");
}
fprintf (mallstream, "@ %s%s%s[%p] ",
info.dli_fname ?: "", info.dli_fname ? ":" : "",
info->dli_fname ?: "", info->dli_fname ? ":" : "",
buf, caller);
}
else
#endif
fprintf (mallstream, "@ [%p] ", caller);
}
}
static Dl_info *
lock_and_info (const __ptr_t 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 (__ptr_t, const __ptr_t) __THROW;
static void
tr_freehook (ptr, caller)
@ -127,8 +140,10 @@ tr_freehook (ptr, caller)
{
if (ptr == NULL)
return;
__libc_lock_lock (lock);
tr_where (caller);
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);
__libc_lock_unlock (lock);
@ -152,7 +167,8 @@ tr_mallochook (size, caller)
{
__ptr_t hdr;
__libc_lock_lock (lock);
Dl_info mem;
Dl_info *info = lock_and_info (caller, &mem);
__malloc_hook = tr_old_malloc_hook;
if (tr_old_malloc_hook != NULL)
@ -161,7 +177,7 @@ tr_mallochook (size, caller)
hdr = (__ptr_t) malloc (size);
__malloc_hook = tr_mallochook;
tr_where (caller);
tr_where (caller, info);
/* We could be printing a NULL here; that's OK. */
fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
@ -186,7 +202,8 @@ tr_reallochook (ptr, size, caller)
if (ptr == mallwatch)
tr_break ();
__libc_lock_lock (lock);
Dl_info mem;
Dl_info *info = lock_and_info (caller, &mem);
__free_hook = tr_old_free_hook;
__malloc_hook = tr_old_malloc_hook;
@ -199,7 +216,7 @@ tr_reallochook (ptr, size, caller)
__malloc_hook = tr_mallochook;
__realloc_hook = tr_reallochook;
tr_where (caller);
tr_where (caller, info);
if (hdr == NULL)
/* Failed realloc. */
fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long int) size);
@ -208,7 +225,7 @@ tr_reallochook (ptr, size, caller)
else
{
fprintf (mallstream, "< %p\n", ptr);
tr_where (caller);
tr_where (caller, info);
fprintf (mallstream, "> %p %#lx\n", hdr, (unsigned long int) size);
}
@ -229,7 +246,8 @@ tr_memalignhook (alignment, size, caller)
{
__ptr_t hdr;
__libc_lock_lock (lock);
Dl_info mem;
Dl_info *info = lock_and_info (caller, &mem);
__memalign_hook = tr_old_memalign_hook;
__malloc_hook = tr_old_malloc_hook;
@ -240,7 +258,7 @@ tr_memalignhook (alignment, size, caller)
__memalign_hook = tr_memalignhook;
__malloc_hook = tr_mallochook;
tr_where (caller);
tr_where (caller, info);
/* We could be printing a NULL here; that's OK. */
fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);