|
|
41b21e |
diff --git a/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/PyProcessFactory.java b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/PyProcessFactory.java
|
|
|
41b21e |
index 4610781..e08767f 100644
|
|
|
41b21e |
--- a/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/PyProcessFactory.java
|
|
|
41b21e |
+++ b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/PyProcessFactory.java
|
|
|
41b21e |
@@ -8,8 +8,6 @@ import org.eclipse.debug.core.ILaunch;
|
|
|
41b21e |
import org.eclipse.debug.core.IProcessFactory;
|
|
|
41b21e |
import org.eclipse.debug.core.model.IProcess;
|
|
|
41b21e |
import org.eclipse.debug.core.model.RuntimeProcess;
|
|
|
41b21e |
-import org.jvnet.process_factory.AbstractProcess;
|
|
|
41b21e |
-import org.jvnet.process_factory.ProcessFactory;
|
|
|
41b21e |
import org.python.pydev.core.log.Log;
|
|
|
41b21e |
import org.python.pydev.debug.ui.DebugPrefsPage;
|
|
|
41b21e |
|
|
|
41b21e |
@@ -59,9 +57,9 @@ public class PyProcessFactory implements IProcessFactory {
|
|
|
41b21e |
public void destroy() {
|
|
|
41b21e |
if (DebugPrefsPage.getKillSubprocessesWhenTerminatingProcess()) {
|
|
|
41b21e |
try {
|
|
|
41b21e |
- AbstractProcess p = ProcessFactory.CreateProcess(process);
|
|
|
41b21e |
- //I.e.: this is the real change in this wrapper: when killing a process, we'll kill the children
|
|
|
41b21e |
- //processes too, not only the main process (i.e.: so that we don't have zombie processes alive for
|
|
|
41b21e |
+ UnixProcessKiller p = new UnixProcessKiller(process);
|
|
|
41b21e |
+ //I.e.: this is the real change in this wrapper: when killing a process, we'll kill the children
|
|
|
41b21e |
+ //processes too, not only the main process (i.e.: so that we don't have zombie processes alive for
|
|
|
41b21e |
//Django, etc).
|
|
|
41b21e |
p.killRecursively();
|
|
|
41b21e |
} catch (Exception e) {
|
|
|
41b21e |
diff --git a/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/UnixProcessKiller.java b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/UnixProcessKiller.java
|
|
|
41b21e |
new file mode 100644
|
|
|
41b21e |
index 0000000..c8ec14f
|
|
|
41b21e |
--- /dev/null
|
|
|
41b21e |
+++ b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/UnixProcessKiller.java
|
|
|
41b21e |
@@ -0,0 +1,108 @@
|
|
|
41b21e |
+package org.python.pydev.debug.processfactory;
|
|
|
41b21e |
+
|
|
|
41b21e |
+import java.io.BufferedInputStream;
|
|
|
41b21e |
+import java.io.IOException;
|
|
|
41b21e |
+import java.io.InputStreamReader;
|
|
|
41b21e |
+import java.lang.reflect.Field;
|
|
|
41b21e |
+import java.util.LinkedHashSet;
|
|
|
41b21e |
+import java.util.StringTokenizer;
|
|
|
41b21e |
+
|
|
|
41b21e |
+public class UnixProcessKiller {
|
|
|
41b21e |
+ private final int pid;
|
|
|
41b21e |
+
|
|
|
41b21e |
+ private static class Output {
|
|
|
41b21e |
+
|
|
|
41b21e |
+ public final String stdout;
|
|
|
41b21e |
+ public final String stderr;
|
|
|
41b21e |
+
|
|
|
41b21e |
+ public Output(String stdout, String stderr) {
|
|
|
41b21e |
+ this.stdout = stdout;
|
|
|
41b21e |
+ this.stderr = stderr;
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+
|
|
|
41b21e |
+ public UnixProcessKiller(Process p)
|
|
|
41b21e |
+ throws Exception {
|
|
|
41b21e |
+ this.pid = getPid(p);
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+
|
|
|
41b21e |
+ private static int getPid(Process process)
|
|
|
41b21e |
+ throws Exception {
|
|
|
41b21e |
+ try {
|
|
|
41b21e |
+ Field f = process.getClass().getDeclaredField("pid");
|
|
|
41b21e |
+ f.setAccessible(true);
|
|
|
41b21e |
+ return f.getInt(process);
|
|
|
41b21e |
+ } catch (Exception e) {
|
|
|
41b21e |
+ throw new RuntimeException(e);
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+
|
|
|
41b21e |
+ public void killRecursively()
|
|
|
41b21e |
+ throws IOException {
|
|
|
41b21e |
+ LinkedHashSet<Integer> listed = new LinkedHashSet<>();
|
|
|
41b21e |
+ killRecursively(pid, listed);
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+
|
|
|
41b21e |
+ private static void killRecursively(int pid, LinkedHashSet<Integer> listed)
|
|
|
41b21e |
+ throws IOException {
|
|
|
41b21e |
+ listed.add(Integer.valueOf(pid));
|
|
|
41b21e |
+ Runtime.getRuntime().exec(new String[] {
|
|
|
41b21e |
+ "kill", "-stop", Integer.toString(pid)
|
|
|
41b21e |
+ }, null, null);
|
|
|
41b21e |
+ Process createProcess = Runtime.getRuntime().exec(new String[] {
|
|
|
41b21e |
+ "pgrep", "-P", Integer.toString(pid)
|
|
|
41b21e |
+ }, null, null);
|
|
|
41b21e |
+ Output outputPGrep = getProcessOutput(createProcess);
|
|
|
41b21e |
+ if (outputPGrep.stderr != null && outputPGrep.stderr.length() > 0) {
|
|
|
41b21e |
+ throw new RuntimeException(outputPGrep.stderr);
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+ Runtime.getRuntime().exec(new String[] {
|
|
|
41b21e |
+ "kill", "-KILL", Integer.toString(pid)
|
|
|
41b21e |
+ }, null, null);
|
|
|
41b21e |
+ String ids = outputPGrep.stdout;
|
|
|
41b21e |
+ StringTokenizer strTok = new StringTokenizer(ids);
|
|
|
41b21e |
+ do {
|
|
|
41b21e |
+ if (!strTok.hasMoreTokens()) {
|
|
|
41b21e |
+ break;
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+ String nextToken = strTok.nextToken();
|
|
|
41b21e |
+ int found = Integer.parseInt(nextToken);
|
|
|
41b21e |
+ if (!listed.contains(Integer.valueOf(found))) {
|
|
|
41b21e |
+ killRecursively(found, listed);
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+ } while (true);
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+
|
|
|
41b21e |
+ private static Output getProcessOutput(Process process)
|
|
|
41b21e |
+ throws IOException {
|
|
|
41b21e |
+ try {
|
|
|
41b21e |
+ process.getOutputStream().close();
|
|
|
41b21e |
+ } catch (IOException e2) {
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+ InputStreamReader inputStream = new InputStreamReader(new BufferedInputStream(process.getInputStream()));
|
|
|
41b21e |
+ InputStreamReader errorStream = new InputStreamReader(new BufferedInputStream(process.getErrorStream()));
|
|
|
41b21e |
+ try {
|
|
|
41b21e |
+ process.waitFor();
|
|
|
41b21e |
+ } catch (InterruptedException e1) {
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+ try {
|
|
|
41b21e |
+ Object sync = new Object();
|
|
|
41b21e |
+ synchronized (sync) {
|
|
|
41b21e |
+ sync.wait(10L);
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+ } catch (Exception e) {
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+ return new Output(readInputStream(inputStream), readInputStream(errorStream));
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+
|
|
|
41b21e |
+ private static String readInputStream(InputStreamReader in)
|
|
|
41b21e |
+ throws IOException {
|
|
|
41b21e |
+ StringBuffer contents = new StringBuffer();
|
|
|
41b21e |
+ char buf[] = new char[80];
|
|
|
41b21e |
+ int c;
|
|
|
41b21e |
+ while ((c = in.read(buf)) != -1) {
|
|
|
41b21e |
+ contents.append(buf, 0, c);
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+ return contents.toString();
|
|
|
41b21e |
+ }
|
|
|
41b21e |
+}
|
|
|
41b21e |
diff --git a/plugins/org.python.pydev.debug/META-INF/MANIFEST.MF b/plugins/org.python.pydev.debug/META-INF/MANIFEST.MF
|
|
|
dc00b4 |
index e4ea072..12fd1ce 100644
|
|
|
41b21e |
--- a/plugins/org.python.pydev.debug/META-INF/MANIFEST.MF
|
|
|
41b21e |
+++ b/plugins/org.python.pydev.debug/META-INF/MANIFEST.MF
|
|
|
41b21e |
@@ -3,8 +3,7 @@ Bundle-ManifestVersion: 2
|
|
|
41b21e |
Bundle-Name: Pydev debug
|
|
|
41b21e |
Bundle-SymbolicName: org.python.pydev.debug; singleton:=true
|
|
|
dc00b4 |
Bundle-Version: 4.5.5.qualifier
|
|
|
41b21e |
-Bundle-ClassPath: pydev-debug.jar,
|
|
|
41b21e |
- libs/winp-1.19.jar
|
|
|
41b21e |
+Bundle-ClassPath: pydev-debug.jar
|
|
|
41b21e |
Bundle-Activator: org.python.pydev.debug.core.PydevDebugPlugin
|
|
|
41b21e |
Bundle-Vendor: Aptana
|
|
|
41b21e |
Bundle-Localization: plugin
|
|
|
41b21e |
diff --git a/plugins/org.python.pydev.debug/build.properties b/plugins/org.python.pydev.debug/build.properties
|
|
|
41b21e |
index 0704b04..bf249fa 100644
|
|
|
41b21e |
--- a/plugins/org.python.pydev.debug/build.properties
|
|
|
41b21e |
+++ b/plugins/org.python.pydev.debug/build.properties
|
|
|
41b21e |
@@ -1,5 +1,4 @@
|
|
|
41b21e |
bin.includes = plugin.xml,\
|
|
|
41b21e |
- libs/winp-1.19.jar,\
|
|
|
41b21e |
META-INF/,\
|
|
|
41b21e |
schema/,\
|
|
|
41b21e |
icons/,\
|