[Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Thu Feb 25 00:56:23 UTC 2016
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207359
--- Comment #2 from Mark Millard <markmi at dsl-only.net> ---
I've finally traced the low level details of the _Unwind_RaiseException stuck
looping failure. . .
Starting from the observed low-level evidence based on observation via gdb and
such:
A backtrace while stopped during the unbounded looping is:
#0 uw_update_context (context=context at entry=0xffffffffffffccf0,
fs=fs at entry=0xffffffffffffc370) at
/usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind-dw2.c:1371
#1 0x00000000501cb95c in _Unwind_RaiseException (exc=0x50815058) at
/usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind.inc:126
#2 0x000000005016e3a0 in throw_exception (ex=0x50815000) at
/usr/src/lib/libcxxrt/../../contrib/libcxxrt/exception.cc:751
#3 0x0000000010000d50 in main () at exception_test.cpp:5
_Unwind_RaiseException never returns for source code that looks like:
#include <exception>
int main(void)
{
try { throw std::exception(); }
catch (std::exception& e) {}
return 0;
}
where in /usr/lib/libc++.so.1 there is:
736 static void throw_exception(__cxa_exception *ex)
737 {
. . .
751 _Unwind_Reason_Code err =
_Unwind_RaiseException(&ex->unwindHeader);
. . .
756 }
The unbounded loop in _Unwind_RaiseException is in the code:
85 _Unwind_Reason_Code
86 _Unwind_RaiseException(struct _Unwind_Exception *exc)
87 {
88 struct _Unwind_Context this_context, cur_context;
89 _Unwind_Reason_Code code;
90
91 /* Set up this_context to describe the current stack frame. */
92 uw_init_context (&this_context);
93 cur_context = this_context;
94
95 /* Phase 1: Search. Unwind the stack, calling the personality
routine
96 with the _UA_SEARCH_PHASE flag set. Do not modify the stack yet.
*/
97 while (1)
98 {
99 _Unwind_FrameState fs;
100
101 /* Set up fs to describe the FDE for the caller of cur_context.
The
102 first time through the loop, that means __cxa_throw. */
103 code = uw_frame_state_for (&cur_context, &fs);
. . .
125 /* Update cur_context to describe the same frame as fs. */
126 uw_update_context (&cur_context, &fs);
127 }
. . .
140 }
The uw_update_context call is doing the following before returning:
1367 /* Compute the return address now, since the return address column
1368 can change from frame to frame. */
1369 context->ra = __builtin_extract_return_addr
1370 (_Unwind_GetPtr (context, fs->retaddr_column));
with context->ra before and after the call both being 0x5016e3a0 . In fact it
was 0x5016e3a0 for the prior uw_frame_state_for call as well and continues to
be so each loop iteration once the problem starts.
As for the code around 0x5016e3a0:
0x5016e398 <throw_exception(__cxxabiv1::__cxa_exception*)+136>: stw
r10,48(r9)
0x5016e39c <throw_exception(__cxxabiv1::__cxa_exception*)+140>: bl
0x50162ae0 <00000017.plt_call._Unwind_RaiseException@@GCC_3.0>
0x5016e3a0 <throw_exception(__cxxabiv1::__cxa_exception*)+144>: ld
r2,40(r1)
0x5016e3a4 <throw_exception(__cxxabiv1::__cxa_exception*)+148>: addi
r1,r1,128
0x5016e3a8 <throw_exception(__cxxabiv1::__cxa_exception*)+152>: mr
r4,r31
0x5016e3ac <throw_exception(__cxxabiv1::__cxa_exception*)+156>: ld
r0,16(r1)
From /usr/local/bin/objdump for FreeBSD projects/clang380-import -r295902's
/usr/lib/libc++.so.1 for the same code (to match up with the .eh_frame dwarf
information presented later):
0000000000015398 <.__cxa_end_catch+0x4d8> stw r10,48(r9)
000000000001539c <.__cxa_end_catch+0x4dc> bl 0000000000009ae0
<CXXABI_1.3+0x9ae0>
00000000000153a0 <.__cxa_end_catch+0x4e0> ld r2,40(r1)
00000000000153a4 <.__cxa_end_catch+0x4e4> addi r1,r1,128
00000000000153a8 <.__cxa_end_catch+0x4e8> mr r4,r31
00000000000153ac <.__cxa_end_catch+0x4ec> ld r0,16(r1)
The code block above from 153a0 up to 153a8 is being given 153a0 as its "return
address" (context->ra) by uw_update_context via interpreting the dwarf
.eh_frame information. So once in that range there it never leaves that range.
The relevant dwarfdump output spanning that area is:
(Note that 153a0 up to 153a8 is part of the range that includes the bl to
_Unwind_RaiseException .)
< 0><0x00015310:0x000153dc><><fde offset 0x000010d8 length: 0x00000034><eh
aug data len 0x0>
0x00015310: <off cfa=00(r1) >
0x00015318: <off cfa=00(r1) > <off r31=-8(cfa) > <off r65=r0 >
0x00015324: <off cfa=128(r1) > <off r31=-8(cfa) > <off r65=16(cfa) >
0x00015368: <off cfa=00(r1) > <off r31=-8(cfa) > <off r65=16(cfa) >
0x00015378: <off cfa=00(r1) >
0x00015380: <off cfa=128(r1) > <off r31=-8(cfa) > <off r65=16(cfa) >
0x000153a8: <off cfa=00(r1) > <off r31=-8(cfa) > <off r65=16(cfa) >
0x000153b8: <off cfa=00(r1) >
0x000153c0: <off cfa=128(r1) > <off r31=-8(cfa) > <off r65=16(cfa) >
fde section offset 4312 0x000010d8 cie offset for fde: 4316 0x000010dc
0 DW_CFA_advance_loc 8 (2 * 4)
1 DW_CFA_register r65 = r0
4 DW_CFA_offset r31 -8 (1 * -8)
6 DW_CFA_advance_loc 12 (3 * 4)
7 DW_CFA_def_cfa_offset 128
10 DW_CFA_offset_extended_sf r65 16 (-2 * -8)
13 DW_CFA_advance_loc 68 (17 * 4)
14 DW_CFA_remember_state
15 DW_CFA_def_cfa_offset 0
17 DW_CFA_advance_loc 16 (4 * 4)
18 DW_CFA_restore_extended r65
20 DW_CFA_restore r31
21 DW_CFA_advance_loc 8 (2 * 4)
22 DW_CFA_restore_state
23 DW_CFA_advance_loc 40 (10 * 4)
24 DW_CFA_remember_state
25 DW_CFA_def_cfa_offset 0
27 DW_CFA_advance_loc 16 (4 * 4)
28 DW_CFA_restore_extended r65
30 DW_CFA_restore r31
31 DW_CFA_advance_loc 8 (2 * 4)
32 DW_CFA_restore_state
33 DW_CFA_nop
34 DW_CFA_nop
35 DW_CFA_nop
36 DW_CFA_nop
37 DW_CFA_nop
38 DW_CFA_nop
Note that the stack pointer manipulation (incrementing/popping) *after* the
return from the bl. 15339c, 153a0, and 153a4 should be 3 distinct contexts in
the .eh_frame information but are not:
000000000001539c <.__cxa_end_catch+0x4dc> bl 0000000000009ae0
<CXXABI_1.3+0x9ae0>
00000000000153a0 <.__cxa_end_catch+0x4e0> ld r2,40(r1)
00000000000153a4 <.__cxa_end_catch+0x4e4> addi r1,r1,128
So there is a missing step or more of frame-context tracking in the .eh_frame
information.
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the freebsd-bugs
mailing list