C++ exceptions in freebsd-arm doesn't seem to work

Warner Losh imp at bsdimp.com
Sun Jul 20 16:46:57 UTC 2014


On Jul 19, 2014, at 6:49 PM, Ian Lepore <ian at FreeBSD.org> wrote:

> 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.

Hopefully when released, it will be mature enough for us to include in 11.

Warner
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 842 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.freebsd.org/pipermail/freebsd-arm/attachments/20140720/be6b69fe/attachment.sig>


More information about the freebsd-arm mailing list