FULL PRODUCT VERSION :
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Server VM (build 1.6.0_01-b06, mixed mode)
FULL OS VERSION :
Linux xx.xx.xx.xx 2.4.21-40.ELsmp #1 SMP Thu Feb 2 22:22:39 EST 2006 i686 i686 i386 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
We launch java from within a large and complex native application. By the time we launch java, the native app has already loaded a very large number of libraries.
One of these libraries (or some prior memory allocation) has reserved memory through virtual address 0x6000000. This is a problem because the libjvm.so for IA32 is not built PIC-style. Instead it uses the address 0x6000000 as its base. The loader will load the libjvm.so and - since 0x6000000 is already in use - will relocate it. This inevitably then causes a crash.
THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: Yes
THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Take the source code below and compile and run as shown in the comments. For java 6 this crashes, but for java 5 it works. Note that the mmap() is used here to simulate the effect of some other component reserving address 0x6000000 before the JVM is started. This would normally happen as libraries are loaded.
EXPECTED VERSUS ACTUAL BEHAVIOR :
Should run like this:
bash-2.05b$ ./invoke
Before calling JNI_CreateJavaVM : 0.6507886317570846
After calling JNI_CreateJavaVM : 0.6507886317570846
After calling DestroyJavaVM : 0.6507886317570846
Actually does this:
bash-2.05b$ ./invoke
Before calling JNI_CreateJavaVM : 0.6507886317570846
./invoke: relocation error: ./invoke: symbol JNI_CreateJavaVM, version SUNWprivate_1.1 not defined in file libjvm.so with link time reference
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/*
* To build : cc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -L$JAVA_HOME/jre/lib/i386 -L$JAVA_HOME/jre/lib/i386/server -o invoke invoke.c -ljava -lpthread -ljvm -lverify -lm
*
* To run : export LD_LIBRARY_PATH=$JAVA_HOME/jre/lib/i386:$JAVA_HOME/jre/lib/i386/server
* ./server
*
*/
#include <jni.h>
#include <math.h>
#include <sys/mman.h>
#define PATH_SEPARATOR ':'
#define USER_CLASSPATH "."
double testFn() {
double X,Z;
return tan(1000000.0/M_PI);
}
main(int argc, char *argv[]) {
JNIEnv *env;
JavaVM *jvm;
jint res;
JavaVMInitArgs vm_args;
JavaVMOption options[10];
int nOptions;
int i;
mmap(0x6000000, 0x1000000, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_ANONYMOUS|MAP_SHARED, 0, 0);
printf("Before calling JNI_CreateJavaVM : %.16g\n", testFn());
nOptions = 0;
options[nOptions++].optionString = "-Djava.class.path=" USER_CLASSPATH;
vm_args.version = 0x00010002;
vm_args.options = options;
vm_args.nOptions = nOptions;
vm_args.ignoreUnrecognized = JNI_TRUE;
res = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
if (res < 0) {
fprintf(stderr, "Can't create Java VM\n");
exit(1);
}
printf("After calling JNI_CreateJavaVM : %.16g\n", testFn());
(*jvm)->DestroyJavaVM(jvm);
printf("After calling DestroyJavaVM : %.16g\n", testFn());
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Use java 5.
Release Regression From : 6
The above release value was the last known release where this
bug was not reproducible. Since then there has been a regression.