United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6474073 (process) Runtime.exec() creates zombies (sol)
JDK-6474073 : (process) Runtime.exec() creates zombies (sol)

Details
Type:
Bug
Submit Date:
2006-09-22
Status:
Closed
Updated Date:
2011-03-07
Project Name:
JDK
Resolved Date:
2011-03-07
Component:
core-libs
OS:
solaris_2.5.1,linux
Sub-Component:
java.lang
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports
Backport:
Duplicate:
Duplicate:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.6.0-beta2"
Java(TM) SE Runtime Environment (build 1.6.0-beta2-b86)
Java HotSpot(TM) 64-Bit Server VM (build 1.6.0-beta2-b86, mixed mode)

A DESCRIPTION OF THE PROBLEM :
My application uses Runtime.exec() to execute external commands (shell scripts, system binaries).

If the external command does not exist an IOException is thrown and a defunct process (zombie) is left behind.

This issue does not appear in java version 1.5.0

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
call Runtime.exec() with a non-existing file. e.g. 'Runtime.exec("no-such-file")'

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Checking the running processes does not show any defunct (zombie) process
ACTUAL -
After Runtime.exec runs, a defunct process is left behind, which is only removed when the JVM itself exits.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.*;
public class Zombie{
    private static void check() {
        try {
            Process p = Runtime.getRuntime().exec("ps -ef");
            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            while (true) {
                line = br.readLine();
                if (line == null)
                    break;
                if (line.indexOf("defunct") > 0) {
                    System.out.println(line);
                }
            }
        } catch (IOException e) { }
    }
        
    
    public static void main(String[] args) {
        System.out.println("check before");
        check();
        try {
            Runtime.getRuntime().exec("no-such-file");
        } catch (IOException e) { }
        System.out.println("check after");
        check();
    }
}
---------- END SOURCE ----------

                                    

Comments
EVALUATION

An excellent find by the submitter.

Introduced in b81 by the fixes for

4052517: (process) Runtime.exec won't execute programs belonging to other groups on Unix
4811767: (process) Runtime.exec should throw IOException when workdir does not exist (Unix)
5033302: (process) Can't execute Solaris NFS programs with uid>64k on Linux-amd64

The following looks like the fix:

--- /tmp/geta13483	2006-09-22 04:00:00.418839800 -0700
+++ UNIXProcess_md.c	2006-09-22 03:55:15.499011000 -0700
@@ -571,14 +571,15 @@
 	_exit(-1);
     }
 
     /* parent process */
 
     close(fail[1]); fail[1] = -1; /* See: WhyCantJohnnyExec */
     if (read(fail[0], &errnum, sizeof(errnum)) != 0) {
+	waitpid(resultPid, NULL, 0);
 	throwIOException(env, errnum, "Exec failed");
 	goto Catch;
     }
 
     (*env)->SetIntField(env, stdin_fd,  IO_fd_fdID, in [1]);
     (*env)->SetIntField(env, stdout_fd, IO_fd_fdID, out[0]);
     (*env)->SetIntField(env, stderr_fd, IO_fd_fdID, err[0]);
                                     
2006-09-22
EVALUATION

Apparently, zombies only show up in the ps output on solaris.
On linux, some mechanism causes zombies to be removed from the 
output of ps.
                                     
2006-09-22



Hardware and Software, Engineered to Work Together