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

JNI program crashes with an access violation when JIT enabled

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2
    • Resolution: Won't Fix
    • Affects Version/s: 1.2.0, 1.2.2
    • Fix Version/s: None
    • Component/s: vm-legacy

      Description

      we are developing the new Java GUI for [company xyz].

      Unfortunately, the JIT compiler delivered with the
      Sun VM does not seem to work for our program (it crashes,
      see details below).

      Turning off the JIT helps as a workaround (painfully slow,
      though), as does using a different VM (the Symantec VM,
      for example, works well).

      This currently results in all our demos being shown
      with either the Symantec or the IBM VM. We feel that it
      might be in our mutual interest to resolve
      this matter as quickly as possible.

      The program is designed as a mixed C/Java application.
      The display components are all written in java, while
      the communication and protocol handling is partly C/C++.
      We therefore have quite a lot (maybe an unusual lot ?)
      of JNI calls.

      Everything works fine if the JIT compiler is turned off.
      With the JIT compiler enabled, the program crashes with
      an access violation.

      By debugging and tracing, we found out that one argument
      given to a native method in java is not correctly passed
      to the C method (the access violation occurs as a result
      in our application specific coding). Most surprisingly,
      this seems to happen only after a couple of successful
      invocations of the same method, even with the same parameter
      values.

      The following trace prints the method calls and parameters
      immediately before the JNI call (from java, trace key "JNI")
      and within the JNI call (from C, trace key "C_JNI"). The
      parameters are identical except for the very last call (after
      which the program crashes).

      Without JIT, all parameters are passed correctly (resulting
      in identical trace outputs) and the program continues to run.

      When we run the program with the VM delivered with Symantec
      Cafe 3.0 (version 1.1.7, with symcjit.dll, 3.10.088), the JIT
      works just fine.

      To help you analyse the problem, we have provided trace output
      from our program and a running example, using a dummy program
      instead of a real application server.

      Please find attached:
      - a typical trace output
      - the java code where the JNI is called
      - the C++ code where the JNI calls into our C library
      - instructions to reproduce the problem

      We are using the JDK 1.2.2 preview (java version "1.2.2"
      Classic VM (build JDK-1.2.2-U, native threads, symcjit))
      under Windows NT 4.0 (4.0.1381), but the same problem seems to
      occur in most of the previous JDK releases, too.

      We hope to get this solved fast, because it effectively prevents
      us from using the Sun VM for the time being.

      ############################ Trace output ########################

      JNI: jniCreateAutomationResultList(95755632)
      C_JNI: jniCreateAutomationResultList, 95755632)
      JNI: jniAddResult(97561872, 2)
      C_JNI: jniAddResult, 97561872, 2)
      JNI: jniAddResult(97561872, 4)
      C_JNI: jniAddResult, 97561872, 4)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872, 5)
      C_JNI: jniAddResult, 97561872, 5)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 97561872)
      JNI: jniAddResult(97561872)
      C_JNI: jniAddResult, 117354100)

      ############################ java code ###########################

      class JniAutomationResultList
      {
          private long mAutomationResultListId;

          ...

          //-----------------------------------------------------------
          private void addResult(Object resultObject)
          {

              ...

              // trivial case
              if (resultObject == null)
              {
                  if (T.race("JNI"))
                      T.race("JNI", "jniAddResult("
                             + mAutomationResultListId + ")");
                  jniAddResult(mAutomationResultListId);
              }

              ...
          }
          
          ...

          //-----------------------------------------------------------
          private native synchronized void
              jniAddResult(long automationResultListId);

          ...
      }

      ############################ C code ############################

      ...

      JNIEXPORT void JNICALL
        Java_com_xyz_platin_parser_JniAutomationResultList_jniAddResult__J
        (JNIEnv *jEnv, jobject jObject, jlong automationResultListId)
      {
          ...
          
          Trace(JNI) << "jniAddResult" << ", "
                     << (long) automationResultListId
                     << ")" << endl;
       
         ...

      }

      ##################### reproducing the problem #################

      In order to reproduce the problem, please unpack the attached zip
      file into an empty directory. Using two command windows, start the
      server in one window by calling "server.bat" (this will start a
      dummy application server that listens locally on port 3200) and the
      GUI in the other window by calling "client.bat".

      If the program runs correctly, you should see a logon screen. Push
      any button and an error message about incorrect logon data should
      appear.

      If the program crashes, you should see a trace output similar to the
      example above.

      Removing the "-t JNI:C_JNI" argument from the command line in
      "client.bat" will disable the (rather noisy) trace output.

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              tbell Tim Bell
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Imported:
                Indexed: