Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Feb 2016 00:56:23 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 207359] projects/clang380-import for TARGET_ARCH=powerpc64 via powerpc64-gcc : c++ exceptions unbounded loop in _Unwind_RaiseException (9 line program)
Message-ID:  <bug-207359-8-Uacbi9tKNY@https.bugs.freebsd.org/bugzilla/>
In-Reply-To: <bug-207359-8@https.bugs.freebsd.org/bugzilla/>
References:  <bug-207359-8@https.bugs.freebsd.org/bugzilla/>

next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D207359

--- Comment #2 from Mark Millard <markmi@dsl-only.net> ---
I've finally traced the low level details of the _Unwind_RaiseException stu=
ck
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=3Dcontext@entry=3D0xffffffffffffccf0,
fs=3Dfs@entry=3D0xffffffffffffc370) at
/usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind-dw2.c:1371
#1  0x00000000501cb95c in _Unwind_RaiseException (exc=3D0x50815058) at
/usr/src/gnu/lib/libgcc/../../../contrib/gcc/unwind.inc:126
#2  0x000000005016e3a0 in throw_exception (ex=3D0x50815000) 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 =3D
_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=20=20=20=20=20=20
91        /* Set up this_context to describe the current stack frame.  */
92        uw_init_context (&this_context);
93        cur_context =3D this_context;
94=20=20=20=20=20=20
95        /* Phase 1: Search.  Unwind the stack, calling the personality
routine
96           with the _UA_SEARCH_PHASE flag set.  Do not modify the stack y=
et.=20
*/
97        while (1)
98          {
99            _Unwind_FrameState fs;
100=20=20=20=20=20
101           /* Set up fs to describe the FDE for the caller of cur_contex=
t.=20
The
102              first time through the loop, that means __cxa_throw.  */
103           code =3D 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 =3D __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=
=20=20=20=20
r10,48(r9)
   0x5016e39c <throw_exception(__cxxabiv1::__cxa_exception*)+140>:      bl=
=20=20=20=20=20
0x50162ae0 <00000017.plt_call._Unwind_RaiseException@@GCC_3.0>
   0x5016e3a0 <throw_exception(__cxxabiv1::__cxa_exception*)+144>:      ld=
=20=20=20=20=20
r2,40(r1)
   0x5016e3a4 <throw_exception(__cxxabiv1::__cxa_exception*)+148>:      add=
i=20=20=20
r1,r1,128
   0x5016e3a8 <throw_exception(__cxxabiv1::__cxa_exception*)+152>:      mr=
=20=20=20=20=20
r4,r31
   0x5016e3ac <throw_exception(__cxxabiv1::__cxa_exception*)+156>:      ld=
=20=20=20=20=20
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 "re=
turn
address" (context->ra) by uw_update_context via interpreting the dwarf
.eh_frame information. So once in that range there it never leaves that ran=
ge.

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=3D00(r1) >=20
        0x00015318: <off cfa=3D00(r1) > <off r31=3D-8(cfa) > <off r65=3Dr0 =
>=20
        0x00015324: <off cfa=3D128(r1) > <off r31=3D-8(cfa) > <off r65=3D16=
(cfa) >=20
        0x00015368: <off cfa=3D00(r1) > <off r31=3D-8(cfa) > <off r65=3D16(=
cfa) >=20
        0x00015378: <off cfa=3D00(r1) >=20
        0x00015380: <off cfa=3D128(r1) > <off r31=3D-8(cfa) > <off r65=3D16=
(cfa) >=20
        0x000153a8: <off cfa=3D00(r1) > <off r31=3D-8(cfa) > <off r65=3D16(=
cfa) >=20
        0x000153b8: <off cfa=3D00(r1) >=20
        0x000153c0: <off cfa=3D128(r1) > <off r31=3D-8(cfa) > <off r65=3D16=
(cfa) >=20
 fde section offset 4312 0x000010d8 cie offset for fde: 4316 0x000010dc
         0 DW_CFA_advance_loc 8  (2 * 4)
         1 DW_CFA_register r65 =3D 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_fra=
me
information.

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-207359-8-Uacbi9tKNY>