mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Bug 304096: Interrupting a Windows target does not always work (fixed last two non-working scenarios: attach with gdb 6.8)
This commit is contained in:
parent
19dadcff48
commit
994628eca9
3 changed files with 50 additions and 3 deletions
|
@ -418,6 +418,20 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0
|
||||
*/
|
||||
public void interruptInferiorAndWait(long pid, int timeout, RequestMonitor rm) {
|
||||
if (fProcess instanceof Spawner) {
|
||||
Spawner gdbSpawner = (Spawner) fProcess;
|
||||
gdbSpawner.raise((int)pid, gdbSpawner.INT);
|
||||
fInterruptFailedJob = new MonitorInterruptJob(timeout, rm);
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Cannot interrupt.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
// destroy() should be supported even if it's not spawner.
|
||||
if (getState() == State.STARTED) {
|
||||
|
|
|
@ -23,12 +23,13 @@ import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
|||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl2;
|
||||
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl2;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
||||
|
@ -46,6 +47,7 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
|||
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
public class GDBRunControl extends MIRunControl {
|
||||
|
@ -75,6 +77,7 @@ public class GDBRunControl extends MIRunControl {
|
|||
|
||||
private IGDBBackend fGdb;
|
||||
private IMIProcesses fProcService;
|
||||
private IGDBControl fGbControlService;
|
||||
private CommandFactory fCommandFactory;
|
||||
|
||||
// Record list of execution contexts
|
||||
|
@ -101,6 +104,7 @@ public class GDBRunControl extends MIRunControl {
|
|||
|
||||
fGdb = getServicesTracker().getService(IGDBBackend.class);
|
||||
fProcService = getServicesTracker().getService(IMIProcesses.class);
|
||||
fGbControlService = getServicesTracker().getService(IGDBControl.class);
|
||||
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
|
||||
|
||||
register(new String[]{IRunControl.class.getName(),
|
||||
|
@ -138,7 +142,27 @@ public class GDBRunControl extends MIRunControl {
|
|||
@Override
|
||||
protected void handleSuccess() {
|
||||
if (getData()) {
|
||||
fGdb.interruptAndWait(IGDBBackend.INTERRUPT_TIMEOUT_DEFAULT, rm);
|
||||
// A local Windows attach session requires us to interrupt
|
||||
// the inferior instead of gdb. This deficiency was fixed
|
||||
// in gdb 7.0. Note that there's a GDBRunControl_7_0,
|
||||
// so we're dealing with gdb < 7.0 if we get here.
|
||||
// Refer to https://bugs.eclipse.org/bugs/show_bug.cgi?id=304096#c56
|
||||
// if you have the stomach for it.
|
||||
if (fGdb.getIsAttachSession()
|
||||
&& fGdb.getSessionType() != SessionType.REMOTE
|
||||
&& Platform.getOS().equals(Platform.OS_WIN32)) {
|
||||
String inferiorPid = fGbControlService.getInferiorProcess().getPid();
|
||||
if (inferiorPid != null) {
|
||||
fGdb.interruptInferiorAndWait(Long.parseLong(inferiorPid), IGDBBackend.INTERRUPT_TIMEOUT_DEFAULT, rm);
|
||||
}
|
||||
else {
|
||||
assert false : "why don't we have the inferior's pid?"; //$NON-NLS-1$
|
||||
fGdb.interruptAndWait(IGDBBackend.INTERRUPT_TIMEOUT_DEFAULT, rm);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fGdb.interruptAndWait(IGDBBackend.INTERRUPT_TIMEOUT_DEFAULT, rm);
|
||||
}
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Context cannot be suspended.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
|
|
|
@ -124,6 +124,15 @@ public interface IGDBBackend extends IMIBackend {
|
|||
*/
|
||||
public void interruptAndWait(int timeout, RequestMonitor rm);
|
||||
|
||||
/**
|
||||
* Same as {@link #interruptAndWait(int, RequestMonitor)}, except the
|
||||
* inferior process is directly interrupted.
|
||||
*
|
||||
* @param pid the PID of the inferior
|
||||
* @since 3.0
|
||||
*/
|
||||
public void interruptInferiorAndWait(long pid, int timeout, RequestMonitor rm);
|
||||
|
||||
/**
|
||||
* @return The type of the session currently ongoing with the backend
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue