1

When I run this code and the call graph is really large, the program prints to the last line that opt outputs and is blocked at readLine, even though there is nothing left. Anyone know what the problem is? opt -print-callgraph file sends the call graph to the error stream. I tried executing opt -print-callgraph file 2> callgraph so that I can read from a file instead but it complains that there are too many positional arguments.

Oddly enough, the code runs fine for call graphs that are small in size.

I tried using ProcessBuilder as well but I get the same problem.

Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("opt -print-callgraph " + file);
BufferedReader in = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String s = null;
try {
    // Gets stuck at readLine after printing out the last line.
    while ((s = in.readLine()) != null) {
        System.out.println(s);
    }
} catch (Exception e) {
    e.printStackTrace();
} finally {
    in.close();
}
Oak
  • 26,231
  • 8
  • 93
  • 152
gruuuvy
  • 2,028
  • 4
  • 31
  • 52

1 Answers1

2

You need to read both streams, in separate threads, or else merge them so you're reading them both at the same time. Otherwise the process can block if output is unconsumed. In this case there must be unconsumed output in stdout which is blocking the process, which means it won't finish, which means it won't close stderr, which means reading stderr will block.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • An example of reading both streams would look exactly the same as an example of reading one of them, as you already have above, only it would happen twice. An example of starting a thread is hardly required. An example of calling the method that merges the streams is hardly required either, as it is only one line that calls a documented API. I suggest you look it up. – user207421 Mar 29 '14 at 23:49