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

Hang encountered when JNI code to execute system command called multiple times

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2
    • Resolution: Duplicate
    • Affects Version/s: 1.4.0
    • Fix Version/s: 1.4.2_12
    • Component/s: hotspot
    • Labels:
    • Subcomponent:
    • CPU:
      x86
    • OS:
      linux

      Description

      Platform Info
      ---------------
      Red Hat Enterprise Linux AS release 3 (Taroon Update 4)

      (Plese let me know, what other platform information might be required like packages info, etc.). The degree of reproducibility seems to vary with specific mahicnes, but it is reproducible nevertheless.

      Java version used to reproduce this
      -------------------------------------
      java version "1.4.2_04"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_04-b05)
      Java HotSpot(TM) Client VM (build 1.4.2_04-b05, mixed mode)

      Problem Summary
      ----------------

      A simple java program takes on the command line, as input, the number of times a system command that needs to be run.
      In order to run this system command, JNI is used to call native code that does a system() call to execute the command and return the exit code of the command to the Java code.

      When the java program is run, the following things are observed
      Suppose for example the number of times that the system command needs to be run is 20000. Thus internally, the JNI code will be called 20000 times. The following things happen on the given platform, with varying degrees of reproducibility
      1) The execution hangs sometimes after some number of iterations. The process needs to be suspended and killed.
      2) The exit code returned by the system call everytime is different and is not consistently the same exit code, even though its the same command that is executed everytime and the command seems to execute successfully.

      In the following sections, I provide the following
      1) source code
      2) Compilation steps for the above source code
      3) how to run the source code

      SOURCE CODE SUMMARY
      ----------------------------------------
      1. CheckBug.java - this is the java code
      2. CheckBug.h - header file for the JNI native method
      3. debugC.h - header file for native code
      4. debugC.c - JNI native method implementation
      5. mainMeth.c - main entry for native code

      SOURCE CODE
      ----------------------------------------

      Java Program
      -----------------------------------
      CheckBug.java
      -----------------------------------

      public class CheckBug
      {
         static
          {
            System.loadLibrary("hello");
          }

        /**
         * This is a static class so no constructor required
         */
        private CheckBug(){}

         /* executes a system command num no. of times */
         private static void newMethod(int num)
         {
              /* can replace this with other commands as well */
              String linux_hardnofiles_command = "/bin/sh -c \"ulimit -Hn\"";

              for(int i = 0; i < num; i ++)
              {
                System.out.println("iter=" + i + ":");
                runLocalUnixCommand(linux_hardnofiles_command);
              }

       }

         private static void runLocalUnixCommand (String command)
         {
            String sCommand = command;
            int result = 0;
            System.out.println("Command=" + sCommand + ":");
            result = sysFunctionEnglish(sCommand);
            System.out.println("result=" + result + ":");
         }

        public static void main(String[] args)
        {
          try
          {
            Integer oInt = new Integer(args[0]);
            newMethod(oInt.intValue());
          }
          catch(Exception e)
          {
            System.out.println("Exception :" + e.getMessage());
            e.printStackTrace();
          }
        }

        public static native int sysFunctionEnglish(String command);

      }

      --------------------------------------------------------------------
      Native Code
      -----------------------------
      h files
      -----------------------------
      1. CheckBug.h
      -----------------------------
      #include <jni.h>

      #ifndef _Included_CheckBug
      #define _Included_CheckBug
      #ifdef __cplusplus

      extern "C" {

      #endif

      JNIEXPORT jint JNICALL Java_CheckBug_sysFunctionEnglish(JNIEnv *, jclass, jstring);

      #ifdef __cplusplus

      }
      #endif
      #endif

      -----------------------------
      2. debugC.h
      -----------------------------
      // debug
      int sysFunctionImpl(char *cmd);

      -----------------------------
      c files
      -----------------------------
      1. debugC.c
      -----------------------------
      #include <stdio.h>
      #include <sys/types.h>
      #include <sys/uio.h>
      #include <unistd.h>
      #include <fcntl.h>
      #include <signal.h>
      #include <sys/wait.h>
      #include "CheckBug.h"
      #include "debugC.h"

      #define LC_ALL "LC_ALL"
      #define EQUAL "EQUAL"
      #define LANG_C "C"

      /*
       * Class: Java_oracle_sysman_oii_oiip_osd_unix_OiipuUnixOps_sysFunction
       * Method: sysFunctionEnglish
       * Signature: (Ljava/lang/String)
       */

      JNIEXPORT jint JNICALL Java_CheckBug_sysFunctionEnglish
        (JNIEnv *env, jclass cls, jstring command)
      {
      const char *cmnd;
        int status; /* PID of Child Process & Return Status from wait() */
        int wait_status;
        cmnd = (*env)->GetStringUTFChars(env, command, 0);
        status = sysFunctionImpl(cmnd);
        (*env)->ReleaseStringUTFChars(env,command,cmnd);
         wait_status = WEXITSTATUS(status);
         return (jint)wait_status;
      }

      int sysFunctionImpl(char *cmd)
      {
        int status;

        printf("before calling system cmd=%s:\n", (char *)cmd);
        status = system((char *)cmd);
        printf("after calling system result=%d\n", status);

        return status;
      }

      -----------------------------
      2. mainMeth.c
      -----------------------------
      #include "debugC.h"

      // main method
      main(int argc, char* argv[])
      {
        int j = 0;
        char *cmd = "/bin/sh -c \"ulimit -Hn\"";
        for(j = 0; j < 500; j ++)
        {
          sysFunctionImpl(cmd);
        }
      }


      ------------------------------------------
      COMPILATION STEPS
      ------------------------------------------
      Note: all source files are under the same directory
      Suppose $JAVA_HOME represents the java location
        To compile, I used the following steps.
      1. To create .o files
      cc -c -g -I$JAVA_HOME/include -I$JAVA_HOME/include/linux debugC.c mainMeth.c

      2. To create shared library, libhello.so
      cc -shared -o libhello.so debugC.o

      3. To compile jave code
      $JAVA_HOME/bin/javac -classpath `pwd` CheckBug.java


      ------------------------------------------
      EXCECUTION STEPS
      ------------------------------------------

      After the above completion, perform the following steps
      1. Ensure that LD_LIBRARY_PATH containes the current directory, that contains the shared library libhello.so. To do this execute -
      setenv LD_LIBRARY_PATH `pwd`:$LD_LIBRARY_PATH

      2. Now the java program can be run as follows
      $JAVA_HOME/bin/java -classpath `pwd` CheckBug <number of iterations>

      A large number of iterations (upto 20000) maybe required to reproduce the hang.

      Please let me know if more information is required

        Attachments

          Activity

            People

            Assignee:
            minqi Yumin Qi (Inactive)
            Reporter:
            mmma Marvin Ma (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: