Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Cortell2010-04-28 12:26:25 -0400
committerJohn Cortell2010-04-28 12:26:25 -0400
commita67d7300906c8c98b0081c2b840b69ce9a7870eb (patch)
tree06b7926e5ab5e3daadb5173e0434133ce0030176 /debug/org.eclipse.cdt.debug.mi.core
parent8f44d67a49efa47af06a461e52e5b89996c06a87 (diff)
downloadorg.eclipse.cdt-a67d7300906c8c98b0081c2b840b69ce9a7870eb.tar.gz
org.eclipse.cdt-a67d7300906c8c98b0081c2b840b69ce9a7870eb.tar.xz
org.eclipse.cdt-a67d7300906c8c98b0081c2b840b69ce9a7870eb.zip
Bug 304096: Interrupting a Windows target does not always work, revisited. CDI adjustments.
Diffstat (limited to 'debug/org.eclipse.cdt.debug.mi.core')
-rw-r--r--debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/MIInferior.java19
-rw-r--r--debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/factories/win32/CygwinCommandFactory.java12
-rw-r--r--debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/CygwinMIProcessAdapter.java123
-rw-r--r--debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MIProcessAdapter.java25
4 files changed, 157 insertions, 22 deletions
diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/MIInferior.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/MIInferior.java
index 4bb845afa7..4a91e16a1e 100644
--- a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/MIInferior.java
+++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/MIInferior.java
@@ -57,7 +57,7 @@ public class MIInferior extends Process {
int inferiorPID;
- /** See {@link #getIsRemoteInferior()} */
+ /** See {@link #isRemoteInferior()} */
private boolean fIsRemoteInferior;
public MIInferior(MISession mi, IMITTY p) {
@@ -394,11 +394,24 @@ public class MIInferior extends Process {
}
/**
- * Is the inferior process being debugged remotely through gdbserver?
+ * Is the inferior process being debugged remotely through gdbserver? This
+ * is mutually exclusive with {@link #isAttachedLocalInferior()}.
*
* @since 7.0
*/
- public boolean getIsRemoteInferior() {
+ public boolean isRemoteInferior() {
return fIsRemoteInferior;
}
+
+ /**
+ * Is this inferior process being debugged through a local attach session?
+ * I.e., is it a process running on "this" machine that was not launched by
+ * gdb but which gdb attached to? This is mutually exclusive with
+ * {@link #isRemoteInferior()
+ *
+ * @since 7.0
+ */
+ public boolean isAttachedLocalInferior() {
+ return session.isAttachSession();
+ }
}
diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/factories/win32/CygwinCommandFactory.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/factories/win32/CygwinCommandFactory.java
index 5b4897c997..12b95acd18 100644
--- a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/factories/win32/CygwinCommandFactory.java
+++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/factories/win32/CygwinCommandFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2010 QNX Software Systems and others.
+ * Copyright (c) 2004, 2007 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,7 +10,12 @@
*******************************************************************************/
package org.eclipse.cdt.debug.mi.core.command.factories.win32;
+import java.io.IOException;
+
+import org.eclipse.cdt.debug.mi.core.CygwinMIProcessAdapter;
+import org.eclipse.cdt.debug.mi.core.MIProcess;
import org.eclipse.cdt.debug.mi.core.command.MIEnvironmentDirectory;
+import org.eclipse.core.runtime.IProgressMonitor;
/**
* Command factory for the gdb/mi protocol for CygWin environment.
@@ -34,4 +39,9 @@ public class CygwinCommandFactory extends StandardWinCommandFactory {
public MIEnvironmentDirectory createMIEnvironmentDirectory(boolean reset, String[] pathdirs) {
return new CygwinMIEnvironmentDirectory( getMIVersion(), reset, pathdirs );
}
+
+ public MIProcess createMIProcess(String[] args, int launchTimeout,
+ IProgressMonitor monitor) throws IOException {
+ return new CygwinMIProcessAdapter(args, launchTimeout, monitor);
+ }
}
diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/CygwinMIProcessAdapter.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/CygwinMIProcessAdapter.java
new file mode 100644
index 0000000000..5308c3e218
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/CygwinMIProcessAdapter.java
@@ -0,0 +1,123 @@
+/**********************************************************************
+ * Copyright (c) 2007 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ **********************************************************************/
+
+package org.eclipse.cdt.debug.mi.core;
+
+import java.io.IOException;
+
+import org.eclipse.cdt.utils.spawner.Spawner;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * @author Doug Schaefer
+ */
+public class CygwinMIProcessAdapter extends MIProcessAdapter {
+
+ /**
+ * @param args
+ * @param launchTimeout
+ * @param monitor
+ * @throws IOException
+ */
+ public CygwinMIProcessAdapter(String[] args, int launchTimeout,
+ IProgressMonitor monitor) throws IOException {
+ super(args, launchTimeout, monitor);
+ }
+
+ public void interrupt(MIInferior inferior) {
+ if (fGDBProcess instanceof Spawner) {
+ if (inferior.isRunning()) {
+ boolean interruptedInferior = false;
+ Spawner gdbSpawner = (Spawner) fGDBProcess;
+
+ // Cygwin gdb 6.8 is capricious when it comes to interrupting
+ // the target. MinGW and later versions of Cygwin aren't. A
+ // simple CTRL-C to gdb seems to do the trick in every case.
+ // Once we drop support for gdb 6.8, we should be able to ditch
+ // this method and rely on the base implementation
+ // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=304096#c56
+ if (Platform.getOS().equals(Platform.OS_WIN32)) {
+ if (inferior.isRemoteInferior()) {
+ // Interrupt gdb with a 'kill -SIGINT'. The reason we
+ // need to send a simulated Cygwin/POSIX SIGINT to
+ // Cygwin gdb is that it has special handling in the case
+ // of remote debugging, as explained in the bugzilla
+ // comment above. That special handling will forward the
+ // interrupt request through gdbserver to the remote
+ // inferior, but the interrupt to gdb *must* be a
+ // simulated Cygwin/POSIX SIGINT; a CTRL-C won't do.
+ gdbSpawner.interrupt();
+ }
+ else if (inferior.isAttachedLocalInferior()) {
+ // Cygwin gdb 6.8 has no support for forwarding an
+ // interrupt request to the local process it has
+ // attached to. That support has since been added and
+ // will be available in 7.x. So, the only way to suspend the
+ // attached-to inferior is to interrupt it directly.
+ // The following call will take a special path in the
+ // JNI code. See Java_org_eclipse_cdt_utils_spawner_Spawner_raise()
+ // We don't use the Cygwin 'kill' command since we don't
+ // know if the process associated with PID (the
+ // inferior) is a cygwin
+ // process (kill only works on cygwin programs). We also
+ // can't use GenerateConsoleCtrlEvent() to send a CTRL-C
+ // since that can only be used if the recipient shares a
+ // console with the caller. So, we end up looking for a
+ // console window associated with PID, and then we
+ // fabricate keyboard events to simulate the user doing
+ // a CTRL-C in that console! Crazy stuff, but it works.
+ // Thing is, the PID associated with the console window
+ // has to be that of the process we're trying to
+ // interrupt. What that means is that in order for CDT's
+ // 'suspend' button to work in an attach debug session,
+ // the inferior must have been launched with its own
+ // console. If you open a Windows console and type
+ // 'myprogram.exe', CDT can attach to it but not suspend
+ // it once it resumes it. Instead, you have to launch
+ // the program by using 'start myprogram.exe'.
+ interruptInferior(inferior);
+ interruptedInferior = true;
+ }
+ else {
+ // The typical case--gdb launches the inferior.
+ // Interrupt gdb but with a CTRL-C. gdb (6.8) itself
+ // doesn't have a handler for CTRL-C, but all processes
+ // in the console
+ // process group will receive the CTRL-C, and gdb
+ // registers itself to catch any such events that
+ // happen in the inferior. Thus it is able to determine
+ // and report that the inferior has been interrupted.
+ // But it's important we don't interrupt Cygwin gdb with
+ // a 'kill' since that will only reach gdb, and gdb
+ // won't forward the request on to the inferior. See
+ // bugzilla comment referenced above for details.
+ gdbSpawner.interruptCTRLC();
+ }
+ }
+ else {
+ gdbSpawner.interrupt();
+ }
+
+ waitForInterrupt(inferior);
+
+ // If we are still running try to interrupt the inferior (unless we
+ // already tried that above)
+ if (inferior.isRunning() && inferior.getInferiorPID() > 0 && !interruptedInferior) {
+ // lets try something else.
+ interruptInferior(inferior);
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MIProcessAdapter.java b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MIProcessAdapter.java
index 7c146c4f83..9c803f90bd 100644
--- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MIProcessAdapter.java
+++ b/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/MIProcessAdapter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 QNX Software Systems and others.
+ * Copyright (c) 2000, 2009 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -123,28 +123,18 @@ public class MIProcessAdapter implements MIProcess {
if (fGDBProcess instanceof Spawner) {
if (inferior.isRunning()) {
Spawner gdbSpawner = (Spawner) fGDBProcess;
-
- // Cygwin gdb 6.8 is capricious when it comes to interrupting the
- // target. The same logic here will work with MinGW, though. And on
- // linux it's irrelevant since interruptCTRLC()==interrupt(). So,
- // one odd size fits all.
- // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=304096#c54
- if (inferior.getIsRemoteInferior()) {
- gdbSpawner.interrupt();
+ if (inferior.isAttachedLocalInferior()) {
+ // not all gdb versions forward the interrupt to an attached
+ // inferior, so interrupt the inferior directly
+ interruptInferior(inferior);
}
else {
- gdbSpawner.interruptCTRLC();
+ // standard case (gdb launches process) and remote case (gdbserver)
+ gdbSpawner.interrupt();
}
-
waitForInterrupt(inferior);
}
- // If we are still running try to drop the sig to the PID
- if (inferior.isRunning() && inferior.getInferiorPID() > 0) {
- // lets try something else.
- interruptInferior(inferior);
- }
}
-
}
protected boolean waitForInterrupt(MIInferior inferior) {
@@ -170,7 +160,6 @@ public class MIProcessAdapter implements MIProcess {
if (fGDBProcess instanceof Spawner) {
Spawner gdbSpawner = (Spawner) fGDBProcess;
gdbSpawner.raise(inferior.getInferiorPID(), gdbSpawner.INT);
- waitForInterrupt(inferior);
}
}

Back to the top