JDK-4694590 : libstdc++ version requirement: Newer version of gcc supplies libstdc++.so.4.0.0
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.4.0,1.4.1
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2002-05-31
  • Updated: 2003-04-01
  • Resolved: 2003-04-01
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
[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

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)

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.

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.

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

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