Bug 20160 - [4.0/4.1 Regression] link errors building libgcj tests
Summary: [4.0/4.1 Regression] link errors building libgcj tests
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libgcj (show other bugs)
Version: 4.0.0
: P2 critical
Target Milestone: 4.0.0
Assignee: Alexandre Oliva
URL:
Keywords:
: 20190 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-02-23 10:52 UTC by Richard Earnshaw
Modified: 2005-03-02 00:27 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-02-25 14:07:21


Attachments
Patch that may fix the problem, at the expense of even slower library creation (1.13 KB, patch)
2005-02-25 08:04 UTC, Alexandre Oliva
Details | Diff
Don't wipe out the dir onto which we've extracted convenience archives (1.17 KB, patch)
2005-02-25 18:53 UTC, Alexandre Oliva
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Earnshaw 2005-02-23 10:52:05 UTC
The libgcj testsuite is failing substantially all tests that require linking
libgcj.a on arm-elf because of missing symbols.

This failure started to occur sometime between 2005/02/13 and 2005/02/16.

There are about 5000 lines of error messages for each link command: the total
testrun log is about 1.5GBytes in size!

/work/rearnsha/gnu/egcs/arm-elf/libjava/testsuite/../../libjava/.libs/libgcj.a(jni.o):
In function `_Jv_JNI_GetAnyMethodID<0u>':
/home/rearnsha/gnusrc/egcs-cross/libjava/jni.cc:730: undefined reference to
`java::lang::StringBuffer::StringBuffer(java::lang::String*)'
/home/rearnsha/gnusrc/egcs-cross/libjava/jni.cc:736: undefined reference to
`java::lang::StringBuffer::class$'
/work/rearnsha/gnu/egcs/arm-elf/libjava/testsuite/../../libjava/.libs/libgcj.a(jni.o):
In function `_Jv_JNI_GetAnyMethodID<1u>':
/home/rearnsha/gnusrc/egcs-cross/libjava/jni.cc:730: undefined reference to
`java::lang::StringBuffer::StringBuffer(java::lang::String*)'
/home/rearnsha/gnusrc/egcs-cross/libjava/jni.cc:736: undefined reference to
`java::lang::StringBuffer::class$'
/work/rearnsha/gnu/egcs/arm-elf/libjava/testsuite/../../libjava/.libs/libgcj.a(link.o):
In function `_Jv_Linker::find_field(java::lang::Class*, java::lang::Class*,
_Jv_Utf8Const*, _Jv_Utf8Const*)':
/home/rearnsha/gnusrc/egcs-cross/libjava/link.cc:178: undefined reference to
`java::lang::StringBuffer::StringBuffer()'
/home/rearnsha/gnusrc/egcs-cross/libjava/link.cc:202: undefined reference to
`java::lang::StringBuffer::StringBuffer()'
/home/rearnsha/gnusrc/egcs-cross/libjava/link.cc:197: undefined reference to
`java::lang::StringBuffer::class$'
/work/rearnsha/gnu/egcs/arm-elf/libjava/testsuite/../../libjava/.libs/libgcj.a(link.o):
In function `_Jv_Linker::search_method_in_class(java::lang::Class*,
java::lang::Class*, _Jv_Utf8Const*, _Jv_Utf8Const*)':
/home/rearnsha/gnusrc/egcs-cross/libjava/link.cc:471: undefined reference to
`java::lang::StringBuffer::StringBuffer()'
/home/rearnsha/gnusrc/egcs-cross/libjava/link.cc:478: undefined reference to
`java::lang::StringBuffer::class$'
/work/rearnsha/gnu/egcs/arm-elf/libjava/testsuite/../../libjava/.libs/libgcj.a(link.o):
In function `_Jv_GetMethodString(java::lang::Class*, _Jv_Method*,
java::lang::Class*)':
/home/rearnsha/gnusrc/egcs-cross/libjava/link.cc:684: undefined reference to
`java::lang::StringBuffer::StringBuffer(java::lang::String*)'

etc.
Comment 1 Ranjit Mathew 2005-02-23 11:10:03 UTC
Does backing out this patch help?

http://gcc.gnu.org/ml/java-patches/2005-q1/msg00402.html

(See also: PR 20155)
Comment 2 Richard Earnshaw 2005-02-24 13:19:31 UTC
Yes, that's the patch that introduces the problem.
Comment 3 Richard Earnshaw 2005-02-24 14:12:03 UTC
*** Bug 20190 has been marked as a duplicate of this bug. ***
Comment 4 Richard Henderson 2005-02-24 22:01:50 UTC
Verified on i686-linux with --disable-shared.
Comment 5 Richard Henderson 2005-02-24 22:15:10 UTC
Yet another libtool bug.  It has clobbered ./java/lang/StringBuffer.o
with ./gnu/gcj/runtime/StringBuffer.o when moving data from the 
convenience library to the main library.

I fear we may be screwed, with no resolution that satisfies everyone.
Alex?  Is there any way out?
Comment 6 Alexandre Oliva 2005-02-24 22:51:36 UTC
Technically, it's not a libtool bug.  When you create an archive out of object
files that have overlapping basenames, ar will generally only retain the last
one.  Dropping the dirname portion is mandated by POSIX.

The right solution would be to avoid duplicate basenames entirely.  This is
probably tricky and painful to do in libjava.

Libtool has some trickery to at least force object files with the same basename
into an archive, passing special options to ar.  I suppose the best course of
action would be to rename the input files internally, transparently to the
caller, such that, when they're extracted, you don't one to overwrite the other.

Either way, this is probably not trivial to implement in libtool.  Reverting to
piecewise linking and modifying the grouping strategy might be easier.  I'll
think a bit about it.
Comment 7 Alexandre Oliva 2005-02-24 22:55:54 UTC
A short-term, simpler solution that might be more suitable for the GCC 4
time-frame is to create one convenience archives per subdir, so as to make sure
we don't have any overlapping basenames within a single archive.
Comment 8 Alexandre Oliva 2005-02-25 08:04:54 UTC
Created attachment 8282 [details]
Patch that may fix the problem, at the expense of even slower library creation

This patch makes sure no duplicate object names are added to static archives
created by libtool, thereby avoiding the problem if we have to extract the
contents of the archive.  Unfortunately, this will slow down even more the
creation of archives :-(

Richard (Earnshaw), would you please give it a try and let me know whether the
patch indeed fixes the problem for you.  Make sure you don't have any left-over
convenience libraries from a previous build; they may already contain
overlapping names.
Comment 9 Richard Earnshaw 2005-02-25 14:07:16 UTC
The build fails:

rm -fr .libs/libgcj.lax/libgcjgc_convenience.a
mkdir .libs/libgcj.lax/libgcjgc_convenience.a
(cd .libs/libgcj.lax/libgcjgc_convenience.a &&
/work/rearnsha/gnu/egcs/binutils/ar x
/work/rearnsha/gnu/egcs/arm-elf/thumb/libjava/../boehm-gc/.libs/libgcjgc_convenience.a)
copying selected object files to avoid basename conflicts...
rm -fr .libs/libgcj.lax
mkdir .libs/libgcj.lax
cp org/ietf/jgss/MessagesBundle.properties.o
.libs/libgcj.lax/lt1-MessagesBundle.properties.o
cp .libs/libgcj.lax/libgcj0_convenience.a/EventListener.o
.libs/libgcj.lax/lt2-EventListener.o
cp: cannot stat `.libs/libgcj.lax/libgcj0_convenience.a/EventListener.o': No
such file or directory
cp .libs/libgcj.lax/libgcj0_convenience.a/ContentHandler.o
.libs/libgcj.lax/lt3-ContentHandler.o
cp: cannot stat `.libs/libgcj.lax/libgcj0_convenience.a/ContentHandler.o': No
such file or directory
cp .libs/libgcj.lax/libgcj0_convenience.a/Attributes.o
.libs/libgcj.lax/lt4-Attributes.o
cp: cannot stat `.libs/libgcj.lax/libgcj0_convenience.a/Attributes.o': No such
file or directory

