mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-05 19:35:52 +03:00
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:
10
ChangeLog
10
ChangeLog
@@ -1,5 +1,15 @@
|
|||||||
2011-05-16 Ulrich Drepper <drepper@gmail.com>
|
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
|
* malloc/mtrace.c: Remove support for USE_MTRACE_FILE. It is not
|
||||||
used and couldn't be at all thread-safe.
|
used and couldn't be at all thread-safe.
|
||||||
|
|
||||||
|
16
NEWS
16
NEWS
@@ -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.
|
Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc.
|
||||||
See the end for copying conditions.
|
See the end for copying conditions.
|
||||||
|
|
||||||
@@ -9,13 +9,13 @@ Version 2.14
|
|||||||
|
|
||||||
* The following bugs are resolved with this release:
|
* The following bugs are resolved with this release:
|
||||||
|
|
||||||
386, 7101, 9730, 9732, 9809, 10138, 10149, 10157, 11257, 11258, 11487,
|
386, 6420, 7101, 9730, 9732, 9809, 10138, 10149, 10157, 11257, 11258,
|
||||||
11532, 11578, 11653, 11668, 11724, 11901, 11945, 11947, 11952, 12052,
|
11487, 11532, 11578, 11653, 11668, 11724, 11901, 11945, 11947, 11952,
|
||||||
12083, 12158, 12178, 12200, 12346, 12393, 12420, 12432, 12445, 12449,
|
12052, 12083, 12158, 12178, 12200, 12346, 12393, 12420, 12432, 12445,
|
||||||
12453, 12454, 12460, 12469, 12489, 12509, 12510, 12511, 12518, 12527,
|
12449, 12453, 12454, 12460, 12469, 12489, 12509, 12510, 12511, 12518,
|
||||||
12541, 12545, 12551, 12582, 12583, 12587, 12597, 12601, 12611, 12625,
|
12527, 12541, 12545, 12551, 12582, 12583, 12587, 12597, 12601, 12611,
|
||||||
12626, 12631, 12650, 12653, 12655, 12660, 12681, 12685, 12711, 12713,
|
12625, 12626, 12631, 12650, 12653, 12655, 12660, 12681, 12685, 12711,
|
||||||
12714, 12717, 12723, 12724, 12734, 12738
|
12713, 12714, 12717, 12723, 12724, 12734, 12738
|
||||||
|
|
||||||
* The RPC implementation in libc is obsoleted. Old programs keep working
|
* The RPC implementation in libc is obsoleted. Old programs keep working
|
||||||
but new programs cannot be linked with the routines in libc anymore.
|
but new programs cannot be linked with the routines in libc anymore.
|
||||||
|
@@ -79,46 +79,59 @@ tr_break ()
|
|||||||
}
|
}
|
||||||
libc_hidden_def (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
|
static void
|
||||||
internal_function
|
internal_function
|
||||||
tr_where (caller)
|
tr_where (caller, info)
|
||||||
const __ptr_t caller;
|
const __ptr_t caller;
|
||||||
|
Dl_info *info;
|
||||||
{
|
{
|
||||||
if (caller != NULL)
|
if (caller != NULL)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_ELF
|
if (info != NULL)
|
||||||
Dl_info info;
|
|
||||||
if (_dl_addr (caller, &info, NULL, NULL))
|
|
||||||
{
|
{
|
||||||
char *buf = (char *) "";
|
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 = alloca (len + 6 + 2 * sizeof (void *));
|
||||||
|
|
||||||
buf[0] = '(';
|
buf[0] = '(';
|
||||||
__stpcpy (_fitoa (caller >= (const __ptr_t) info.dli_saddr
|
__stpcpy (_fitoa (caller >= (const __ptr_t) info->dli_saddr
|
||||||
? caller - (const __ptr_t) info.dli_saddr
|
? caller - (const __ptr_t) info->dli_saddr
|
||||||
: (const __ptr_t) info.dli_saddr - caller,
|
: (const __ptr_t) info->dli_saddr - caller,
|
||||||
__stpcpy (__mempcpy (buf + 1, info.dli_sname,
|
__stpcpy (__mempcpy (buf + 1, info->dli_sname,
|
||||||
len),
|
len),
|
||||||
caller >= (__ptr_t) info.dli_saddr
|
caller >= (__ptr_t) info->dli_saddr
|
||||||
? "+0x" : "-0x"),
|
? "+0x" : "-0x"),
|
||||||
16, 0),
|
16, 0),
|
||||||
")");
|
")");
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (mallstream, "@ %s%s%s[%p] ",
|
fprintf (mallstream, "@ %s%s%s[%p] ",
|
||||||
info.dli_fname ?: "", info.dli_fname ? ":" : "",
|
info->dli_fname ?: "", info->dli_fname ? ":" : "",
|
||||||
buf, caller);
|
buf, caller);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
fprintf (mallstream, "@ [%p] ", caller);
|
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_t, const __ptr_t) __THROW;
|
||||||
static void
|
static void
|
||||||
tr_freehook (ptr, caller)
|
tr_freehook (ptr, caller)
|
||||||
@@ -127,8 +140,10 @@ tr_freehook (ptr, caller)
|
|||||||
{
|
{
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return;
|
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. */
|
/* Be sure to print it first. */
|
||||||
fprintf (mallstream, "- %p\n", ptr);
|
fprintf (mallstream, "- %p\n", ptr);
|
||||||
__libc_lock_unlock (lock);
|
__libc_lock_unlock (lock);
|
||||||
@@ -152,7 +167,8 @@ tr_mallochook (size, caller)
|
|||||||
{
|
{
|
||||||
__ptr_t hdr;
|
__ptr_t hdr;
|
||||||
|
|
||||||
__libc_lock_lock (lock);
|
Dl_info mem;
|
||||||
|
Dl_info *info = lock_and_info (caller, &mem);
|
||||||
|
|
||||||
__malloc_hook = tr_old_malloc_hook;
|
__malloc_hook = tr_old_malloc_hook;
|
||||||
if (tr_old_malloc_hook != NULL)
|
if (tr_old_malloc_hook != NULL)
|
||||||
@@ -161,7 +177,7 @@ tr_mallochook (size, caller)
|
|||||||
hdr = (__ptr_t) malloc (size);
|
hdr = (__ptr_t) malloc (size);
|
||||||
__malloc_hook = tr_mallochook;
|
__malloc_hook = tr_mallochook;
|
||||||
|
|
||||||
tr_where (caller);
|
tr_where (caller, info);
|
||||||
/* We could be printing a NULL here; that's OK. */
|
/* We could be printing a NULL here; that's OK. */
|
||||||
fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
|
fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
|
||||||
|
|
||||||
@@ -186,7 +202,8 @@ tr_reallochook (ptr, size, caller)
|
|||||||
if (ptr == mallwatch)
|
if (ptr == mallwatch)
|
||||||
tr_break ();
|
tr_break ();
|
||||||
|
|
||||||
__libc_lock_lock (lock);
|
Dl_info mem;
|
||||||
|
Dl_info *info = lock_and_info (caller, &mem);
|
||||||
|
|
||||||
__free_hook = tr_old_free_hook;
|
__free_hook = tr_old_free_hook;
|
||||||
__malloc_hook = tr_old_malloc_hook;
|
__malloc_hook = tr_old_malloc_hook;
|
||||||
@@ -199,7 +216,7 @@ tr_reallochook (ptr, size, caller)
|
|||||||
__malloc_hook = tr_mallochook;
|
__malloc_hook = tr_mallochook;
|
||||||
__realloc_hook = tr_reallochook;
|
__realloc_hook = tr_reallochook;
|
||||||
|
|
||||||
tr_where (caller);
|
tr_where (caller, info);
|
||||||
if (hdr == NULL)
|
if (hdr == NULL)
|
||||||
/* Failed realloc. */
|
/* Failed realloc. */
|
||||||
fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long int) size);
|
fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long int) size);
|
||||||
@@ -208,7 +225,7 @@ tr_reallochook (ptr, size, caller)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf (mallstream, "< %p\n", ptr);
|
fprintf (mallstream, "< %p\n", ptr);
|
||||||
tr_where (caller);
|
tr_where (caller, info);
|
||||||
fprintf (mallstream, "> %p %#lx\n", hdr, (unsigned long int) size);
|
fprintf (mallstream, "> %p %#lx\n", hdr, (unsigned long int) size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +246,8 @@ tr_memalignhook (alignment, size, caller)
|
|||||||
{
|
{
|
||||||
__ptr_t hdr;
|
__ptr_t hdr;
|
||||||
|
|
||||||
__libc_lock_lock (lock);
|
Dl_info mem;
|
||||||
|
Dl_info *info = lock_and_info (caller, &mem);
|
||||||
|
|
||||||
__memalign_hook = tr_old_memalign_hook;
|
__memalign_hook = tr_old_memalign_hook;
|
||||||
__malloc_hook = tr_old_malloc_hook;
|
__malloc_hook = tr_old_malloc_hook;
|
||||||
@@ -240,7 +258,7 @@ tr_memalignhook (alignment, size, caller)
|
|||||||
__memalign_hook = tr_memalignhook;
|
__memalign_hook = tr_memalignhook;
|
||||||
__malloc_hook = tr_mallochook;
|
__malloc_hook = tr_mallochook;
|
||||||
|
|
||||||
tr_where (caller);
|
tr_where (caller, info);
|
||||||
/* We could be printing a NULL here; that's OK. */
|
/* We could be printing a NULL here; that's OK. */
|
||||||
fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
|
fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long int) size);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user