Date: Wed, 24 Feb 2016 20:46:47 -0800 From: Mark Millard <markmi@dsl-only.net> To: FreeBSD PowerPC ML <freebsd-ppc@freebsd.org>, FreeBSD Toolchain <freebsd-toolchain@freebsd.org> Cc: Andreas Tobler <andreast-list@fgznet.ch>, Konstantin Belousov <kostikbel@gmail.com>, Baptiste Daroussin <bapt@FreeBSD.org> Subject: r207471 submitted against devel/powerpc64-gcc for _Unwind_RaiseException's internal unbounded looping; matching up with 207359 against base system Message-ID: <38D884F8-0EB4-4F3E-9475-7465FE173D79@dsl-only.net>
next in thread | raw e-mail | index | archive | help
> #include <exception> >=20 > int main(void) > { > try { throw std::exception(); } > catch (std::exception& e) {} // same result without & > return 0; > } compiled under devel/powerpc64-gcc (gcc 5.3 based) on a FreeBSD = projects/clang380-import (-r295902, for example) that was also built = (buildworld/buildkernel) with the same devel/powerpc64-gcc demonstrates: _Unwind_RaiseException never returns because it is stuck in a unbounded = loop. [clang380-import vs. 11.0-CURRENT is not likely to be a big distinction = here. PowerPC64 might be or might not be relative to g++ 5.3 .] The cause has been tracked down to incomplete (and so inaccurate) = .eh_frame information as shown below. I use a mix of . . . # /usr/local/bin/objdump -d --prefix-addresses libcxxrt.so.1.full output and the matching . . . # dwarfdump -v -v -F libcxxrt.so.1.full | more output to show this. 0000000000015350 <.__cxa_end_catch+0x490> addi r3,r31,88 0000000000015354 <.__cxa_end_catch+0x494> addi r10,r10,1 0000000000015358 <.__cxa_end_catch+0x498> stw r10,48(r9) 000000000001535c <.__cxa_end_catch+0x49c> bl 0000000000009ae0 = <00000017.plt_call._Unwind_RaiseException@@GCC_3.0> 0000000000015360 <.__cxa_end_catch+0x4a0> ld r2,40(r1) 0000000000015364 <.__cxa_end_catch+0x4a4> addi r1,r1,128 0000000000015368 <.__cxa_end_catch+0x4a8> mr r4,r31 vs. < 0><0x00015050:0x00015310><report_failure><fde offset 0x000010a8 = length: 0x0000002c><eh aug data len 0x0> 0x00015050: <off cfa=3D00(r1) >=20 0x0001506c: <off cfa=3D176(r1) > <off r28=3D-32(cfa) > <off = r29=3D-24(cfa) > <off r30=3D-16(cfa) > <off r31=3D-8(cfa) > <off = r65=3D16(cfa) >=20 0x000150b8: <off cfa=3D00(r1) > <off r28=3D-32(cfa) > <off = r29=3D-24(cfa) > <off r30=3D-16(cfa) > <off r31=3D-8(cfa) > <off = r65=3D16(cfa) >=20 0x000150d0: <off cfa=3D00(r1) >=20 0x000150e0: <off cfa=3D176(r1) > <off r28=3D-32(cfa) > <off = r29=3D-24(cfa) > <off r30=3D-16(cfa) > <off r31=3D-8(cfa) > <off = r65=3D16(cfa) >=20 Of note here is that the return "address" from the bl context is = correctly identified as 0000000000015360 by the .eh_frame information = and its interpretation. But also of note there is that 0000000000015360 and 0000000000015364 = also are identified as having 0000000000015360 as their return address = (part of the same block of code as the bl as things are classified = above). (That is what the live code actually generates, up to relocation = issues changing addresses.) So when _Unwind_RaiseException attempts to walk up the stack from itself = for the first pass up the stack it gets to 0000000000015360. And from there it gets to 0000000000015360 and loops. And from there it gets to 0000000000015360 and loops. And from there it gets to 0000000000015360 and loops. And from there it gets to 0000000000015360 and loops. . . . This code/.eh_frame pattern occurs again a little later (and this is = where the original problem was observed for this low-level-detail view). = . . 0000000000015380 <.__cxa_end_catch+0x4c0> addis r8,r2,-1 0000000000015384 <.__cxa_end_catch+0x4c4> addi r3,r31,88 0000000000015388 <.__cxa_end_catch+0x4c8> ld r10,28144(r8) 000000000001538c <.__cxa_end_catch+0x4cc> std r10,32(r31) 0000000000015390 <.__cxa_end_catch+0x4d0> lwz r10,48(r9) 0000000000015394 <.__cxa_end_catch+0x4d4> addi r10,r10,1 0000000000015398 <.__cxa_end_catch+0x4d8> stw r10,48(r9) 000000000001539c <.__cxa_end_catch+0x4dc> bl 0000000000009ae0 = <00000017.plt_call._Unwind_RaiseException@@GCC_3.0> 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) vs. < 0><0x00015310:0x000153dc><throw_exception><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 This leads to (during _Unwind_RaiseException's loop): . . . And from there it gets to 00000000000153a0 and loops. And from there it gets to 00000000000153a0 and loops. And from there it gets to 00000000000153a0 and loops. And from there it gets to 00000000000153a0 and loops. . . . 0000000000015360 and 00000000000153a0 should each be starts of new = code-block ranges for identifying a different return address. So C++ exception handling is broken for FreeBSD when buildworld is based = on devel/powerpc65-gcc: libcxxrt has examples of the error in it. I'd expect that gcc5 (5.3) has other contexts where it does not get the = correct return address via its .eh_frame generated materials, at least = for powerpc64. [207359 might be considered replaced by 207471.] =3D=3D=3D Mark Millard markmi at dsl-only.net
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?38D884F8-0EB4-4F3E-9475-7465FE173D79>