aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-05-14 10:46:17 -0400
committerUlrich Drepper <drepper@gmail.com>2011-05-14 10:46:17 -0400
commitd6f67f7d833b4e2039f832355fb0edd65522c9f4 (patch)
tree4c6f49bb0855978eb83a31b3d43134414a2ef621
parent0656e90edc091f122284b602d2d590314e40c97a (diff)
downloadglibc-d6f67f7d833b4e2039f832355fb0edd65522c9f4.tar
glibc-d6f67f7d833b4e2039f832355fb0edd65522c9f4.tar.gz
glibc-d6f67f7d833b4e2039f832355fb0edd65522c9f4.tar.bz2
glibc-d6f67f7d833b4e2039f832355fb0edd65522c9f4.zip
Handle recursive calls in backtrace better
-rw-r--r--ChangeLog7
-rw-r--r--NEWS12
-rw-r--r--sysdeps/ia64/backtrace.c27
3 files changed, 36 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 36a37087b1..43726ca8a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/NEWS b/NEWS
index 2fc193cf23..55932448e7 100644
--- a/NEWS
+++ b/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.
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);