From owner-freebsd-ppc@freebsd.org Thu Feb 25 01:53:06 2016 Return-Path: Delivered-To: freebsd-ppc@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 808F8AB2E52 for ; Thu, 25 Feb 2016 01:53:06 +0000 (UTC) (envelope-from markmi@dsl-only.net) Received: from asp.reflexion.net (outbound-mail-211-156.reflexion.net [208.70.211.156]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4470F1A7 for ; Thu, 25 Feb 2016 01:53:05 +0000 (UTC) (envelope-from markmi@dsl-only.net) Received: (qmail 28369 invoked from network); 25 Feb 2016 01:53:02 -0000 Received: from unknown (HELO mail-cs-02.app.dca.reflexion.local) (10.81.19.2) by 0 (rfx-qmail) with SMTP; 25 Feb 2016 01:53:02 -0000 Received: by mail-cs-02.app.dca.reflexion.local (Reflexion email security v7.80.0) with SMTP; Wed, 24 Feb 2016 20:52:58 -0500 (EST) Received: (qmail 25827 invoked from network); 25 Feb 2016 01:52:57 -0000 Received: from unknown (HELO iron2.pdx.net) (69.64.224.71) by 0 (rfx-qmail) with SMTP; 25 Feb 2016 01:52:57 -0000 X-No-Relay: not in my network X-No-Relay: not in my network X-No-Relay: not in my network X-No-Relay: not in my network Received: from [192.168.1.8] (c-76-115-7-162.hsd1.or.comcast.net [76.115.7.162]) by iron2.pdx.net (Postfix) with ESMTPSA id C82371C43AE; Wed, 24 Feb 2016 17:52:58 -0800 (PST) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) Subject: Re: projects/clang380-import for TARGET_ARCH=powerpc64: /lib/libgcc_s.so.1 is incompatible with using the pair: /usr/lib/libc++.so.1 and /lib/libcxxrt.so.1 for C++ exception handling From: Mark Millard In-Reply-To: Date: Wed, 24 Feb 2016 17:53:03 -0800 Cc: Roman Divacky , Dimitry Andric Content-Transfer-Encoding: quoted-printable Message-Id: <440081D9-83A0-44B8-B209-C50DB4B52885@dsl-only.net> References: <5B9137BF-0E86-4C4B-A3FB-18F444A850AC@dsl-only.net> To: FreeBSD PowerPC ML , FreeBSD Toolchain X-Mailer: Apple Mail (2.2104) X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Feb 2016 01:53:06 -0000 [In part: My references to libc++ should have been to libcxxrt. Also: = devel/powerpc64-gcc produced the incomplete .eh_frame information.] On 2016-Feb-24, at 5:07 PM, Mark Millard wrote: >=20 > [Deliberate top posting an history removal for significant new = information.] >=20 > I've finally traced the low level details of the powerpc64 = _Unwind_RaiseException stuck looping failure. What I've submitted into = the defect is basically that for clang 3.8.0's .eh_frame information = generation in libcxxrt's code there is an error in the form of an = incompleteness. . . >=20 >=20 > Starting from the observed low-level evidence based on observation via = gdb and such: >=20 > A backtrace while stopped during the unbounded looping is: >=20 >> #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 >=20 > _Unwind_RaiseException never returns for source code that looks like: >=20 >> #include >>=20 >> int main(void) >> { >> try { throw std::exception(); } >> catch (std::exception& e) {} >> return 0; >> } >=20 > where in /usr/lib/libc++.so.1 there is: >=20 >> 736 static void throw_exception(__cxa_exception *ex) >> 737 { >> . . . >> 751 _Unwind_Reason_Code err =3D = _Unwind_RaiseException(&ex->unwindHeader); >> . . . >> 756 } >=20 > The unbounded loop in _Unwind_RaiseException is in the code: >=20 >> 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=09 >> 91 /* Set up this_context to describe the current stack frame. = */ >> 92 uw_init_context (&this_context); >> 93 cur_context =3D this_context; >> 94=09 >> 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=09 >> 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 =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 } >=20 > The uw_update_context call is doing the following before returning: >=20 >> 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)); >=20 > 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. >=20 > As for the code around 0x5016e3a0: >=20 >> 0x5016e398 : = stw r10,48(r9) >> 0x5016e39c : = bl 0x50162ae0 <00000017.plt_call._Unwind_RaiseException@@GCC_3.0> >> 0x5016e3a0 : = ld r2,40(r1) >> 0x5016e3a4 : = addi r1,r1,128 >> 0x5016e3a8 : = mr r4,r31 >> 0x5016e3ac : = ld r0,16(r1) >=20 > =46rom /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): >=20 >> 0000000000015398 <.__cxa_end_catch+0x4d8> stw r10,48(r9) >> 000000000001539c <.__cxa_end_catch+0x4dc> bl 0000000000009ae0 = >> 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) >=20 > 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. >=20 > 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 .) >=20 >> < 0><0x00015310:0x000153dc><> >> 0x00015310: =20 >> 0x00015318: =20 >> 0x00015324: =20 >> 0x00015368: =20 >> 0x00015378: =20 >> 0x00015380: =20 >> 0x000153a8: =20 >> 0x000153b8: =20 >> 0x000153c0: =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 >=20 > Note that the stack pointer manipulation (incrementing/popping) = *after* the return from the bl. 15339c, 153a0, and 153a4 should be 3 or = so distinct contexts in the .eh_frame information but are not. The code = is: >=20 >> 000000000001539c <.__cxa_end_catch+0x4dc> bl 0000000000009ae0 = >> 00000000000153a0 <.__cxa_end_catch+0x4e0> ld r2,40(r1) >> 00000000000153a4 <.__cxa_end_catch+0x4e4> addi r1,r1,128 >=20 > So there is a missing step or more of frame-context tracking in the = .eh_frame information. I should have noted that devel/powerpc64-gcc was used for buildworld of = projects/clang380-import -r295902 (and other versions) --and so for = libcxxrt as well. So it is g++ 5.3 that put out the incomplete .eh_frame frame-context = tracking, not clang 3.8.0. There is also the point that I typed "libc++" in places that I should = have typed "libcxxrt". =3D=3D=3D Mark Millard markmi at dsl-only.net