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