diff options
author | Ulrich Drepper <drepper@gmail.com> | 2011-05-14 10:46:17 -0400 |
---|---|---|
committer | Ulrich Drepper <drepper@gmail.com> | 2011-05-14 10:46:17 -0400 |
commit | d6f67f7d833b4e2039f832355fb0edd65522c9f4 (patch) | |
tree | 4c6f49bb0855978eb83a31b3d43134414a2ef621 | |
parent | 0656e90edc091f122284b602d2d590314e40c97a (diff) | |
download | glibc-d6f67f7d833b4e2039f832355fb0edd65522c9f4.tar glibc-d6f67f7d833b4e2039f832355fb0edd65522c9f4.tar.gz glibc-d6f67f7d833b4e2039f832355fb0edd65522c9f4.tar.bz2 glibc-d6f67f7d833b4e2039f832355fb0edd65522c9f4.zip |
Handle recursive calls in backtrace better
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | NEWS | 12 | ||||
-rw-r--r-- | sysdeps/ia64/backtrace.c | 27 |
3 files changed, 36 insertions, 10 deletions
@@ -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. @@ -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. diff --git a/sysdeps/ia64/backtrace.c b/sysdeps/ia64/backtrace.c index 5cefb86ae4..d4ff291022 100644 --- a/sysdeps/ia64/backtrace.c +++ b/sysdeps/ia64/backtrace.c @@ -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); |