United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4750978 : (process) Runtime.exec/Process.waitFor hang when a new directory is given (lnx)

Details
Type:
Bug
Submit Date:
2002-09-20
Status:
Resolved
Updated Date:
2002-12-17
Project Name:
JDK
Resolved Date:
2002-12-17
Component:
core-libs
OS:
linux
Sub-Component:
java.lang
CPU:
x86
Priority:
P2
Resolution:
Fixed
Affected Versions:
1.4.1
Fixed Versions:
1.4.2 (b11)

Related Reports
Relates:
Relates:

Sub Tasks

Description

Name: nt126004			Date: 09/20/2002


FULL PRODUCT VERSION :
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)
Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)


FULL OPERATING SYSTEM VERSION : RedHat 7.2, kernel 2.4.7-10,
glibc-2.2.4-13


A DESCRIPTION OF THE PROBLEM :
This appears to be specific to Linux.
Repeated calls to Runtime.exec(command,envp,dir) method
eventually cause the JVM to hang. This does not happen with
the Runtime.exec(command) method. Also this does not happen
in J2SDK 1.4.0

Depending on the code used, this may happen when reading
input or error streams from the created process, or during
the exec call itself, or during a Process.waitFor() call.

REGRESSION.  Last worked in version 1.4

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Choose one of the Java programs attached
2. Compile and run. You may need an environment with fairly
fast terminal IO, eg. text console rather than X
3. Output should stop after no more than 5-10 seconds
4. Reinstate the commented out exec call, and comment out
the previous one.
5. Recompile, rerun
6. Output continues (apparently) indefinitely


EXPECTED VERSUS ACTUAL BEHAVIOR :
JVM hangs rather than executing indefinitely.

REPRODUCIBILITY :
This bug can be reproduced always.

ERROR MESSAGES :
here is a thread dump from a hung run -
Full thread dump Java HotSpot(TM) Client VM (1.4.1-b21 mixed mode):

"process reaper" daemon prio=1 tid=0x0x81552e0 nid=0x2067 runnable [4c76e000..4c76e860]
        at java.lang.UNIXProcess.waitForProcessExit(Native Method)
        at java.lang.UNIXProcess.access$1500(UNIXProcess.java:20)
        at java.lang.UNIXProcess$2.run(UNIXProcess.java:127)

"Signal Dispatcher" daemon prio=1 tid=0x0x808d920 nid=0x2011 waiting on condition [0..0]

"Finalizer" daemon prio=1 tid=0x0x8086d68 nid=0x200e in Object.wait() [4c3f2000..4c3f2860]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x441f0490> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111)
        - locked <0x441f0490> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=1 tid=0x0x8086120 nid=0x200d in Object.wait() [4c371000..4c371860]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x441f0380> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:426)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:113)
        - locked <0x441f0380> (a java.lang.ref.Reference$Lock)

"main" prio=1 tid=0x0x8051e58 nid=0x200a runnable [bfffd000..bfffd5d8]
        at java.io.FileInputStream.readBytes(Native Method)
        at java.io.FileInputStream.read(FileInputStream.java:191)
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:183)
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:222)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:277)
        - locked <0x4425fa20> (a java.io.BufferedInputStream)
        at java.io.FilterInputStream.read(FilterInputStream.java:90)
        at execbust.main(execbust.java:20)

"VM Thread" prio=1 tid=0x0x8082ee0 nid=0x200c runnable 

"VM Periodic Task Thread" prio=1 tid=0x0x808c450 nid=0x200f waiting on condition 
"Suspend Checker Thread" prio=1 tid=0x0x808ceb8 nid=0x2010 runnable 

---------- BEGIN SOURCE ----------
// This example tries reading the input and error streams. JVM hangs while
// reading the input/error streams, in a consistent way
class execbust
{
  public static void main(String args[])
  {
    try {
      File file = new File(".");
      byte iobuf[] = new byte[1024];
      int bytes;
      while (true) {
        InputStream errStream,inStream;
        System.out.print('E');
        Process proc = Runtime.getRuntime().exec("pwd",null,file);
//        Process proc = Runtime.getRuntime().exec("pwd");
        System.out.print('e');
        inStream = proc.getInputStream();
        errStream = proc.getErrorStream();
        while ((bytes = inStream.read(iobuf)) > 0)
          System.out.write(iobuf,0,bytes);
        while ((bytes = errStream.read(iobuf)) > 0)
          System.err.write(iobuf,0,bytes);
        
        System.out.print('W');
        proc.waitFor();
        System.out.print('w');
  
        System.out.print('C');
        errStream.close();
        inStream.close();
        proc.getOutputStream().close();
        System.out.print('c');
      }
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}

import java.io.*;

// All streams are just closed after use; no reading/writing. The JVM hangs
// in an unpredicatable way, sometimes in exec(), sometimes in waitFor()
class execbust2
{
  public static void main(String args[])
  {
    try {
      File file = new File(".");
      while (true) {
        System.out.print('E');
        Process proc = Runtime.getRuntime().exec("pwd",null,file);
//        Process proc = Runtime.getRuntime().exec("pwd");
        System.out.print('e');
        
        System.out.print('W');
        proc.waitFor();
        System.out.print('w');
  
        System.out.print('C');
        proc.getOutputStream().close();
        proc.getInputStream().close();
        proc.getErrorStream().close();
        System.out.print('c');
      }
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}
---------- END SOURCE ----------

CUSTOMER WORKAROUND :
None found as yet

Release Regression From : 1.4
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

(Review ID: 164718) 
======================================================================

                                    

Comments
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
mantis-beta

FIXED IN:
mantis-beta

INTEGRATED IN:
mantis-b11
mantis-beta


                                     
2004-06-14
EVALUATION

The root problem is that when a new working directory is specified in an
invocation of Runtime.exec the conversion of the pathname string to a char* in
the underlying native code is done after forking the child process, which can
cause the child process to deadlock with the parent.  The fix is to do this
conversion before forking the child.

The fix is identical to one already applied to the Solaris version of this code
(4486978), though the failure mode on Solaris is more catastrophic.

-- ###@###.### 2002/11/22
                                     
188-10-11 0



Hardware and Software, Engineered to Work Together