|
|
9d64b0d |
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
|
|
|
9d64b0d |
index 4610781..e08767f 100644
|
|
|
9d64b0d |
--- a/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/PyProcessFactory.java
|
|
|
9d64b0d |
+++ b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/PyProcessFactory.java
|
|
|
46dcb5d |
@@ -9,8 +9,6 @@
|
|
|
9d64b0d |
import org.eclipse.debug.core.IProcessFactory;
|
|
|
9d64b0d |
import org.eclipse.debug.core.model.IProcess;
|
|
|
9d64b0d |
import org.eclipse.debug.core.model.RuntimeProcess;
|
|
|
9d64b0d |
-import org.jvnet.process_factory.AbstractProcess;
|
|
|
9d64b0d |
-import org.jvnet.process_factory.ProcessFactory;
|
|
|
9d64b0d |
import org.python.pydev.core.log.Log;
|
|
|
a8c7137 |
import org.python.pydev.debug.ui.RunPreferencesPage;
|
|
|
9d64b0d |
|
|
|
46dcb5d |
@@ -64,11 +62,10 @@
|
|
|
266987d |
@Override
|
|
|
266987d |
public void run() {
|
|
|
266987d |
try {
|
|
|
266987d |
- AbstractProcess p = ProcessFactory.createProcess(process);
|
|
|
266987d |
+ UnixProcessKiller p = new UnixProcessKiller(process);
|
|
|
266987d |
// I.e.: this is the real change in this wrapper: when killing a process, we'll kill the children
|
|
|
266987d |
// processes too, not only the main process (i.e.: so that we don't have zombie processes alive for
|
|
|
266987d |
// Django, etc).
|
|
|
266987d |
- // Note: custom build from https://github.com/fabioz/winp (appveyor) to also support unix
|
|
|
266987d |
p.killRecursively();
|
|
|
266987d |
} catch (Exception e) {
|
|
|
266987d |
Log.log(e);
|
|
|
9d64b0d |
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
|
|
|
9d64b0d |
new file mode 100644
|
|
|
9d64b0d |
index 0000000..c8ec14f
|
|
|
9d64b0d |
--- /dev/null
|
|
|
9d64b0d |
+++ b/plugins/org.python.pydev.debug/src/org/python/pydev/debug/processfactory/UnixProcessKiller.java
|
|
|
9d64b0d |
@@ -0,0 +1,108 @@
|
|
|
9d64b0d |
+package org.python.pydev.debug.processfactory;
|
|
|
9d64b0d |
+
|
|
|
9d64b0d |
+import java.io.BufferedInputStream;
|
|
|
9d64b0d |
+import java.io.IOException;
|
|
|
9d64b0d |
+import java.io.InputStreamReader;
|
|
|
9d64b0d |
+import java.lang.reflect.Field;
|
|
|
9d64b0d |
+import java.util.LinkedHashSet;
|
|
|
9d64b0d |
+import java.util.StringTokenizer;
|
|
|
9d64b0d |
+
|
|
|
9d64b0d |
+public class UnixProcessKiller {
|
|
|
9d64b0d |
+ private final int pid;
|
|
|
9d64b0d |
+
|
|
|
9d64b0d |
+ private static class Output {
|
|
|
9d64b0d |
+
|
|
|
9d64b0d |
+ public final String stdout;
|
|
|
9d64b0d |
+ public final String stderr;
|
|
|
9d64b0d |
+
|
|
|
9d64b0d |
+ public Output(String stdout, String stderr) {
|
|
|
9d64b0d |
+ this.stdout = stdout;
|
|
|
9d64b0d |
+ this.stderr = stderr;
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+
|
|
|
9d64b0d |
+ public UnixProcessKiller(Process p)
|
|
|
9d64b0d |
+ throws Exception {
|
|
|
9d64b0d |
+ this.pid = getPid(p);
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+
|
|
|
9d64b0d |
+ private static int getPid(Process process)
|
|
|
9d64b0d |
+ throws Exception {
|
|
|
9d64b0d |
+ try {
|
|
|
9d64b0d |
+ Field f = process.getClass().getDeclaredField("pid");
|
|
|
9d64b0d |
+ f.setAccessible(true);
|
|
|
9d64b0d |
+ return f.getInt(process);
|
|
|
9d64b0d |
+ } catch (Exception e) {
|
|
|
9d64b0d |
+ throw new RuntimeException(e);
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+
|
|
|
9d64b0d |
+ public void killRecursively()
|
|
|
9d64b0d |
+ throws IOException {
|
|
|
9d64b0d |
+ LinkedHashSet<Integer> listed = new LinkedHashSet<>();
|
|
|
9d64b0d |
+ killRecursively(pid, listed);
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+
|
|
|
9d64b0d |
+ private static void killRecursively(int pid, LinkedHashSet<Integer> listed)
|
|
|
9d64b0d |
+ throws IOException {
|
|
|
9d64b0d |
+ listed.add(Integer.valueOf(pid));
|
|
|
9d64b0d |
+ Runtime.getRuntime().exec(new String[] {
|
|
|
9d64b0d |
+ "kill", "-stop", Integer.toString(pid)
|
|
|
9d64b0d |
+ }, null, null);
|
|
|
9d64b0d |
+ Process createProcess = Runtime.getRuntime().exec(new String[] {
|
|
|
9d64b0d |
+ "pgrep", "-P", Integer.toString(pid)
|
|
|
9d64b0d |
+ }, null, null);
|
|
|
9d64b0d |
+ Output outputPGrep = getProcessOutput(createProcess);
|
|
|
9d64b0d |
+ if (outputPGrep.stderr != null && outputPGrep.stderr.length() > 0) {
|
|
|
9d64b0d |
+ throw new RuntimeException(outputPGrep.stderr);
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+ Runtime.getRuntime().exec(new String[] {
|
|
|
9d64b0d |
+ "kill", "-KILL", Integer.toString(pid)
|
|
|
9d64b0d |
+ }, null, null);
|
|
|
9d64b0d |
+ String ids = outputPGrep.stdout;
|
|
|
9d64b0d |
+ StringTokenizer strTok = new StringTokenizer(ids);
|
|
|
9d64b0d |
+ do {
|
|
|
9d64b0d |
+ if (!strTok.hasMoreTokens()) {
|
|
|
9d64b0d |
+ break;
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+ String nextToken = strTok.nextToken();
|
|
|
9d64b0d |
+ int found = Integer.parseInt(nextToken);
|
|
|
9d64b0d |
+ if (!listed.contains(Integer.valueOf(found))) {
|
|
|
9d64b0d |
+ killRecursively(found, listed);
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+ } while (true);
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+
|
|
|
9d64b0d |
+ private static Output getProcessOutput(Process process)
|
|
|
9d64b0d |
+ throws IOException {
|
|
|
9d64b0d |
+ try {
|
|
|
9d64b0d |
+ process.getOutputStream().close();
|
|
|
9d64b0d |
+ } catch (IOException e2) {
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+ InputStreamReader inputStream = new InputStreamReader(new BufferedInputStream(process.getInputStream()));
|
|
|
9d64b0d |
+ InputStreamReader errorStream = new InputStreamReader(new BufferedInputStream(process.getErrorStream()));
|
|
|
9d64b0d |
+ try {
|
|
|
9d64b0d |
+ process.waitFor();
|
|
|
9d64b0d |
+ } catch (InterruptedException e1) {
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+ try {
|
|
|
9d64b0d |
+ Object sync = new Object();
|
|
|
9d64b0d |
+ synchronized (sync) {
|
|
|
9d64b0d |
+ sync.wait(10L);
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+ } catch (Exception e) {
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+ return new Output(readInputStream(inputStream), readInputStream(errorStream));
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+
|
|
|
9d64b0d |
+ private static String readInputStream(InputStreamReader in)
|
|
|
9d64b0d |
+ throws IOException {
|
|
|
9d64b0d |
+ StringBuffer contents = new StringBuffer();
|
|
|
9d64b0d |
+ char buf[] = new char[80];
|
|
|
9d64b0d |
+ int c;
|
|
|
9d64b0d |
+ while ((c = in.read(buf)) != -1) {
|
|
|
9d64b0d |
+ contents.append(buf, 0, c);
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+ return contents.toString();
|
|
|
9d64b0d |
+ }
|
|
|
9d64b0d |
+}
|
|
|
9d64b0d |
diff --git a/plugins/org.python.pydev.debug/build.properties b/plugins/org.python.pydev.debug/build.properties
|
|
|
9d64b0d |
index 0704b04..bf249fa 100644
|
|
|
9d64b0d |
--- a/plugins/org.python.pydev.debug/build.properties
|
|
|
9d64b0d |
+++ b/plugins/org.python.pydev.debug/build.properties
|
|
|
266987d |
@@ -3,8 +3,7 @@
|
|
|
9d64b0d |
schema/,\
|
|
|
9d64b0d |
icons/,\
|
|
|
266987d |
pydev-debug.jar,\
|
|
|
266987d |
- LICENSE.txt,\
|
|
|
266987d |
- libs/winp-1.26.0.7.jar
|
|
|
266987d |
+ LICENSE.txt
|
|
|
266987d |
jars.compile.order = pydev-debug.jar
|
|
|
266987d |
source.pydev-debug.jar = src/,\
|
|
|
266987d |
src_console/
|
|
|
e4909f6 |
diff --git a/plugins/org.python.pydev.debug/META-INF/MANIFEST.MF b/plugins/org.python.pydev.debug/META-INF/MANIFEST.MF
|
|
|
e4909f6 |
index e4ea072..12fd1ce 100644
|
|
|
e4909f6 |
--- a/plugins/org.python.pydev.debug/META-INF/MANIFEST.MF
|
|
|
e4909f6 |
+++ b/plugins/org.python.pydev.debug/META-INF/MANIFEST.MF
|
|
|
e4909f6 |
@@ -3,8 +3,7 @@ Bundle-ManifestVersion: 2
|
|
|
e4909f6 |
Bundle-Name: Pydev debug
|
|
|
e4909f6 |
Bundle-SymbolicName: org.python.pydev.debug; singleton:=true
|
|
|
84d4f24 |
Bundle-Version: 7.7.0.qualifier
|
|
|
e4909f6 |
-Bundle-ClassPath: pydev-debug.jar,
|
|
|
266987d |
- libs/winp-1.26.0.7.jar
|
|
|
e4909f6 |
+Bundle-ClassPath: pydev-debug.jar
|
|
|
e4909f6 |
Bundle-Activator: org.python.pydev.debug.core.PydevDebugPlugin
|
|
|
6969096 |
Bundle-Vendor: Brainwy Software Ltda
|
|
|
266987d |
Eclipse-BundleShape: dir
|