United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4694590 libstdc++ version requirement: Newer version of gcc supplies libstdc++.so.4.0.0
JDK-4694590 : libstdc++ version requirement: Newer version of gcc supplies libstdc++.so.4.0.0

Details
Type:
Bug
Submit Date:
2002-05-31
Status:
Closed
Updated Date:
2003-04-01
Project Name:
JDK
Resolved Date:
2003-04-01
Component:
hotspot
OS:
linux
Sub-Component:
runtime
CPU:
x86
Priority:
P4
Resolution:
Duplicate
Affected Versions:
1.4.0,1.4.1
Fixed Versions:

Related Reports
Duplicate:
Duplicate:
Duplicate:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description
[N O T E : T H I S   I S   N O T   A   D U P L I C A T E   O F   4 6 8 7 8 1 4]
[                    PLEASE SEE NOTES IN EVALUATION                           ]

Name: gm110360			Date: 05/30/2002


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

I got this output by running java on a linux box that has gcc2.96.3, not 3.1.


Kondara MNU/Linux 2.1 with some CVS updates.
Kernel: Linux 2.4.18
glibc: 2.2.5
gcc: *3.1* (provides libstdc++.so.4.0.0)




A DESCRIPTION OF THE PROBLEM :
Java2 SDK 1.4 does not run at all on some Linux box that only has newer libstdc++.
Newer version of gcc supplies libstdc++.so.4.0.0, and is not compatible with
older ones.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Install gcc 3.0 or higher.
2. Install Java2 SDK 1.4.
   RPM complains about failed dependencies:
   libstdc++-libc6.1-1.so.2 is needed by...
3. Install Java2 SDK 1.4 with ignoring dependencies.
   (Using --nodeps) Of course this would not help at all.
4. run java -version. Then it complains:
   failed ../jre/lib/i386/client/libjvm.so. because libstdc++-libc6.1-1.so.2:
cannot open shared object file: No such file or directory.


This bug can be reproduced always.

CUSTOMER WORKAROUND :
Copy older libstdc++.so by hand from older gcc package.
(Review ID: 147011) 
======================================================================

                                    

Comments
EVALUATION

There are multiple issues surrounding libstdc++.so, moving to use a different
gcc to build JDK doesn't solve all of the problems - unless we can provide 
binaries for every possible gcc version. We'd like to keep a single binary 
build to simplify testing and deployment, so that's not what we want to do. 

We've implemented a couple of changes in 1.4.2 to solve the compatibility
issues and they were put back by different bug IDs. But since this bug is 
one of the top bugs on JDC, here I'll explain the changes and possible 
workarounds before 1.4.2 is released:

1. JDK requires libstdc++-libc6.1-1.so.2

PROBLEM

JDK is linked with libstdc++-libc6.1-1.so.2, and many new Linux distributions
do not have this library installed by default. As the result, you'll see
error message similar to this:

Error: failed ../jre/lib/i386/client/libjvm.so. because libstdc++-libc6.1-1.so.2: cannot open shared object file: No such file or directory.

FIX

To fix this, we statically link libstdc++.so in JDK, so there is no requirement
on user side to have the library installed. It is implemented for HotSpot VM
in 1.4.1 and for the rest of JDK in 1.4.2.

WORKAROUND

User has to install libstdc++-libc6.1-1.so.2 manually. For example, Redhat
Linux has this library in the "compat-libstdc++" package.

2. Incompatibility in C++ ABI

PROBLEM

The binary interface of libstdc++ has been constantly changing in the past
two years, if user JNI code is written in C++ and not compiled by the same
compiler we used to build JDK (i.e. egcs-2.91), at runtime, there will be
two incompatible libstdc++.so being loaded into memory at the same time.

That isn't healthy, in particular, when two libraries have common symbols
(yes, there are many common symbols between different libstdc++.so), symbols
from the first loaded library will be used to resolve all references. This can
lead to crashes or aborts.

FIX

We really can't fix imcompatibility issues for C++ ABI. What we did for
1.4.2 is just trying to work around the problem. Please see 4776723 and
4706607. We statically link the C++ runtime in JDK and enabled linker
script to hide symbols from libstdc++ and other internal symbols. As the
result, those symbols become invisible to JNI code, and when some native
code needs to call into C++ runtime, the call will be resolved with
the appropriate libstdc++.so. There are still two libstdc++.so being
loaded at the same time, but it should be benign.

