Other | Other | Other |
---|---|---|
1.3.0_02 02Fixed | 1.3.1Fixed | 1.4.0Fixed |
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
Name: rlT66838 Date: 06/13/2000 java version "1.3.0" Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-beta) Java HotSpot(TM) Client VM (build 1.3-beta, mixed mode) I have a problem with signals on JDK 1.3.0 beta on Solaris 7 using the Hostpot VM (both client and server). When a thread attaches to the JVM it seems that its signal mask is changed. This did not happen with JDK 1.2.2 on Solaris nor does it happen with Sun JDK 1.3.0 beta on Linux or IBM JDK 1.3.0 alpha on Linux. So, I consider this to be a bug in JDK 1.3.0 beta on Solaris. Please find attached a program to reproduce this. It will run a long loop. Hitting Ctrl-C will interrupt the program. On Solaris JDK 1.3 this will happen abruptly, because a thread other than main will get the signal. On any other JDK, the main thread will exit with a message. On the machine tested uname -a gives: SunOS sunsite.pub.ro 5.7 Generic_106541-11 sun4u sparc SUNW,Ultra-Enterprise Dummy Java class to call from native code: public class Prog { public static void main(String args[]) { for(int i=1; i<1000000; i++) System.out.println("Java class invoked: " + args[0] + " -> " + i); } } C program: #include <jni.h> #include <dlfcn.h> #include <pthread.h> #include <signal.h> #include <errno.h> void *handle; char* error; jint (JNICALL *jni_create_java_vm)(JavaVM **, JNIEnv **, void *) = NULL; JavaVM *jvm; void loadJVM() { handle = dlopen(JVM_SO, RTLD_NOW|RTLD_GLOBAL); if (!handle) { fputs (dlerror(), stderr); fputs (" : 2\n", stderr); exit(1); } fputs("Will load JVM...\n", stderr); jni_create_java_vm = dlsym(handle, "JNI_CreateJavaVM"); if ((error = dlerror()) != NULL) { fputs(error, stderr); fputs (" : 3\n", stderr); exit(1); } fputs("JVM loaded okay.\n", stderr); } JNIEnv* initJVM() /* The JDK1.2 way of doing it */ { JNIEnv *env = NULL; JavaVMInitArgs vm_args; JavaVMOption options[1]; jint res; options[0].optionString = "-Djava.class.path=."; /* user classes */ vm_args.version = JNI_VERSION_1_2; vm_args.nOptions = 1; vm_args.options = options; vm_args.ignoreUnrecognized = JNI_FALSE; fputs("Will create JVM...\n", stderr); res = (*jni_create_java_vm)(&jvm, &env, &vm_args); if (res < 0) { fprintf(stderr, "Can't create Java VM: %d\n", res); exit(1); } fputs("JVM created OK!\n", stderr); return env; } void doStuff(JNIEnv *env) { jclass cls; jmethodID mid; jstring jstr; jobjectArray args; cls = (*env)->FindClass(env, "Prog"); if (cls == 0) { fprintf(stderr, "Can't find Prog class\n"); exit(1); } mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V"); if (mid == 0) { fprintf(stderr, "Can't find Prog.main\n"); exit(1); } jstr = (*env)->NewStringUTF(env, "from C!"); if (jstr == 0) { fprintf(stderr, "Out of memory\n"); exit(1); } args = (*env)->NewObjectArray(env, 1, (*env)->FindClass(env, "java/lang/String"), jstr); if (args == 0) { fprintf(stderr, "Out of memory\n"); exit(1); } (*env)->CallStaticVoidMethod(env, cls, mid, args); } JNIEnv* atchJVM() { JNIEnv *env = NULL; int res; res = (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL); if (res < 0) { fprintf(stderr, "Thread attach failed\n"); return NULL; } return env; } void* somethr(void* x) { JNIEnv *env; fprintf(stderr, "Some thread will create JVM.\n"); loadJVM(); env = initJVM(); fprintf(stderr, "Some thread will call Java.\n"); doStuff(env); if((*jvm)->DetachCurrentThread(jvm) != 0) fputs("Error: thread not detached!\n", stderr); fprintf(stderr, "Some thread exiting.\n"); return env; } int main() { JNIEnv *env; sigset_t set; pthread_t thr1; pthread_attr_t attr; int ss=0, sig; fprintf(stderr, "Main thread will set signal mask.\n"); sigemptyset(&set); sigaddset(&set, SIGPIPE); sigaddset(&set, SIGTERM); sigaddset(&set, SIGHUP); sigaddset(&set, SIGINT); pthread_sigmask(SIG_BLOCK, &set, NULL); pthread_attr_init(&attr); ss = 1024 * 1024; pthread_attr_setstacksize(&attr, ss); pthread_attr_getstacksize(&attr, &ss); fprintf(stderr, "Stack size: %d\n", ss); pthread_create(&thr1,NULL,somethr,NULL); sigemptyset(&set); sigaddset(&set, SIGTERM); sigaddset(&set, SIGHUP); sigaddset(&set, SIGINT); fprintf(stderr, "Main thread waiting for signal.\n"); do { int err; sig = 0; err = sigwait(&set, &sig); if (err != 0 && err != EINTR) { fprintf(stderr, "main: sigwait() error: %s\n", strerror(err)); } else { fprintf(stderr, "main: sigwait() got: %d\n", sig); exit(0); } } while (sig != SIGTERM && sig != SIGINT); pthread_join(thr1, NULL); dlclose(handle); fputs("Main thread exiting.\n", stderr); } (Review ID: 106080) ======================================================================
|