etc.

Incidentally, wouldn't it be more efficient to use links (either hard or soft)
rather than doing a copy?
Comment 10 Alexandre Oliva 2005-02-25 16:53:25 UTC
Hard-linking is an option, although we can't rely on hard-links being available.
 Soft-linking would require even more pathname tweaking, it's just not worth it.

Anyhow, thanks for testing, I see what the problem is, and I'll have a new patch
for you soon.
Comment 11 Alexandre Oliva 2005-02-25 18:53:58 UTC
Created attachment 8284 [details]
Don't wipe out the dir onto which we've extracted convenience archives

This should fix the problem you ran into, avoid another potential (although
very unlikely) error condition and try ln before cp to speed things up a tiny
little bit.  Please let me know how it goes.
Comment 12 Richard Earnshaw 2005-02-26 16:34:18 UTC
That patch seems to work, thanks.
Comment 13 Alexandre Oliva 2005-03-01 22:27:01 UTC
Subject: [PR libgcj/20160] rename archive members with duplicate basenames

The archives created for libjava are broken, in that some of the
object files that should go into it are missing.  That's because AR
is supposed to drop dirname components of pathnames in archive
members.  Libtool was already careful enough to ensure the all archive
members made to the convenience library, by using ar cq if creating
archives piecewise, but it isn't as careful when extracting the
archive members to create other archives with them, so we end up
dropping all but the last-added overlapping-basename object from the
second-generation archive.

