From owner-freebsd-arm@FreeBSD.ORG Sat Jul 19 22:35:22 2014 Return-Path: Delivered-To: freebsd-arm@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 0A6F19E8 for ; Sat, 19 Jul 2014 22:35:22 +0000 (UTC) Received: from mho-01-ewr.mailhop.org (mho-03-ewr.mailhop.org [204.13.248.66]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BEBF92568 for ; Sat, 19 Jul 2014 22:35:21 +0000 (UTC) Received: from c-50-155-136-3.hsd1.co.comcast.net ([50.155.136.3] helo=ilsoft.org) by mho-01-ewr.mailhop.org with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.72) (envelope-from ) id 1X8dDs-0008Ae-0v; Sat, 19 Jul 2014 22:35:20 +0000 Received: from [172.22.42.240] (revolution.hippie.lan [172.22.42.240]) by ilsoft.org (8.14.9/8.14.9) with ESMTP id s6JMZJrq028118; Sat, 19 Jul 2014 16:35:19 -0600 (MDT) (envelope-from ian@FreeBSD.org) X-Mail-Handler: Dyn Standard SMTP by Dyn X-Originating-IP: 50.155.136.3 X-Report-Abuse-To: abuse@dyndns.com (see http://www.dyndns.com/services/sendlabs/outbound_abuse.html for abuse reporting information) X-MHO-User: U2FsdGVkX1/afZLfDZPcYRtE0ohyoiBO X-Authentication-Warning: paranoia.hippie.lan: Host revolution.hippie.lan [172.22.42.240] claimed to be [172.22.42.240] Subject: Re: C++ exceptions in freebsd-arm doesn't seem to work From: Ian Lepore To: Olavi Kumpulainen In-Reply-To: References: Content-Type: text/plain; charset="iso-8859-13" Date: Sat, 19 Jul 2014 16:35:18 -0600 Message-ID: <1405809318.85788.35.camel@revolution.hippie.lan> Mime-Version: 1.0 X-Mailer: Evolution 2.32.1 FreeBSD GNOME Team Port Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by ilsoft.org id s6JMZJrq028118 Cc: freebsd-arm@freebsd.org X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "Porting FreeBSD to ARM processors." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 Jul 2014 22:35:22 -0000 On Sat, 2014-06-07 at 14:12 +0200, Olavi Kumpulainen wrote: > Hi there, >=20 > If this question has been discussed before, sorry. I couldn=FFt find an= ything when scanning through the archives though. >=20 > So, I=FFm running FreeBSD-10/stable on a RPI version B as you can see h= ere; >=20 >=20 > Copyright (c) 1992-2014 The FreeBSD Project. > Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 199= 4 > The Regents of the University of California. All rights reserve= d. > FreeBSD is a registered trademark of The FreeBSD Foundation. > FreeBSD 10.0-STABLE #0 r266807: Thu May 29 07:07:08 UTC 2014 > root@grind.freebsd.org:/usr/obj/arm.armv6/usr/src/sys/RPI-B arm > FreeBSD clang version 3.4.1 (tags/RELEASE_34/dot1-final 208032) 2014051= 2 >=20 >=20 > I have this little program; >=20 > $ cat t.cc >=20 > #include > #include >=20 > void func()=20 > { > throw std::exception(); > } >=20 >=20 > int main() > { > std::cout << "Starting throw-test" << std::endl; >=20 > try > { > func(); > } > catch(std::exception){ > std::cout << =B4In my exception handler" << std::endl; > } > catch(...) { > std::cout << "In catch-all handler" << std::endl; > } >=20 > return 0; > } >=20 > With this Makefile; >=20 > $ cat Makefile >=20 > all : t >=20 > t : t.cc > c++ -o t -fexceptions t.cc >=20 >=20 > Running the above produces the following result; >=20 > $ ./t > Starting throw-test > Fatal error during phase 1 unwinding > Abort (core dumped) >=20 > Which indeed is not what I expected. >=20 > I=FFve tried debugging this for a couple of days and have concluded tha= t my throw clause ends up in contrib/gcc/config/arm/unwind-arm.c. The ass= ociated code in unwind-arm.c is; >=20 > static _Unwind_Reason_Code > get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address) > { > const __EIT_entry * eitp; > int nrec; > =20 > /* The return address is the address of the instruction following the > call instruction (plus one in thumb mode). If this was the last > instruction in the function the address will lie in the following > function. Subtract 2 from the address so that it points within th= e call > instruction itself. */ > return_address -=3D 2; >=20 > if (__gnu_Unwind_Find_exidx) > { > eitp =3D (const __EIT_entry *) __gnu_Unwind_Find_exidx (return_ad= dress, > &nrec); > if (!eitp) > { > UCB_PR_ADDR (ucbp) =3D 0; > return _URC_FAILURE; > } > } > else > { > eitp =3D &__exidx_start; > nrec =3D &__exidx_end - &__exidx_start; > } >=20 >=20 > Since __gnu_Unwind_Find_exidx =3D=3D NULL, the EIT is located in an arr= ay located between __exidx_start and __exidx_end. >=20 > However, __exidx_end =3D=3D __exidx_start! So the EIT has a length of z= ero, nrec will be 0. libgcc will fail the lookup and return _URC_FAILURE = to libcxxrt.cc, which in turn will produce the fprintf(stderr, "Fatal err= or during phase 1 unwinding\n"); >=20 > # readelf -s t | grep exidx > 36: 0000a267 0 NOTYPE GLOBAL DEFAULT ABS __exidx_start > 47: 0000a267 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end > 115: 0000a267 0 NOTYPE GLOBAL DEFAULT ABS __exidx_end > 150: 0000a267 0 NOTYPE GLOBAL DEFAULT ABS __exidx_start >=20 > So exception throwing in clang++ doesn=FFt seem to work. >=20 > Can any of you guys shed some light on this? >=20 > Cheers, >=20 > /Olavi I checked in a partial fix for c++ exception handling in r268893. It fixes the specific problem you detailed above, which was essentially that the __gnu_Unwind_Find_exidx() function was not available in any shared library, making the unwinder fall back to using the __exidx_start and end symbols, which are only valid in a statically-linked app. With the new function in place, exceptions are closer to working with gcc 4.2.1, but still don't work with clang. With gcc, some things work and some things don't. For example if you throw an exception and in the same function have a catch with the right specific type it segfaults, but a catch(...) will catch it without problems. But you can catch an exception by type if the catch is in a function higher up the call chain from the place it was thrown. We're continuing to debug this at $work, and welcome any input if anyone else makes progress with it. Right now we still don't know whether the segfaults are because of bad unwinder library code or bad unwind data emitted by gcc. (I sure hope it's the library, because that's easier to fix.) On the clang front, it has been said that c++ exceptions work in clang 3.5, so we tried the clang-devel port, and it didn't just work. But it turns out that port hasn't been updated for quite a while, so we may not have tested the code that's supposed to work right. While trying that I discovered that clang 3.5 isn't scheduled for release for about another year, so that really isn't a viable solution for anyone with near-term needs, unless the required changes can be cherry-picked and brought into our version of 3.4. -- Ian