This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][RFA] Reap children on stack trace generation.


There are two related problems I am having with stack trace generation.
 Each invocation of Throwable.printStackTrace() leaves at least one
zombie process.  This was verified on both mipsel-linux and
i686-pc-linux-gnu.

The first problem is that NameFinder.close() destroys() the child
process, but never does waitFor() to reap the child.  There are several
other places where the same thing would happen on errors in the child.

natPosixProcess.cc has a related problem.  First it forks, but if the
exec fails, the child is not reaped.

I don't think it is possible to write a dejagnu testcase to detect the
zombies.

make check in libjava only on i686-pc-linux-gnu gives no new failures.

O.K. to install on mainline?

David Daney
2004-07-06  David Daney  <ddaney@avtrex.com>

	* gnu/gcj/runtime/NameFinder.java (NameFinder): Remove
	unexecutable code from catch block.
	(lookup): Reap child on Process failure.
	(createStackTraceElement): Ditto.
	(demangleName): Ditto.
	(close): Ditto.
	* java/lang/natPosixProcess.cc (startProcess): Reap child on exec
	failure.

Index: gnu/gcj/runtime/NameFinder.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/NameFinder.java,v
retrieving revision 1.7
diff -u -p -r1.7 NameFinder.java
--- gnu/gcj/runtime/NameFinder.java	9 Apr 2004 04:39:24 -0000	1.7
+++ gnu/gcj/runtime/NameFinder.java	6 Jul 2004 06:55:05 -0000
@@ -116,23 +116,24 @@ public class NameFinder
     executable = getExecutable();
     Runtime runtime = Runtime.getRuntime();
     if (demangle)
-    {
-      try
-	{
-	  String[] exec = new String[] {"c++filt", "-s", "java"};
-	  cppfilt = runtime.exec(exec);
-	  cppfiltIn = new BufferedReader
-			(new InputStreamReader(cppfilt.getInputStream()));
-	  cppfiltOut = new BufferedWriter
-			(new OutputStreamWriter(cppfilt.getOutputStream()));
-	}
-      catch (IOException ioe)
-        {
-	  if (cppfilt != null)
-	    cppfilt.destroy();
-	  cppfilt = null;
-	}
-    }
+      {
+	try
+	  {
+	    String[] exec = new String[] { "c++filt", "-s", "java" };
+	    cppfilt = runtime.exec(exec);
+	  }
+	catch (IOException ioe)
+	  {
+	   /* Ignore. */
+	  }
+	if (cppfilt != null)
+	  {
+	    cppfiltIn = new BufferedReader(new InputStreamReader(cppfilt
+	                                                         .getInputStream()));
+	    cppfiltOut = new BufferedWriter(new OutputStreamWriter(cppfilt
+	                                                           .getOutputStream()));
+	  }
+      }
 
     if (use_addr2line)
       {
@@ -216,16 +217,29 @@ public class NameFinder
 		name = addr2lineIn.readLine();
 		file = addr2lineIn.readLine();
 
-                // addr2line uses symbolic debugging information instead
-                // of the actually exported labels as addr2name.awk does.
-                // This name might need some modification, depending on 
-                // the system, to make it a label like that returned 
-                // by addr2name.awk or dladdr.
-                if (! usingAddr2name)
-                  if (name != null && ! "??".equals (name))
-                    name = getExternalLabel (name);
+		// addr2line uses symbolic debugging information instead
+		// of the actually exported labels as addr2name.awk does.
+		// This name might need some modification, depending on 
+		// the system, to make it a label like that returned 
+		// by addr2name.awk or dladdr.
+		if (! usingAddr2name)
+		  if (name != null && ! "??".equals(name))
+		    name = getExternalLabel(name);
+	      }
+	    catch (IOException ioe)
+	      {
+		addr2line.destroy();
+		// Must also waitFor() as to not leave zombies.
+		try
+		  {
+		    addr2line.waitFor();
+		  }
+		catch (InterruptedException ie)
+		  {
+		    /* Ignore. */
+		  }
+		addr2line = null;
 	      }
-	    catch (IOException ioe) { addr2line = null; }
 	  }
 
 	if (name == null || "??".equals(name))
@@ -432,16 +446,29 @@ public class NameFinder
   private String demangleName(String s)
   {
     if (cppfilt != null)
-    {
-      try
-	{
-	  cppfiltOut.write(s);
-	  cppfiltOut.newLine();
-	  cppfiltOut.flush();
-	  return cppfiltIn.readLine();
-	}
-      catch (IOException ioe) { cppfilt.destroy(); cppfilt = null; }
-    }
+      {
+	try
+	  {
+	    cppfiltOut.write(s);
+	    cppfiltOut.newLine();
+	    cppfiltOut.flush();
+	    return cppfiltIn.readLine();
+	  }
+	catch (IOException ioe)
+	  {
+	    cppfilt.destroy();
+	    // Must also waitFor() as to not leave zombies.
+	    try
+	      {
+		cppfilt.waitFor();
+	      }
+	    catch (InterruptedException ie)
+	      {
+		/* Ignore. */
+	      }
+	    cppfilt = null;
+	  }
+      }
 
     return s;
   }
@@ -473,7 +500,7 @@ public class NameFinder
 	int i = m.indexOf('(');
 	if (i > 0)
 	  {
-	    sb.append(m.substring(0,i));
+	    sb.append(m.substring(0, i));
 	    index += i + 1;
 	  }
       }
@@ -557,10 +584,32 @@ public class NameFinder
   public void close()
   {
     if (cppfilt != null)
-      cppfilt.destroy();
+      {
+	cppfilt.destroy();
+	// Must also waitFor() as to not leave zombies.
+	try
+	  {
+	    cppfilt.waitFor();
+	  }
+	catch (InterruptedException ie)
+	  {
+	    /* Ignore. */
+	  }
+      }
 
     if (addr2line != null)
-      addr2line.destroy();
+      {
+	addr2line.destroy();
+	// Must also waitFor() as to not leave zombies.
+	try
+	  {
+	    addr2line.waitFor();
+	  }
+	catch (InterruptedException ie)
+	  {
+	    /* Ignore. */
+	  }
+      }
   }
 
   /**
Index: java/lang/natPosixProcess.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natPosixProcess.cc,v
retrieving revision 1.18
diff -u -p -r1.18 natPosixProcess.cc
--- java/lang/natPosixProcess.cc	1 Mar 2004 21:33:27 -0000	1.18
+++ java/lang/natPosixProcess.cc	6 Jul 2004 06:55:06 -0000
@@ -324,6 +324,22 @@ java::lang::ConcreteProcess::startProces
       myclose (errp[1]);
       myclose (msgp[1]);
 
+      if (-1 != pid)
+        {
+          // Fork succeeded, but other problems keep us from
+          // creating the Process.  Must kill and reap the child
+          // so we don't leave zombies.
+
+          // Ignore r, child  might be dead already.
+          // We don't care about the status, we are just trying to cleanup.
+          int r = kill ((pid_t) pid, SIGKILL);
+
+          // Ignore this r also. We cannot throw
+          // InterruptedException from here, so we will just throw
+          // 'thrown' and hope for the best.
+          r = waitpid ((pid_t) pid, NULL, 0);
+        }
+
       exc = thrown;
     }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]