Bug 50888 - Bootstrap failure in libjava against latest git glibc
Summary: Bootstrap failure in libjava against latest git glibc
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: bootstrap (show other bugs)
Version: 4.7.0
: P1 normal
Target Milestone: ---
Assignee: Jakub Jelinek
URL:
Keywords:
: 51177 (view as bug list)
Depends on:
Blocks:
 
Reported: 2011-10-27 18:40 UTC by Jakub Jelinek
Modified: 2014-04-15 23:01 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-11-23 00:00:00


Attachments
gcc47-pr50888.patch (700 bytes, patch)
2011-11-23 13:19 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2011-10-27 18:40:05 UTC
./.libs/libgcj.so: undefined reference to `__cxa_call_unexpected'
collect2: ld returned 1 exit status
make[3]: *** [jv-convert] Error 1
make[3]: *** Waiting for unfinished jobs....
./.libs/libgcj.so: undefined reference to `__cxa_call_unexpected'
collect2: ld returned 1 exit status
make[3]: *** [gcj-dbtool] Error 1

The problem is that libgcj is compiled with C++ and -fnon-call-exceptions, but doesn't link against -lstdc++ nor -lsupc++.  <ctype.h> in glibc recently changed, so that isspace in C++ is now an inline function:
# define __isctype_f(type) \
  __extern_inline int                                                         \
  is##type (int __c) __THROW                                                  \
  {                                                                           \
    return (*__ctype_b_loc ())[(int) (__c)] & (unsigned short int) _IS##type; \
  }
...
__isctype_f (space)

While __ctype_b_loc, a function pointer, has throw () on it, the isspace inline
has it too.  So normally not a problem.  But with -fnon-call-exceptions we end up with __cxa_call_unexpected call just in case __ctype_b_loc fn pointer would be invalid (it is not, but gcc doesn't know it).

2011-10-27  Jakub Jelinek  <jakub@redhat.com>

        * prims.cc (__NO_CTYPE): For glibc define this before including
        ctype.h.

--- libjava/prims.cc    2009-04-28 06:02:30.000000000 +0200
+++ libjava/prims.cc    2011-10-27 12:57:42.748752380 +0200
@@ -38,6 +38,14 @@ details.  */
 #endif
 
 #ifndef DISABLE_GETENV_PROPERTIES
+#ifdef __GLIBC__
+/* glibc 2.15+ provides even for C++ inline optimized ::isspace etc.
+   Unfortunately those inlines are throw (), and call a function pointer
+   (which is throw () too, but with -fnon-call-exceptions this results
+   in a __cxa_call_unexpected call.  This macro disables the optimized
+   version.  */
+#define __NO_CTYPE 1
+#endif
 #include <ctype.h>
 #include <java-props.h>
 #define PROCESS_GCJ_PROPERTIES process_gcj_properties()

works for me but might be considered too hackish (__NO_CTYPE results in macro says to <ctype.h> it should optimize isspace etc.).

Other alternatives would be to link -lsupc++ in, or replace use of isspace (c)
with memchr (" \t\n\r\v", c, 5) != NULL (the standard POSIX "C" locale isspace characters), or use safe-ctype, etc.
Comment 1 Jakub Jelinek 2011-10-27 18:40:45 UTC
This affects 4.6.2 too and most probably 4.5.x too.
Comment 2 Mark Wielaard 2011-10-27 18:53:35 UTC
(In reply to comment #0)
> or replace use of isspace (c)
> with memchr (" \t\n\r\v", c, 5) != NULL (the standard POSIX "C" locale isspace
> characters), or use safe-ctype, etc.

I think that is the best solution, or even only check for a literal space.
This code is only used to "parse" properties provided by the GCJ_PROPERTIES environment variable. Which is a gcj extension.

It was added in 1999 and it hasn't been changed since then.
http://gcc.gnu.org/ml/java-patches/1999-q4/msg00014.html
Any opinions Anthony?
Comment 3 Mark Wielaard 2011-10-27 23:14:02 UTC
<antgreen> I don't think isspace() is really needed.  We can just check for ' ' and maybe tab.
<antgreen> wow - 1999 was a long time ago
Comment 4 Christian Joensson 2011-10-31 05:29:38 UTC
Recent bootstrap/build on i686/linux

libtool: link: /usr/local/src/trunk/objdir/./gcc/gcj -B/usr/local/src/trunk/objdir/i686-redhat-linux/libjava/ -B/usr/local/src/trunk/objdir/./gcc/ -B/usr/i686-redhat-linux/bin/ -B/usr/i686-redhat-linux/lib/ -isystem /usr/i686-redhat-linux/include -isystem /usr/i686-redhat-linux/sys-include -ffloat-store -fomit-frame-pointer -Usun -g -O2 -o .libs/jv-convert --main=gnu.gcj.convert.Convert -shared-libgcc  -L/usr/local/src/trunk/objdir/i686-redhat-linux/libjava/.libs -L/usr/local/src/trunk/objdir/i686-redhat-linux/libjava ./.libs/libgcj.so -lpthread -lrt -ldl -lz -Wl,-rpath -Wl,/usr/lib
./.libs/libgcj.so: undefined reference to `__cxa_call_unexpected'
collect2: error: ld returned 1 exit status
make[3]: *** [jv-convert] Error 1
Comment 5 Andrew Pinski 2011-11-16 20:48:34 UTC
*** Bug 51177 has been marked as a duplicate of this bug. ***
Comment 6 Andrew Haley 2011-11-21 18:02:29 UTC
I suppose I don't really object to a workaround in libjava, but surely the
sensible thing to do is fix isspace() not to throw.  It can't, anyway: that
would be in breach of its spec.
Comment 7 Jakub Jelinek 2011-11-22 15:19:53 UTC
(In reply to comment #6)
> I suppose I don't really object to a workaround in libjava, but surely the
> sensible thing to do is fix isspace() not to throw.  It can't, anyway: that
> would be in breach of its spec.

Sorry, forgot about this PR.
isspace is actually marked as not throwing, i.e. throw() in C++.  In glibc 2.15+ it happens to be implemented as throw() inline function which calls another function (which is throw() too), the problem is that with -fnon-call-exceptions the compiler doesn't know the function pointer is always non-NULL and assumes the call instruction might throw on SIGSEGV/SIGILL etc.  That will always work, but the compiler must assume it doesn't always, thus it needs -lsupc++ support with which libjava is not linked.
Comment 8 Andrew Haley 2011-11-22 17:55:51 UTC
(In reply to comment #7)

> isspace is actually marked as not throwing, i.e. throw() in C++.  In glibc
> 2.15+ it happens to be implemented as throw() inline function which calls
> another function (which is throw() too), the problem is that with
> -fnon-call-exceptions the compiler doesn't know the function pointer is always
> non-NULL and assumes the call instruction might throw on SIGSEGV/SIGILL etc. 
> That will always work, but the compiler must assume it doesn't always, thus it
> needs -lsupc++ support with which libjava is not linked.

Thank you, all is now clear.  I wonder if it might make sense to fix this
in a more general way than simply not calling isspace().  Perhaps we could
provide a weak __cxa_call_unexpected, or find some way of persuading g++ not
to emit such a call.
Comment 9 Jakub Jelinek 2011-11-23 13:19:34 UTC
Created attachment 25901 [details]
gcc47-pr50888.patch

Untested fix.  Checked all locales on my F16 box and in all of them isspace
is true only for these 6 characters and nothing else (iswspace accepts various other characters, but isspace works on single bytes only and the other characters are multi-byte.

Yes, we could perhaps define __cxa_call_unexpected instead, but we'd really want to make sure it is hidden visibility, in order not to override the libstdc++.so __cxa_call_unexpected.  And not all targets support hidden visibility, so it would turn into a portability nightmare.
Comment 10 Jakub Jelinek 2011-11-24 07:18:21 UTC
Author: jakub
Date: Thu Nov 24 07:18:16 2011
New Revision: 181685

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=181685
Log:
	PR bootstrap/50888
	* prims.cc: Don't include ctype.h.
	(c_isspace): Define.
	(next_property_key, next_property_value): Use it instead
	of isspace.

Modified:
    trunk/libjava/ChangeLog
    trunk/libjava/prims.cc
Comment 11 Jakub Jelinek 2011-11-24 07:21:50 UTC
Author: jakub
Date: Thu Nov 24 07:21:39 2011
New Revision: 181686

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=181686
Log:
	PR bootstrap/50888
	* prims.cc: Don't include ctype.h.
	(c_isspace): Define.
	(next_property_key, next_property_value): Use it instead
	of isspace.

Modified:
    branches/gcc-4_6-branch/libjava/ChangeLog
    branches/gcc-4_6-branch/libjava/prims.cc
Comment 12 Jakub Jelinek 2011-11-24 07:23:24 UTC
Author: jakub
Date: Thu Nov 24 07:23:16 2011
New Revision: 181687

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=181687
Log:
	PR bootstrap/50888
	* prims.cc: Don't include ctype.h.
	(c_isspace): Define.
	(next_property_key, next_property_value): Use it instead
	of isspace.

Modified:
    branches/gcc-4_5-branch/libjava/ChangeLog
    branches/gcc-4_5-branch/libjava/prims.cc
Comment 13 Jakub Jelinek 2011-11-24 07:24:49 UTC
Author: jakub
Date: Thu Nov 24 07:24:43 2011
New Revision: 181688

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=181688
Log:
	PR bootstrap/50888
	* prims.cc: Don't include ctype.h.
	(c_isspace): Define.
	(next_property_key, next_property_value): Use it instead
	of isspace.

Modified:
    branches/gcc-4_4-branch/libjava/ChangeLog
    branches/gcc-4_4-branch/libjava/prims.cc
Comment 14 Jakub Jelinek 2011-11-24 08:41:17 UTC
Fixed for 4.4+.
Comment 15 xuepeng guo 2012-07-11 06:02:17 UTC
Author: xguo
Date: Wed Jul 11 06:02:10 2012
New Revision: 189421

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=189421
Log:
2012-07-11  Terry Guo  <terry.guo@arm.com>

        Backport r181685 from mainline
        2011-11-24  Jakub Jelinek  <jakub@redhat.com>

        PR bootstrap/50888
        * prims.cc: Don't include ctype.h.
        (c_isspace): Define.
        (next_property_key, next_property_value): Use it instead
        of isspace.

Added:
    branches/ARM/embedded-4_6-branch/libjava/ChangeLog.arm
Modified:
    branches/ARM/embedded-4_6-branch/libjava/prims.cc
Comment 16 Wade Colson 2014-04-15 23:01:19 UTC Comment hidden (spam)