mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Bug 304096: Fix interrupting Cygwin gdb for both DSF-GDB and CDI-GDB. Send a real CTRL-C; don't use 'kill -SIGINT'
This commit is contained in:
parent
6fbc6bfd8d
commit
4aee96ae0b
6 changed files with 37 additions and 67 deletions
|
@ -20,6 +20,7 @@ import java.util.StringTokenizer;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.utils.pty.PTY;
|
import org.eclipse.cdt.utils.pty.PTY;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.osgi.util.NLS;
|
import org.eclipse.osgi.util.NLS;
|
||||||
|
|
||||||
public class Spawner extends Process {
|
public class Spawner extends Process {
|
||||||
|
@ -30,6 +31,15 @@ public class Spawner extends Process {
|
||||||
public int KILL = 9;
|
public int KILL = 9;
|
||||||
public int TERM = 15;
|
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 pid = 0;
|
||||||
int status;
|
int status;
|
||||||
int[] fChannels = new int[3];
|
int[] fChannels = new int[3];
|
||||||
|
@ -208,6 +218,26 @@ public class Spawner extends Process {
|
||||||
return raise(pid, INT);
|
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).
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 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() {
|
public int hangup() {
|
||||||
return raise(pid, HUP);
|
return raise(pid, HUP);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -10,13 +10,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.debug.mi.core.command.factories.win32;
|
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.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.
|
* 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) {
|
public MIEnvironmentDirectory createMIEnvironmentDirectory(boolean reset, String[] pathdirs) {
|
||||||
return new CygwinMIEnvironmentDirectory( getMIVersion(), reset, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -102,7 +102,6 @@ public class StandardWinCommandFactory extends StandardCommandFactory {
|
||||||
public MIGDBSetNewConsole createMIGDBSetNewConsole() {
|
public MIGDBSetNewConsole createMIGDBSetNewConsole() {
|
||||||
// By default in Windows, turn off new console so that the
|
// By default in Windows, turn off new console so that the
|
||||||
// Ctrl-C's get propogated automatically to the inferior.
|
// Ctrl-C's get propogated automatically to the inferior.
|
||||||
// Overriden by Cygwin.
|
return new MIGDBSetNewConsole(getMIVersion(), "off"); //$NON-NLS-1$
|
||||||
return new MIGDBSetNewConsole(getMIVersion(), "off");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -123,7 +123,7 @@ public class MIProcessAdapter implements MIProcess {
|
||||||
if (fGDBProcess instanceof Spawner) {
|
if (fGDBProcess instanceof Spawner) {
|
||||||
if (inferior.isRunning()) {
|
if (inferior.isRunning()) {
|
||||||
Spawner gdbSpawner = (Spawner) fGDBProcess;
|
Spawner gdbSpawner = (Spawner) fGDBProcess;
|
||||||
gdbSpawner.interrupt();
|
gdbSpawner.interruptCTRLC();
|
||||||
waitForInterrupt(inferior);
|
waitForInterrupt(inferior);
|
||||||
}
|
}
|
||||||
// If we are still running try to drop the sig to the PID
|
// If we are still running try to drop the sig to the PID
|
||||||
|
|
|
@ -378,7 +378,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
|
||||||
public void interrupt() {
|
public void interrupt() {
|
||||||
if (fProcess instanceof Spawner) {
|
if (fProcess instanceof Spawner) {
|
||||||
Spawner gdbSpawner = (Spawner) fProcess;
|
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) {
|
public void interruptAndWait(int timeout, RequestMonitor rm) {
|
||||||
if (fProcess instanceof Spawner) {
|
if (fProcess instanceof Spawner) {
|
||||||
Spawner gdbSpawner = (Spawner) fProcess;
|
Spawner gdbSpawner = (Spawner) fProcess;
|
||||||
gdbSpawner.interrupt();
|
gdbSpawner.interruptCTRLC();
|
||||||
fInterruptFailedJob = new MonitorInterruptJob(timeout, rm);
|
fInterruptFailedJob = new MonitorInterruptJob(timeout, rm);
|
||||||
} else {
|
} else {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Cannot interrupt.", null)); //$NON-NLS-1$
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Cannot interrupt.", null)); //$NON-NLS-1$
|
||||||
|
|
Loading…
Add table
Reference in a new issue