]>
Commit | Line | Data |
---|---|---|
bb330e25 AF |
1 | From d6f67f7d833b4e2039f832355fb0edd65522c9f4 Mon Sep 17 00:00:00 2001 |
2 | From: Ulrich Drepper <drepper@gmail.com> | |
3 | Date: Sat, 14 May 2011 10:46:17 -0400 | |
4 | Subject: [PATCH] Handle recursive calls in backtrace better | |
5 | ||
6 | --- | |
7 | ChangeLog | 7 +++++++ | |
8 | NEWS | 12 ++++++------ | |
9 | sysdeps/ia64/backtrace.c | 27 +++++++++++++++++++++++---- | |
10 | 3 files changed, 36 insertions(+), 10 deletions(-) | |
11 | ||
12 | 2011-05-14 Ulrich Drepper <drepper@gmail.com> | |
13 | ||
14 | [BZ #12432] | |
15 | * sysdeps/ia64/backtrace.c (struct trace_reg): Add cfa element. | |
16 | (dummy_getcfa): New function. | |
17 | (init): Get _Unwind_GetCFA address, use dummy if not found. | |
18 | (backtrace_helper): In recursion check, also check whether CFA changes. | |
19 | (__backtrace): Completely initialize arg. | |
20 | ||
21 | diff --git a/sysdeps/ia64/backtrace.c b/sysdeps/ia64/backtrace.c | |
22 | index 5cefb86..d4ff291 100644 | |
23 | --- a/sysdeps/ia64/backtrace.c | |
24 | +++ b/sysdeps/ia64/backtrace.c | |
25 | @@ -1,5 +1,5 @@ | |
26 | /* Return backtrace of current program state. | |
27 | - Copyright (C) 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc. | |
28 | + Copyright (C) 2003-2005, 2007, 2009, 2011 Free Software Foundation, Inc. | |
29 | This file is part of the GNU C Library. | |
30 | Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. | |
31 | ||
32 | @@ -27,14 +27,26 @@ | |
33 | struct trace_arg | |
34 | { | |
35 | void **array; | |
36 | - int cnt, size; | |
37 | + _Unwind_Word cfa; | |
38 | + int cnt; | |
39 | + int size; | |
40 | }; | |
41 | ||
42 | #ifdef SHARED | |
43 | static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *); | |
44 | static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *); | |
45 | +static _Unwind_Word (*unwind_getcfa) (struct _Unwind_Context *); | |
46 | static void *libgcc_handle; | |
47 | ||
48 | + | |
49 | +/* Dummy version in case libgcc_s does not contain the real code. */ | |
50 | +static _Unwind_Word | |
51 | +dummy_getcfa (struct _Unwind_Context *ctx __attribute__ ((unused))) | |
52 | +{ | |
53 | + return 0; | |
54 | +} | |
55 | + | |
56 | + | |
57 | static void | |
58 | init (void) | |
59 | { | |
60 | @@ -47,10 +59,13 @@ init (void) | |
61 | unwind_getip = __libc_dlsym (libgcc_handle, "_Unwind_GetIP"); | |
62 | if (unwind_getip == NULL) | |
63 | unwind_backtrace = NULL; | |
64 | + unwind_getcfa = (__libc_dlsym (libgcc_handle, "_Unwind_GetCFA") | |
65 | + ?: dummy_getcfa); | |
66 | } | |
67 | #else | |
68 | # define unwind_backtrace _Unwind_Backtrace | |
69 | # define unwind_getip _Unwind_GetIP | |
70 | +# define unwind_getcfa _Unwind_GetCFA | |
71 | #endif | |
72 | ||
73 | static _Unwind_Reason_Code | |
74 | @@ -65,8 +80,12 @@ backtrace_helper (struct _Unwind_Context *ctx, void *a) | |
75 | arg->array[arg->cnt] = (void *) unwind_getip (ctx); | |
76 | ||
77 | /* Check whether we make any progress. */ | |
78 | - if (arg->cnt > 0 && arg->array[arg->cnt - 1] == arg->array[arg->cnt]) | |
79 | + _Unwind_Word cfa = unwind_getcfa (ctx); | |
80 | + | |
81 | + if (arg->cnt > 0 && arg->array[arg->cnt - 1] == arg->array[arg->cnt] | |
82 | + && cfa == arg->cfa) | |
83 | return _URC_END_OF_STACK; | |
84 | + arg->cfa = cfa; | |
85 | } | |
86 | if (++arg->cnt == arg->size) | |
87 | return _URC_END_OF_STACK; | |
88 | @@ -78,7 +97,7 @@ __backtrace (array, size) | |
89 | void **array; | |
90 | int size; | |
91 | { | |
92 | - struct trace_arg arg = { .array = array, .size = size, .cnt = -1 }; | |
93 | + struct trace_arg arg = { .array = array, .cfa = 0, .size = size, .cnt = -1 }; | |
94 | #ifdef SHARED | |
95 | __libc_once_define (static, once); | |
96 | ||
97 | -- | |
98 | 1.7.1 | |
99 |