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

libjsig.so does not allow system interrupts to be chained into C++ exceptions

XMLWordPrintable

    • x86
    • linux

      FULL PRODUCT VERSION :
      java version "1.6.0_12"
      Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
      Java HotSpot(TM) Server VM (build 11.2-b01, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Red Hat Enterprise Linux Server release 5.3 (Tikanga)


      EXTRA RELEVANT SYSTEM CONFIGURATION :
      This was tested on other RHEL Linux systems&machines, 32 or 64 bit, all failed.
      It is supposed to work on Solaris machines (I did not test myself, I do not have any Solaris machine, but some collaborators told me they used to do it in their former job).

      A DESCRIPTION OF THE PROBLEM :
      The problem happens when using JNI and setting a new interrupt handler in C++ code to throw a C++ exception in place of the system interrupt.
      The exception is not handled correctly by libjsig.so. Instead of having the exception propagated through C++ code (and allowing C++ to catch it), java exists complaining about an uncatched c++ exception.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1 - Create a InterruptTest.java file containing the code provided in the "Source code for an executable test case:" section of this bug. Its aim is just to call a native C++ function.
      2 - Compile it with: javac MyInterrupt; javah -jni MyInterrupt
      3- Create a native code file MyInterrupt.cpp containing the code provided in the "Source code for an executable test case:" section of this bug. This code sets the SIGSEGV signal handler and have it throw a C++ exception in case a system interrupt is raised. The JNI native call have an illegal access memory surrounded by try/catch blocs to catch the exception thrown by the interrupt handler.
      4- Compile the native code with: g++ -m32 -fexceptions -fnon-call-exceptions -fPIC -shared -o libMyInterrupt.so MyInterrupt.cpp
      5- run: LD_PRELOAD=libjsig.so java MyInterrupt
      6- the java VM exits complaining about the C++ exception, I was expecting it to pass the exception onto the native code.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Using the code test case below, the text that should be printed is:"
      Trying a very bad access
      Interrupted..
      Exception catched!
      Nice termination
      "
      This is what gets printed if I do not use libjsig.so but obviously not using jsig is not an alternative since in this case the interrupt caused by jvm errors would not be handled properly.
      ACTUAL -
      Using the code test case below, the actual output is:"
      Trying a very bad access
      Interrupted..
      terminate called after throwing an instance of 'char const*'
      zsh: abort LD_PRELOAD=libjsig.so java MyInterrupt
      "

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      File MyInterrupt.java:
      --->
      class MyInterrupt {
           private native void run();
           public static void main(String[] args) {
               new MyInterrupt().run();
           }
           static {
               System.loadLibrary("MyInterrupt");
           }
       }

      <--

      File MyInterrupt.cpp
      -->
      #include <jni.h>
      #include "MyInterrupt.h"
      #include <stdio.h>
      #include <signal.h>

      // Initialization of the handlers at library loading time
      struct Initialiser{
      Initialiser(){
      struct sigaction sa = {0};
      sa.sa_handler = throwCppExcept;
      if(sigaction(SIGSEGV,&sa, NULL) == -1){
      printf("Error installing handler\n");
      }
      }
      };
      Initialiser i;// initialisation done when constructing this object

      // native function called by Java/JNI
      JNIEXPORT void JNICALL Java_MyInterrupt_run(JNIEnv *, jobject){
      try{
      int* p=NULL;
      printf("Trying a very bad access\n");
      *p = 1;
      }catch(...){
      printf("Exception catched!\n");
      }
      printf("Nice termination\n");
      }
      <--
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      No workaround known.

            Unassigned Unassigned
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: