Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2141979 | 6u1 | Martin Buchholz | P3 | Resolved | Fixed | b01 |
JDK-2142064 | 5.0u11 | Martin Buchholz | P3 | Resolved | Fixed | b01 |
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.
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.
- backported by
-
JDK-2141979 (process) Process.destroy() can kill wrong process (Unix)
- Resolved
-
JDK-2142064 (process) Process.destroy() can kill wrong process (Unix)
- Resolved