Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4345157

JDK 1.3.0 alters thread signal mask

    XMLWordPrintable

Details

    • 02
    • sparc
    • solaris_7
    • Verified

    Backports

      Description



        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)
        ======================================================================

        Attachments

          Issue Links

            Activity

              People

                kbr Kenneth Russell (Inactive)
                rlewis Roger Lewis (Inactive)
                Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: