Date: Sat, 7 Jun 2014 14:12:43 +0200 From: Olavi Kumpulainen <olavi.m.kumpulainen@gmail.com> To: freebsd-arm@freebsd.org Subject: C++ exceptions in freebsd-arm doesn't seem to work Message-ID: <BEAC4CFB-EC4F-456D-8173-2E34CCE3A2C1@gmail.com>
next in thread | raw e-mail | index | archive | help
Hi there, If this question has been discussed before, sorry. I couldn=92t find = anything when scanning through the archives though. So, I=92m 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@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()=20 { throw std::exception(); } int main() { std::cout << "Starting throw-test" << std::endl; try { func(); } catch(std::exception){ std::cout << =93In 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=92ve 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; =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 the = call instruction itself. */ return_address -=3D 2; if (__gnu_Unwind_Find_exidx) { eitp =3D (const __EIT_entry *) __gnu_Unwind_Find_exidx = (return_address, &nrec); if (!eitp) { UCB_PR_ADDR (ucbp) =3D 0; return _URC_FAILURE; } } else { eitp =3D &__exidx_start; nrec =3D &__exidx_end - &__exidx_start; } Since __gnu_Unwind_Find_exidx =3D=3D NULL, the EIT is located in an = array located between __exidx_start and __exidx_end. However, __exidx_end =3D=3D __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=92t seem to work. Can any of you guys shed some light on this? Cheers, /Olavi
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?BEAC4CFB-EC4F-456D-8173-2E34CCE3A2C1>