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

(process) Intermittent hang on piped input (lnx)

XMLWordPrintable

    • b11
    • x86
    • linux



      Name: rmT116609 Date: 10/15/2002


      FULL PRODUCT VERSION :
      java version "1.4.1"
      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 :
      Linux kernel 2.2.14-6.1.1, also seen on 2.2.16 glibc-2.1.3-26



      A DESCRIPTION OF THE PROBLEM :
      When using Runtime.exec in java1.4.1 on an external program
      that needs to read standard input, the program will hang on
      a pipe read about 50% of the time. Under 1.4, this never
      occurred. Since the external program never consumes its
      input, it never exits or performs its work and thus
      Process.waitFor will hang.

      REGRESSION. Last worked in version 1.4

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. compile the attached test program (client JVM)
      2. run repeatedly under java1.4.1
      3. should hang within a few runs and hang about 50% time
      overall.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      When the program is working correctly (java 1.4,
      java1.3.1), it will print the exit code and then exit.
      When it is failing it will hang with no exit code printed.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      No error message. Program hangs.

      REPRODUCIBILITY :
      This bug can be reproduced often.

      ---------- BEGIN SOURCE ----------
      import java.io.*;

      /**
       * This class demonstrates a regression in java1.4.1 in the handling of
       * the Process OutputStream (exec'd process stdin). main executes
       * to completion 100% of the time in java1.4, but about only about 50%
       * of the time under 1.4.1. Issue exists for client JVM, Linux Redhat 6.2
       * not sure about other variants of Linux or other Os, or server JVM.
       */
      public class ExecRegression
      {
          private static final String CAT = "/bin/cat";

          public static void main(String[] args)
          {
            /*
             * Execute /bin/cat supplying two lines of input. cat should
             * read the input lines and copy them to stdout. On completion,
             * p.waitFor should return and the exit status is printed and this
             * program exits. Under 1.4.1, cat sometimes gets stuck on a pipe
             * read and never terminates.
             */
            try {
              Process p = Runtime.getRuntime().exec(new String[] { CAT } );
              String input = "This is Line 1\nThis is Line 2\n";
              StringBufferInputStream in = new StringBufferInputStream(input);
              // create threads to handle I/O streams
              IO ioIn = new IO("stdin", in, p.getOutputStream());
              IO ioOut = new IO("stdout", p.getInputStream(), System.out);
              IO ioErr = new IO("stderr", p.getErrorStream(), System.err);

              // wait for process to exit
              int status = p.waitFor();
              System.out.println(status);
              System.exit(status);
           } catch (Exception e) {
              e.printStackTrace();
           }
          }

          private ExecRegression() {}

          /**
           * Handle IO. Thread is started in constructor.
           */
          static class IO extends Thread {

              private InputStream in;
              private OutputStream out;

              IO(String name, InputStream in, OutputStream out)
              {
                  this.in = in;
                  this.out = out;
                  setName(name);
                  start();
              }

              public void run() {
                  try {
                      int c;
                      while ((c = in.read()) != -1) {
                          out.write(c);
                      }
                      out.flush();
                  } catch (IOException e) {
                  } finally {
                      if (!System.out.equals(out) && !System.err.equals(out)) {
                          // Note: in order to get an exec'd java process to
                          // see EOF on input, it is necessary to close stdin
                          if (out != null)
                              try { out.close(); } catch (Exception e) {}
                      }
                  }
              }
          }
      }


      ---------- END SOURCE ----------


      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: 165706)
      ======================================================================

            mr Mark Reinhold
            rmandalasunw Ranjith Mandala (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: