Re: Process.exec() problem - more details
Peter Lovell <[email protected]> Fri, 15 Jul 2005 18:23:52 -0400
| Newsgroups | gmane.comp.java.vm.sablevm.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi all,
I have been digging into this more extensively, especially today.
From what I can see, the root cause seems to be a failure in the
wait/notify process in and around ProcessThread.run and
Process.waitFor in VMProcess.java
What I see is that a child process is created (spawn, nativeSpawn
etc) and runs to completion. It is reaped by nativeReap (called from
ProcessThread.run) and then the termination activity is done. This
saves exitValue in the process object, sets the state to TERMINATED
and calls notify() for it.
The main java code has called waitFor() and is waiting for process
termination, with the precise timing of these actions being somewhat
unpredictable due to cpu load etc. But in some cases the waiter (main
thread) never seems to resume. I can't quite pinpoint why, but this
is what is happening. The visible effect is that the main-line code
which called waitFor() to wait for process termination just never
executes again.
I am not sure what is a good way to try to find the root cause here.
It's obviously timing-sensitive so I've been debugging with printf
and friends, especially since it's not very frequent.
I don't really want to get into thinlocks and fatlocks (are there
anorexic and obese ones too?) as I'm not really sure of what's
happening there. I realize that I have a sort-of-reproducible case
and I'm happy to try to track the problem down, but I need some
advice on how best to do it.
Just for info, the test cases today are on Mac OS X using dual cpu.
The problem occurs sometime within about 600 tries.
Thanks.....Peter
On Jul 11, 2005, at 1:49 PM, Peter Lovell wrote:
> Hi folks,
> I'm having a problem which I believe to be with exec'ing a process
> and wonder if someone might be able to help. Sometimes another set
> of eyeballs is all it takes.
>
> The problem is an intermittent failure which appears to be a
> deadlock somewhere. The frequency is about two or three times every
> hundred tries. I've appended the java code below (small extract)
> and I can't see any specific problem with it - after all it works -
> most- of the time. Problem is that the call is made to this method
> and the process then remains asleep. In a few instances, the
> process list shows a zombie process...
> 31747 pts/49 Z+ 0:00 [who] <defunct>
>
> A few items of background - I see this problem on Linux (SuSE 9.1,
> kernel 2.6.4) and Mac OS X (10.4.1, dual processor G5). There had
> been a couple of instances on Linux 2.4.20 SuSE 8.2 but that does
> not seem to be happening now (more testing needed). Testing on Sun
> Java has never produced a failure, even in days of testing. The
> sable+classpath version is 1.1.8 but comparison of that code with
> current doesn't seem to show any substantial difference in this
> area [I've been trying today to get latest code but sablevm.org
> site is down, unfortunately]
>
> I'm suspecting a subtle timing issue within classpath as the root
> cause. All suggestions gratefully accepted.
>
> Thanks.....Peter
>
>
>
>
> public String[] getConnectedUsers()
> {
> int count = 0;
> int status = -1;
> String s;
> Runtime rt;
> Process p;
> ArrayList return_data = new ArrayList(32);
> String[] cu = new String[0];
>
> try {
> rt = java.lang.Runtime.getRuntime();
> p = rt.exec(("who"));
> status = p.waitFor();
> if (status != 0){
> System.err.println("WARNING: 'who' failed,
> getConnectedUsers failed");
> return cu;
> }
> InputStream ain = p.getInputStream();
> if ( ain == null ){
> System.err.println("WARNING: 'who' missing,
> getConnectedUsers failed");
> return cu;
> }
> BufferedReader in = new BufferedReader( new
> InputStreamReader ( ain ) );
> if ( in == null ) {
> System.err.print("getConnectedUsers: in is null -
> command must have failed, status = ");
> System.err.println(status);
> } else {
> while ( (s = in.readLine()) != null) {
> if ( (s.length() < 1) || (s.substring(0,1).equals
> ("#")))
> continue; //ignore zero-length line (if any)
> and the user count line
> return_data.add(s.substring(0, 9).trim());
> }
> cu = (String[])return_data.toArray(new String
> [return_data.size()]);
> }
> }
> catch (InterruptedException ie) {
> System.err.println("InterruptedException caught");
> }
> catch (IOException ioe) {
> System.err.println("i/o error");
> }
> return cu;
> }
>
>