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