From 4aee96ae0b602b96e2cafac1381f3f00816bc96d Mon Sep 17 00:00:00 2001 From: John Cortell Date: Mon, 26 Apr 2010 20:18:09 +0000 Subject: [PATCH] Bug 304096: Fix interrupting Cygwin gdb for both DSF-GDB and CDI-GDB. Send a real CTRL-C; don't use 'kill -SIGINT' --- .../eclipse/cdt/utils/spawner/Spawner.java | 30 ++++++++++++++ .../factories/win32/CygwinCommandFactory.java | 21 +--------- .../win32/StandardWinCommandFactory.java | 5 +-- .../debug/mi/core/CygwinMIProcessAdapter.java | 40 ------------------- .../cdt/debug/mi/core/MIProcessAdapter.java | 4 +- .../cdt/dsf/gdb/service/GDBBackend.java | 4 +- 6 files changed, 37 insertions(+), 67 deletions(-) delete mode 100644 debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/CygwinMIProcessAdapter.java diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java index aad306f08ce..2e40f46540e 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/spawner/Spawner.java @@ -20,6 +20,7 @@ import java.util.StringTokenizer; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.utils.pty.PTY; +import org.eclipse.core.runtime.Platform; import org.eclipse.osgi.util.NLS; public class Spawner extends Process { @@ -30,6 +31,15 @@ public class Spawner extends Process { public int KILL = 9; public int TERM = 15; + /** + * A fabricated signal number for use on Windows only. Tells the starter program to send a CTRL-C to the + * inferior regardless of whether the inferior is a Cygiwn process or not. With {@link #INT}, the starter + * does a 'kill -SIGINT' if the inferior is a Cygwin process. + * + * @since 5.2 + */ + public int CTRLC = 1000; // arbitrary high number to avoid collision + int pid = 0; int status; int[] fChannels = new int[3]; @@ -208,6 +218,26 @@ public class Spawner extends Process { return raise(pid, INT); } + /** + * On Windows, this differs from interrupt() in that it will always send a CTRL-C event to the inferior, + * whereas {@link #interrupt()} will do a Cygwin 'kill -SIGINT' if the inferior is a Cygwin process + * (otherwise it sends a CTRL-C). In some cases, CDT needs to send CTRL-C regardless of whether the + * inferior is a cygwin process or not, e.g., when interrupting gdb on Windows (see bug 304096). + * + *

+ * On non-Windows hosts, this simply calls {@link #interrupt()} + * + * @since 5.2 + */ + public int interruptCTRLC() { + if (Platform.getOS().equals(Platform.OS_WIN32)) { + return raise(pid, CTRLC); + } + else { + return interrupt(); + } + } + public int hangup() { return raise(pid, HUP); } 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 11c64590ea9..5b4897c997d 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, 2007 QNX Software Systems and others. + * Copyright (c) 2004, 2010 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,13 +10,7 @@ *******************************************************************************/ 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.cdt.debug.mi.core.command.MIGDBSetNewConsole; -import org.eclipse.core.runtime.IProgressMonitor; /** * Command factory for the gdb/mi protocol for CygWin environment. @@ -40,17 +34,4 @@ public class CygwinCommandFactory extends StandardWinCommandFactory { public MIEnvironmentDirectory createMIEnvironmentDirectory(boolean reset, String[] pathdirs) { return new CygwinMIEnvironmentDirectory( getMIVersion(), reset, pathdirs ); } - - public MIGDBSetNewConsole createMIGDBSetNewConsole() { - // With cygwin, the Ctrl-C isn't getting propagated to the - // inferior. Thus we need to have the inferior in it's own - // console so that the fall back of sending it the interrupt - // signal works. - return new MIGDBSetNewConsole(getMIVersion(), "on"); - } - - 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/mi/org/eclipse/cdt/debug/mi/core/command/factories/win32/StandardWinCommandFactory.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/factories/win32/StandardWinCommandFactory.java index a947f07e0a0..60fb9d5025b 100644 --- a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/factories/win32/StandardWinCommandFactory.java +++ b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/command/factories/win32/StandardWinCommandFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2007 QNX Software Systems and others. + * Copyright (c) 2004, 2010 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 @@ -102,7 +102,6 @@ public class StandardWinCommandFactory extends StandardCommandFactory { public MIGDBSetNewConsole createMIGDBSetNewConsole() { // By default in Windows, turn off new console so that the // Ctrl-C's get propogated automatically to the inferior. - // Overriden by Cygwin. - return new MIGDBSetNewConsole(getMIVersion(), "off"); + return new MIGDBSetNewConsole(getMIVersion(), "off"); //$NON-NLS-1$ } } 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 deleted file mode 100644 index c938a255a32..00000000000 --- a/debug/org.eclipse.cdt.debug.mi.core/src/org/eclipse/cdt/debug/mi/core/CygwinMIProcessAdapter.java +++ /dev/null @@ -1,40 +0,0 @@ -/********************************************************************** - * 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.core.runtime.IProgressMonitor; - -/** - * @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) { - // With cygwin gdb, interrupting gdb itself never works. - // You need to interrupt the inferior directly. - 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 32b56f2ed16..9eca771b652 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, 2009 QNX Software Systems and others. + * Copyright (c) 2000, 2010 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,7 +123,7 @@ public class MIProcessAdapter implements MIProcess { if (fGDBProcess instanceof Spawner) { if (inferior.isRunning()) { Spawner gdbSpawner = (Spawner) fGDBProcess; - gdbSpawner.interrupt(); + gdbSpawner.interruptCTRLC(); waitForInterrupt(inferior); } // If we are still running try to drop the sig to the PID diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java index 8b93ff08882..5a3ace0fae2 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java @@ -378,7 +378,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend { public void interrupt() { if (fProcess instanceof Spawner) { Spawner gdbSpawner = (Spawner) fProcess; - gdbSpawner.interrupt(); + gdbSpawner.interruptCTRLC(); } } @@ -388,7 +388,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend { public void interruptAndWait(int timeout, RequestMonitor rm) { if (fProcess instanceof Spawner) { Spawner gdbSpawner = (Spawner) fProcess; - gdbSpawner.interrupt(); + gdbSpawner.interruptCTRLC(); fInterruptFailedJob = new MonitorInterruptJob(timeout, rm); } else { rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Cannot interrupt.", null)); //$NON-NLS-1$