mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
Handle recursive calls in backtrace better
This commit is contained in:
parent
0656e90edc
commit
d6f67f7d83
@ -1,5 +1,12 @@
|
||||
2011-05-14 Ulrich Drepper <drepper@gmail.com>
|
||||
|
||||
[BZ #12432]
|
||||
* sysdeps/ia64/backtrace.c (struct trace_reg): Add cfa element.
|
||||
(dummy_getcfa): New function.
|
||||
(init): Get _Unwind_GetCFA address, use dummy if not found.
|
||||
(backtrace_helper): In recursion check, also check whether CFA changes.
|
||||
(__backtrace): Completely initialize arg.
|
||||
|
||||
* iconv/loop.c (SINGLE) [STORE_REST]: Add input bytes to bytebuf before
|
||||
storing incomplete byte sequence in state object. Avoid testing for
|
||||
guaranteed too small input if we know there is enough data available.
|
||||
|
12
NEWS
12
NEWS
@ -1,4 +1,4 @@
|
||||
GNU C Library NEWS -- history of user-visible changes. 2011-5-13
|
||||
GNU C Library NEWS -- history of user-visible changes. 2011-5-14
|
||||
Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
See the end for copying conditions.
|
||||
|
||||
@ -10,11 +10,11 @@ Version 2.14
|
||||
* The following bugs are resolved with this release:
|
||||
|
||||
386, 11257, 11258, 11487, 11532, 11578, 11653, 11668, 11724, 11945, 11947,
|
||||
12052, 12158, 12178, 12200, 12346, 12393, 12420, 12445, 12449, 12454,
|
||||
12460, 12469, 12489, 12509, 12510, 12511, 12518, 12527, 12541, 12545,
|
||||
12551, 12583, 12587, 12597, 12611, 12625, 12631, 12650, 12653, 12655,
|
||||
12660, 12681, 12685, 12711, 12713, 12714, 12717, 12723, 12724, 12734,
|
||||
12738
|
||||
12052, 12158, 12178, 12200, 12346, 12393, 12420, 12432, 12445, 12449,
|
||||
12454, 12460, 12469, 12489, 12509, 12510, 12511, 12518, 12527, 12541,
|
||||
12545, 12551, 12583, 12587, 12597, 12611, 12625, 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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Return backtrace of current program state.
|
||||
Copyright (C) 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003-2005, 2007, 2009, 2011 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||
|
||||
@ -27,14 +27,26 @@
|
||||
struct trace_arg
|
||||
{
|
||||
void **array;
|
||||
int cnt, size;
|
||||
_Unwind_Word cfa;
|
||||
int cnt;
|
||||
int size;
|
||||
};
|
||||
|
||||
#ifdef SHARED
|
||||
static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *);
|
||||
static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *);
|
||||
static _Unwind_Word (*unwind_getcfa) (struct _Unwind_Context *);
|
||||
static void *libgcc_handle;
|
||||
|
||||
|
||||
/* Dummy version in case libgcc_s does not contain the real code. */
|
||||
static _Unwind_Word
|
||||
dummy_getcfa (struct _Unwind_Context *ctx __attribute__ ((unused)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init (void)
|
||||
{
|
||||
@ -47,10 +59,13 @@ init (void)
|
||||
unwind_getip = __libc_dlsym (libgcc_handle, "_Unwind_GetIP");
|
||||
if (unwind_getip == NULL)
|
||||
unwind_backtrace = NULL;
|
||||
unwind_getcfa = (__libc_dlsym (libgcc_handle, "_Unwind_GetCFA")
|
||||
?: dummy_getcfa);
|
||||
}
|
||||
#else
|
||||
# define unwind_backtrace _Unwind_Backtrace
|
||||
# define unwind_getip _Unwind_GetIP
|
||||
# define unwind_getcfa _Unwind_GetCFA
|
||||
#endif
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
@ -65,8 +80,12 @@ backtrace_helper (struct _Unwind_Context *ctx, void *a)
|
||||
arg->array[arg->cnt] = (void *) unwind_getip (ctx);
|
||||
|
||||
/* Check whether we make any progress. */
|
||||
if (arg->cnt > 0 && arg->array[arg->cnt - 1] == arg->array[arg->cnt])
|
||||
_Unwind_Word cfa = unwind_getcfa (ctx);
|
||||
|
||||
if (arg->cnt > 0 && arg->array[arg->cnt - 1] == arg->array[arg->cnt]
|
||||
&& cfa == arg->cfa)
|
||||
return _URC_END_OF_STACK;
|
||||
arg->cfa = cfa;
|
||||
}
|
||||
if (++arg->cnt == arg->size)
|
||||
return _URC_END_OF_STACK;
|
||||
@ -78,7 +97,7 @@ __backtrace (array, size)
|
||||
void **array;
|
||||
int size;
|
||||
{
|
||||
struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };
|
||||
struct trace_arg arg = { .array = array, .cfa = 0, .size = size, .cnt = -1 };
|
||||
#ifdef SHARED
|
||||
__libc_once_define (static, once);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user