This problem is already fixed in libtool mainline and 1.5 branches,
using some clever tricks at extract time, that I'm not entirely
comfortable with, and not quite willing to back-port.  Until we
actually upgrade to a newer libtool, I'd rather go with this change
that is IMHO safer, but unfortunately introduces some additional
overhead in archive creation time.  Oh well...

I'm checking this in mainline and 4.0 branch.  Tested on
arm-elf (thanks Richard!) and x86_64-linux-gnu.

Index: ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR libgcj/20160
	* ltmain.sh: Avoid creating archives with components that have
	duplicate basenames.
	* libjava/configure: Rebuilt.

Index: ltmain.sh
===================================================================
RCS file: /cvs/gcc/gcc/ltmain.sh,v
retrieving revision 1.24
diff -u -p -r1.24 ltmain.sh
--- ltmain.sh 8 Sep 2004 15:43:46 -0000 1.24
+++ ltmain.sh 1 Mar 2005 22:16:48 -0000
@@ -4307,6 +4307,63 @@ fi\
 #	  fi
 #	done
 
+	# POSIX demands no paths to be encoded in archives.  We have
+	# to avoid creating archives with duplicate basenames if we
+	# might have to extract them afterwards, e.g., when creating a
+	# static archive out of a convenience library, or when linking
+	# the entirety of a libtool archive into another (currently
+	# not supported by libtool).
+        if (for obj in $oldobjs
+	    do
+	      $echo "X$obj" | $Xsed -e 's%^.*/%%'
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  $echo "copying selected object files to avoid basename conflicts..."
+
+	  if test -z "$gentop"; then
+	    gentop="$output_objdir/${outputname}x"
+
+	    $show "${rm}r $gentop"
+	    $run ${rm}r "$gentop"
+	    $show "$mkdir $gentop"
+	    $run $mkdir "$gentop"
+	    status=$?
+	    if test $status -ne 0 && test ! -d "$gentop"; then
+	      exit $status
+	    fi
+	    generated="$generated $gentop"
+	  fi
+
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+	        newobj=lt$counter-$objbase
+	        counter=`expr $counter + 1`
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      $run ln "$obj" "$gentop/$newobj" ||
+	      $run cp "$obj" "$gentop/$newobj"
+	      oldobjs="$oldobjs $gentop/$newobj"
+	      ;;
+	    *) oldobjs="$oldobjs $obj" ;;
+	    esac
+	  done
+	fi
+
         eval cmds=\"$old_archive_cmds\"
 
         if len=`expr "X$cmds" : ".*"` &&
@@ -4320,20 +4377,7 @@ fi\
           objlist=
           concat_cmds=
           save_oldobjs=$oldobjs
-	  # GNU ar 2.10+ was changed to match POSIX; thus no paths are
-	  # encoded into archives.  This makes 'ar r' malfunction in
-	  # this piecewise linking case whenever conflicting object
-	  # names appear in distinct ar calls; check, warn and compensate.
-          if (for obj in $save_oldobjs
-	    do
-	      $echo "X$obj" | $Xsed -e 's%^.*/%%'
-	    done | sort | sort -uc >/dev/null 2>&1); then
-	    :
-	  else
-	    $echo "$modename: warning: object name conflicts; overriding AR_FLAGS to 'cq'" 1>&2
-	    $echo "$modename: warning: to ensure that POSIX-compatible ar will work" 1>&2
-	    AR_FLAGS=cq
-	  fi
+
           for obj in $save_oldobjs
           do
             oldobjs="$objlist $obj"

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}
Comment 14 GCC Commits 2005-03-01 22:27:51 UTC
Subject: Bug 20160

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	aoliva@gcc.gnu.org	2005-03-01 22:27:44

Modified files:
	.              : ChangeLog ltmain.sh 

Log message:
	PR libgcj/20160
	* ltmain.sh: Avoid creating archives with components that have
	duplicate basenames.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/ChangeLog.diff?cvsroot=gcc&r1=1.1061&r2=1.1062
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/ltmain.sh.diff?cvsroot=gcc&r1=1.24&r2=1.25

Comment 15 GCC Commits 2005-03-01 22:29:39 UTC
Subject: Bug 20160

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-4_0-branch
Changes by:	aoliva@gcc.gnu.org	2005-03-01 22:29:34

Modified files:
	.              : ChangeLog ltmain.sh 

Log message:
	PR libgcj/20160
	* ltmain.sh: Avoid creating archives with components that have
	duplicate basenames.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.1057&r2=1.1057.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/ltmain.sh.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.24&r2=1.24.30.1

Comment 16 Andrew Pinski 2005-03-02 00:27:43 UTC
I am going to assume this is fixed so I am going to close as such.