C++ exceptions in freebsd-arm doesn't seem to work
Ian Lepore
ian at FreeBSD.org
Sun Jul 20 00:49:12 UTC 2014
On Sat, 2014-07-19 at 18:20 -0600, Warner Losh wrote:
> On Jun 7, 2014, at 9:55 AM, Ian Lepore <ian at FreeBSD.org> wrote:
>
> > On Sat, 2014-06-07 at 14:12 +0200, Olavi Kumpulainen wrote:
> >> Hi there,
> >>
> >> If this question has been discussed before, sorry. I couldn´t find anything when scanning through the archives though.
> >>
> >> So, I´m running FreeBSD-10/stable on a RPI version B as you can see here;
> >>
> >>
> >> Copyright (c) 1992-2014 The FreeBSD Project.
> >> Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
> >> The Regents of the University of California. All rights reserved.
> >> FreeBSD is a registered trademark of The FreeBSD Foundation.
> >> FreeBSD 10.0-STABLE #0 r266807: Thu May 29 07:07:08 UTC 2014
> >> root at 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) 20140512
> >>
> >>
> >> I have this little program;
> >>
> >> $ cat t.cc
> >>
> >> #include <stdexcept>
> >> #include <iostream>
> >>
> >> void func()
> >> {
> >> throw std::exception();
> >> }
> >>
> >>
> >> int main()
> >> {
> >> std::cout << "Starting throw-test" << std::endl;
> >>
> >> try
> >> {
> >> func();
> >> }
> >> catch(std::exception){
> >> std::cout << “In my exception handler" << std::endl;
> >> }
> >> catch(...) {
> >> std::cout << "In catch-all handler" << std::endl;
> >> }
> >>
> >> return 0;
> >> }
> >>
> >> With this Makefile;
> >>
> >> $ cat Makefile
> >>
> >> all : t
> >>
> >> t : t.cc
> >> c++ -o t -fexceptions t.cc
> >>
> >>
> >> Running the above produces the following result;
> >>
> >> $ ./t
> >> Starting throw-test
> >> Fatal error during phase 1 unwinding
> >> Abort (core dumped)
> >>
> >> Which indeed is not what I expected.
> >>
> >> I´ve tried debugging this for a couple of days and have concluded that my throw clause ends up in contrib/gcc/config/arm/unwind-arm.c. The associated code in unwind-arm.c is;
> >>
> >> static _Unwind_Reason_Code
> >> get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address)
> >> {
> >> const __EIT_entry * eitp;
> >> int nrec;
> >>
> >> /* 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 the call
> >> instruction itself. */
> >> return_address -= 2;
> >>
> >> if (__gnu_Unwind_Find_exidx)
> >> {
> >> eitp = (const __EIT_entry *) __gnu_Unwind_Find_exidx (return_address,
> >> &nrec);
> >> if (!eitp)
> >> {
> >> UCB_PR_ADDR (ucbp) = 0;
> >> return _URC_FAILURE;
> >> }
> >> }
> >> else
> >> {
> >> eitp = &__exidx_start;
> >> nrec = &__exidx_end - &__exidx_start;
> >> }
> >>
> >>
> >> Since __gnu_Unwind_Find_exidx == NULL, the EIT is located in an array located between __exidx_start and __exidx_end.
> >>
> >> However, __exidx_end == __exidx_start! So the EIT has a length of zero, 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 error during phase 1 unwinding\n");
> >>
> >> # 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
> >>
> >> So exception throwing in clang++ doesn´t seem to work.
> >>
> >> Can any of you guys shed some light on this?
> >>
> >> Cheers,
> >>
> >> /Olavi
> >
> > Sadly, all I can do is confirm what you say: C++ exceptions don't work
> > on ARM EABI, not with clang and not with gcc. The only combo that works
> > is gcc and OABI, but with that combo you lose hardware floating point.
> >
> > There are rumours that this may be fixed in clang 3.5, but we apparently
> > can't import 3.5 because it can't be bootstrapped using gcc 4.2. I
> > haven't had time yet to learn how to build clang 3.5 out-of-tree to
> > confirm that exceptions work there.
>
> I’d like to make one thing perfectly clear, as there’s some confusion.
> As long as we can bootstrap from the last version of the system, the
> fact that it doesn’t compile with gcc 4.2 is *NOT* a gating factor. That’s
> never been a requirement for a 3.5 import, and gcc 4.2 is being shown
> the door for 11.x.
>
> I’ve not had time to try it either. And my time for doing build stuff has
> been limited the past month or so. I hope to get back to it in the coming
> weeks to resolve some lingering issues, as well as fix the external
> toolchain support to be completely bootstrapping rather than half
> bootstrapping like we have today.
>
> Warner
I was under the mistaken impression that 3.5 had been released but we
hadn't adopted it yet. Yesterday I saw something that said 3.5 is
scheduled for release in summer 2015, but I think that was a typo on a
news site. Looking deeper just now, it appears to be scheduled for
August 2014.
-- Ian
More information about the freebsd-arm
mailing list