In the meantime, user could try one of the following workarounds:

WORKAROUNDS

+ If you have access to the source code of the JNI library and can rebuild
  it, build it on Redhat 6.2. Then the JNI bits will be linked against the
  same C++ runtime that is being used by JDK, and there will be no symbol
  conflicts. This is the safest solution. You can continue to deploy on
  non-RH-6.2 systems (e.g. Redhat 7.x) and have the added benefit that you
  can deploy on earlier platforms.

+ If you can rebuild the library, but can't build it on Redhat 6.2,
  you can use gcc (not g++) to link the binary, you also need to add
  "-Wl,-Bsymbolic -Wl,-Bstatic -lstdc++, -Wl,-Bdynamic" to the command
  line to statically link with the correct libstdc++ and force linker
  to resolve symbols within the library.

+ If for some reason you cannot rebuild the library, you can preload
  the libstdc++.so that is used by your JNI library. You need to run
  "ldd" first on the library to figure out which libstdc++.so will
  be used, then set LD_PRELOAD to include it. This will cause all
  reference to the C++ runtime to be resolved by the preloaded libstdc++.so.
  This can work around most of the problems, and easy to test.

3. Change in C++ mangling rules

PROBLEM

This is actually part of the ABI changes, but since it has a different
symptom and requires different solution, I list it here separately.

With gcc-3.x, the format for a mangled C++ symbol has changed.  For example,
A::foo(int) is encoded as foo__1Ai by gcc-2.x and as _ZN1A3fooEi by gcc-3.x.
If library X imports C++ symbols from library Y and X is built by gcc-2.x,
now you try to run X with a version of Y that is built by gcc-3.x, you'll
get errors on unsolved symbols; because, for example, X is trying to call
foo__1Ai but Y only provides _ZN1A3fooEi. That is what's happening when
you use java plugin in a browser built by gcc-3.x.

FIX

Don't import C++ symbols directly.

WORKAROUNDS

No.

###@###.### 2002-12-16

--------------------------------------------------------

One more ABI compatibility problem. This time it's with Java plugin only.
Apparently in a C++ object which contains virtual functions, its vptr
points to different place when the code is compiled by gcc-2.9x or gcc-3.x.
This is causing problems in Java plugin (see 4687814) because the OJI
interface is using virtual functions extensively between browser (Mozilla) 
and plugin. There is really no way to fix it other than building the plugin 
with gcc-3.2 (or modifying OJI). This is not a problem with other part
of JDK because we don't use virtual functions to communicate with other
libraries.

###@###.### 2003-03-31

--------------------------------------------------------

So here's what we did in Mantis in an attempt to resolve the gcc compatibility
issues:

(1) C++ runtime (aka libstdc++.so) is statically linked with JDK. When you 
    install JDK or JRE, there is no requirement on the backward compatibility
    library libstdc++-libc6.1-1.so.2

(2) Linker mapfiles and versioning have been enabled. C++ symbols due to 
    static link in (1) and also VM internal symbols are now hidden. This is
    necessary to avoid symbol conflicts between different libstdc++ versions.
    But if you try to access VM internal symbol directly in a program, it 
    will not work with 1.4.2. This change can also improve VM performance
    (due to smaller dynamic symbol table), but at a cost of less accurate 
    symbol lookup after crash.

(3) 1.4.2 will have two libjavaplugin_oji.so files, one is built by gcc-2.91
    and the other one by gcc-3.2. If you are using gcc-3 built mozilla, use
    the one in "jre/plugin/i386/ns610-gcc32" directory. Otherwise, use the
    one in "jre/plugin/i386/ns610"

I'm now closing this one as "fixed". Mantis-beta should be out very soon, and
the work (except (3) because it has other dependencies) has been backported
to 1.4.1_03. If you continue to see compatibility problems, feel free to let 
me know (hui dot huang at sun dot com).

###@###.### 2003-03-31

---------------------------------------------------------

###@###.### suggested to change bug status to duplicate, as
there is no code change associated with this bug ID. I have marked it as a
duplicate of 4687814 to make it easier tracking code changes.

But please note, this bug is really not a duplicate of 4687814. It's
a tracking bug for C++ compatibility issues, 4687814 is only part of
the problem. Fixes have been delivered under the following bug IDs:

         4776723, 4706607, 4665166, 4687814, 4791798

###@###.### 2003-04-01
                                     
2003-04-01



Hardware and Software, Engineered to Work Together