Even the most simple trow/catch programs appear to crash in the __cxa_* functions. this appears to be at least part of the problem with OpenEXR. How-To-Repeat: The following simple program crashes with the following backtrace: (gdb) r Starting program: /home/admin/a.out start Inside try block Caught an exception -- value is: 99 Program received signal SIGSEGV, Segmentation fault. 0x0000000040396aac in __cxa_end_catch () from /usr/lib/libstdc++.so.6 (gdb) bt #0 0x0000000040396aac in __cxa_end_catch () from /usr/lib/libstdc++.so.6 #1 0x0000000000100f38 in main () at test.cpp:13 // A simple exception handling example. #include <iostream> int main() { std::cout << "start\n"; try { // start a try block std::cout << "Inside try block\n"; throw 99; // throw an error std::cout << "This will not execute"; } catch (int i) { // catch an error std::cout << "Caught an exception -- value is: "; std::cout << i << "\n"; } std::cout << "end"; return 0; }
On Thu, Jan 03, 2008 at 03:29:48AM +0000, Stephen Hurd wrote: > > Even the most simple trow/catch programs appear to crash in the __cxa_* functions. this appears to be at least part of the problem with OpenEXR. > >How-To-Repeat: > The following simple program crashes with the following backtrace: > > (gdb) r > Starting program: /home/admin/a.out > start > Inside try block > Caught an exception -- value is: 99 > > Program received signal SIGSEGV, Segmentation fault. > 0x0000000040396aac in __cxa_end_catch () from /usr/lib/libstdc++.so.6 > (gdb) bt > #0 0x0000000040396aac in __cxa_end_catch () from /usr/lib/libstdc++.so.6 > #1 0x0000000000100f38 in main () at test.cpp:13 > > > // A simple exception handling example. > #include <iostream> > int main() > { > std::cout << "start\n"; > try > { // start a try block > std::cout << "Inside try block\n"; > throw 99; // throw an error > std::cout << "This will not execute"; > } > > catch (int i) > { // catch an error > std::cout << "Caught an exception -- value is: "; > std::cout << i << "\n"; > } > > std::cout << "end"; > > return 0; > } > The underlying problem (from a libstdc++ perspective) is that with GCC 4.2 __gthread_active_p() always returns 1, regardless of whether the program was compiled with -pthread or not. This is even a MI problem: marius@alchemy:/home/marius > uname -a FreeBSD alchemy.franken.de 8.0-CURRENT FreeBSD 8.0-CURRENT #0: Thu Dec 6 15:47:30 CET 2007 root@alchemy.franken.de:/tmp/obj/usr/src/sys/alchemy i386 marius@alchemy:/home/marius > cat test.cc #include <iostream> int main() { std::cout << "__gthread_active_p=" << __gthread_active_p() << "\n"; return (0); } marius@alchemy:/home/marius > g++ -o test test.cc marius@alchemy:/home/marius > ./test __gthread_active_p=1 marius@alchemy:/home/marius > g++ -o test -pthread test.cc marius@alchemy:/home/marius > ./test __gthread_active_p=1 For reference, with GCC 3.4.6 on a FreeBSD 6.2-STABLE: marius@vnv:/home/marius > uname -a FreeBSD vnv.invalid 6.2-STABLE FreeBSD 6.2-STABLE #6: Wed Jun 13 09:21:13 CEST 2007 root@vnv.invalid:/usr/obj/usr/src/sys/vnv i386 marius@vnv:/home/marius > cat test.cc #include <iostream> int main() { std::cout << "__gthread_active_p=" << __gthread_active_p() << "\n"; return (0); } marius@vnv:/home/marius > g++ -o test test.cc marius@vnv:/home/marius > ./test __gthread_active_p=0 marius@vnv:/home/marius > g++ -o test -pthread test.cc marius@vnv:/home/marius > ./test __gthread_active_p=1 With GCC 4.2 __gthread_active_p() always returning 1 breaks the exception handling of libstdc++ for non-threaded programs on platforms without TLS support due to the way it implements EH there, i.e. on FreeBSD/arm and FreeBSD/sparc64 due to the lack of TLS support for these archs in the ancient base binutils. However, given that __gthread_active_p() is also used in a couple of other places besides EH, this bug has great potential to also cause problems in other areas and on all archs. The reason for this false positive is that gthr-posix.h checks for the existence of pthread_cancel() and FreeBSD 7 supplies a stub for it in libc since lib/libc/gen/_pthread_stubs.c rev. 1.13. A solution for this is to use the __gthread_active_p() version that libstdc++ uses for Solaris and which actively checks for a working POSIX threads implementation (if such functions exist) instead of checking for the mere existence of corresponding functions. The patch below changes gthr-posix.h accordingly (in order to use it it's probably best to go through buildworld and installworld in order to ensure all base consumers of gthr-posix.h are rebuilt and all copies of gthr-posix.h are also updated). Does anyone object to me committing that patch to the vendor branch? Marius Index: gthr-posix.h =================================================================== RCS file: /usr/data/bsd/cvs/fbsd/src/contrib/gcc/gthr-posix.h,v retrieving revision 1.1.1.8 diff -u -r1.1.1.8 gthr-posix.h --- gthr-posix.h 14 Aug 2007 02:37:31 -0000 1.1.1.8 +++ gthr-posix.h 3 Jan 2008 14:54:51 -0000 @@ -152,9 +152,13 @@ it is passed so we cannot pretend that the interface is active if -pthreads is not specified. On Solaris 2.5.1, the interface is not exposed at all so we need to play the usual game with weak symbols. On Solaris 10 and up, a - working interface is always exposed. */ + working interface is always exposed. + On FreeBSD 6 and 7 the libc also exposes a dummy POSIX threads interface, + similar to what Solaris 2.6 up to 9 does. FreeBSD >= 700014 even provides + a pthread_cancel stub in libc, which means the alternate __gthread_active_p + below can't be used there. */ -#if defined(__sun) && defined(__svr4__) +#if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__)) static volatile int __gthread_active = -1; @@ -197,7 +201,7 @@ return __gthread_active_latest_value != 0; } -#else /* not Solaris */ +#else /* neither FreeBSD nor Solaris */ static inline int __gthread_active_p (void) @@ -207,7 +211,7 @@ return __gthread_active_ptr != 0; } -#endif /* Solaris */ +#endif /* FreeBSD or Solaris */ #else /* not SUPPORTS_WEAK */
On Thu, Jan 03, 2008 at 07:39:30PM +0100, Marius Strobl wrote: > Does anyone object to me committing that patch to the vendor > branch? I'd rather not - unless it actually has been submitted upstream and there was some indication the change was tolerable to the GCC folks (or its clear they aren't working with us on a solution). I do think it needs to get into RELENG_7_0 ASAP, though. How about committing it just to RELENG_7* for now? > RCS file: /usr/data/bsd/cvs/fbsd/src/contrib/gcc/gthr-posix.h,v .. > we need to play the usual game with weak symbols. On Solaris 10 and up, a > - working interface is always exposed. */ > + working interface is always exposed. > + On FreeBSD 6 and 7 the libc also exposes a dummy POSIX threads interface, > + similar to what Solaris 2.6 up to 9 does. FreeBSD >= 700014 even provides > + a pthread_cancel stub in libc, which means the alternate __gthread_active_p > + below can't be used there. */ If I may suggest the FSF-style formatting: we need to play the usual game with weak symbols. On Solaris 10 and up, a + working interface is always exposed. On FreeBSD 6 and later, libc also + exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up + to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc, + which means the alternate __gthread_active_p below cannot be used there. */ -- -- David (obrien@FreeBSD.org)
marius 2008-01-05 22:58:51 UTC FreeBSD src repository Modified files: (Branch: RELENG_7) contrib/gcc gthr-posix.h Log: On FreeBSD GCC 4.2.x checks for the existence of pthread_cancel() in order to determine whether a program is running with multithreading support. This check causes __gthread_active_p() to always return 1 however, regardless of whether the program was actually compiled with -pthread or not, due to the fact that the FreeBSD libc contains a pthread_cancel() stub. Fix this by using the __gthread_active_p() version that GCC uses for Solaris and which actively checks for a working POSIX threads implementation (if such functions exist) instead of checking for the mere existence of corresponding functions. On platforms without TLS support, i.e. on arm and sparc64 due to the lack of GNU TLS support for these archs in binutils 2.15., the false positives returned by __gthread_active_p() for non-threaded programs cause the exception handling implementation GCC uses in this case to crash. This is because GCC assumes that the POSIX threading functions actually work when __gthread_active_p() returns 1 while in fact the corresponding stubs in libc just immediately return. Given that __gthread_active_p() is also used in a couple of other places besides exception handling, this bug has great potential to also cause problems in other areas and on all archs. This is committed to RELENG_7 directly in order to get a fix into RELENG_7_0 as soon as possible while allowing to loop the official fix back into the vendor branch and not taking gthr-posix.h off the vendor branch in HEAD. PR: 119289 Reviewed by: obrien (plus style fix) Approved by: re (kensmith) Revision Changes Path 1.1.1.8.2.1 +7 -4 src/contrib/gcc/gthr-posix.h _______________________________________________ cvs-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/cvs-all To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
State Changed From-To: open->patched marius, does this need to be MFCed to RELENG_6, or can it just be closed?
Responsible Changed From-To: freebsd-sparc64->marius
On Fri, Feb 29, 2008 at 02:11:43AM +0000, linimon@FreeBSD.org wrote: > > marius, does this need to be MFCed to RELENG_6, or can it just be closed? > It doesn't need to be MFCed to RELENG_6, it's still a MI bug in HEAD/8-CURRENT though. As indicated by obrien@ (see audit-trail), the plan is to let it be fixed upstream first and then to loop the official fix back into our vendor branch once core@ approved it. Gerald@ is still working on the former. Marius
State Changed From-To: patched->suspended Does not need MFC to 6; does, however, need to be dealt with when the next upstream version is incorporated.
marius 2008-04-21 20:40:43 UTC FreeBSD src repository src/contrib/gcc - Imported sources Update of /home/ncvs/src/contrib/gcc In directory repoman.freebsd.org:/tmp/cvs-serv38448 Log Message: * gthr-posix.h (__gthread_active_p): Use the Solaris implementation for FreeBSD as well. This is the fix for __gthread_active_p() returning false positives which was committed as rev. 1.1.1.8.2.1 to RELENG_7 but now looped back to the vendor branch via the GCC repository and relicensed to be GPLv2 by me. Thanks go to gerald@ for getting the fix approved upstream and for committing to the GCC repository. PR: 119289 Approved by: core Status: Vendor Tag: FSF Release Tags: gcc_trunk_20080418_SVN134423 U src/contrib/gcc/gthr-posix.h No conflicts created by this import _______________________________________________ cvs-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/cvs-all To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
State Changed From-To: suspended->closed Close; this PR has been fully dealt with.