mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 10:46:02 +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() {
|
public void destroy() {
|
||||||
// destroy() should be supported even if it's not spawner.
|
// destroy() should be supported even if it's not spawner.
|
||||||
if (getState() == State.STARTED) {
|
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.concurrent.RequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
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.IBreakpoints.IBreakpointsTargetDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
|
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.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.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.IMICommandControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
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.DsfServiceEventHandler;
|
||||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
|
|
||||||
public class GDBRunControl extends MIRunControl {
|
public class GDBRunControl extends MIRunControl {
|
||||||
|
@ -75,6 +77,7 @@ public class GDBRunControl extends MIRunControl {
|
||||||
|
|
||||||
private IGDBBackend fGdb;
|
private IGDBBackend fGdb;
|
||||||
private IMIProcesses fProcService;
|
private IMIProcesses fProcService;
|
||||||
|
private IGDBControl fGbControlService;
|
||||||
private CommandFactory fCommandFactory;
|
private CommandFactory fCommandFactory;
|
||||||
|
|
||||||
// Record list of execution contexts
|
// Record list of execution contexts
|
||||||
|
@ -101,6 +104,7 @@ public class GDBRunControl extends MIRunControl {
|
||||||
|
|
||||||
fGdb = getServicesTracker().getService(IGDBBackend.class);
|
fGdb = getServicesTracker().getService(IGDBBackend.class);
|
||||||
fProcService = getServicesTracker().getService(IMIProcesses.class);
|
fProcService = getServicesTracker().getService(IMIProcesses.class);
|
||||||
|
fGbControlService = getServicesTracker().getService(IGDBControl.class);
|
||||||
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
|
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
|
||||||
|
|
||||||
register(new String[]{IRunControl.class.getName(),
|
register(new String[]{IRunControl.class.getName(),
|
||||||
|
@ -138,7 +142,27 @@ public class GDBRunControl extends MIRunControl {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
if (getData()) {
|
if (getData()) {
|
||||||
|
// 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);
|
fGdb.interruptAndWait(IGDBBackend.INTERRUPT_TIMEOUT_DEFAULT, rm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fGdb.interruptAndWait(IGDBBackend.INTERRUPT_TIMEOUT_DEFAULT, rm);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Context cannot be suspended.", null)); //$NON-NLS-1$
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_STATE, "Context cannot be suspended.", null)); //$NON-NLS-1$
|
||||||
rm.done();
|
rm.done();
|
||||||
|
|
|
@ -124,6 +124,15 @@ public interface IGDBBackend extends IMIBackend {
|
||||||
*/
|
*/
|
||||||
public void interruptAndWait(int timeout, RequestMonitor rm);
|
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
|
* @return The type of the session currently ongoing with the backend
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue