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

(process) Process.destroy() can kill wrong process (Unix)

XMLWordPrintable

    • b03
    • generic
    • generic
    • Not verified

        The current implementation of java.lang.Process.destroy() is incorrect.
        Now it is possible to call destroy and cause some other process to be terminated.

        Current java.lang.Process implementation is:

        --- src/solaris/native/java/lang/UNIXProcess_md.c ---
        JNIEXPORT void JNICALL
        Java_java_lang_UNIXProcess_destroyProcess(JNIEnv *env, jobject junk, jint pid)
        {
           kill(pid, SIGTERM);
        }
        --- src/solaris/native/java/lang/UNIXProcess_md.c ---


        --- src/solaris/classes/java/lang/UNIXProcess.java.linux ---
           public void destroy() {
               destroyProcess(pid);
               try {
                   stdin_stream.close();
                   stdout_stream.close();
                   stderr_stream.close();
               } catch (IOException e) {
                   // ignore
               }
           }
        --- src/solaris/classes/java/lang/UNIXProcess.java.linux ---

        As result, the following situation is possible:

        Thread1 | Thread2
        ----------------------------------------------------------------
        createProcess |
        process.pid=X |

        process.waitFor() |
        process has been terminated |
                                    |
                                    |
                                    | createProcess
                                    | process.pid=X (I know that OS is supposed to avoid assigning same pid for some time but ...)
        process.destroy() |
        -> kill(X, SIGTERM) |
                                    | got signal and terminated with -1 (according to Java_java_lang_UNIXProcess_waitForProcessExit)
                                    |
        ----------------------------------------------------------------


        It would be better if 'destroyProcess(pid)' will be called only in case the process has not been terminated yet.

        Something like:
           public void destroy() {
               synchronized(this)
               {
                   if (!hasExited)
                       destroyProcess(pid);
               }

               try {
                   stdin_stream.close();
                   stdout_stream.close();
                   stderr_stream.close();
               } catch (IOException e) {
                   // ignore
               }
           }


        I will attach the test case after it will be ready.

              martin Martin Buchholz
              epavlova Ekaterina Pavlova
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: