mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 338319: Allow terminating individual processes
This commit is contained in:
parent
4c700d7e5f
commit
e03d0d8880
10 changed files with 283 additions and 257 deletions
|
@ -30,9 +30,11 @@ import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContex
|
||||||
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IProcesses;
|
import org.eclipse.cdt.dsf.debug.service.IProcesses;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
|
||||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||||
import org.eclipse.cdt.dsf.gdb.launching.GDBProcess;
|
import org.eclipse.cdt.dsf.gdb.launching.GDBProcess;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||||
|
@ -45,6 +47,7 @@ import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
|
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
|
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess.State;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
|
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
||||||
|
@ -53,6 +56,7 @@ import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
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;
|
||||||
import org.eclipse.debug.core.DebugPlugin;
|
import org.eclipse.debug.core.DebugPlugin;
|
||||||
import org.eclipse.debug.core.ILaunch;
|
import org.eclipse.debug.core.ILaunch;
|
||||||
|
@ -74,6 +78,11 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
private IGDBBackend fBackend;
|
private IGDBBackend fBackend;
|
||||||
private CommandFactory fCommandFactory;
|
private CommandFactory fCommandFactory;
|
||||||
|
|
||||||
|
// Indicates if we are currently connected to an inferior
|
||||||
|
// We only need a boolean type since we only support single process debugging
|
||||||
|
// in this version of the service
|
||||||
|
private boolean fConnected;
|
||||||
|
|
||||||
// A map of pid to names. It is filled when we get all the
|
// A map of pid to names. It is filled when we get all the
|
||||||
// processes that are running
|
// processes that are running
|
||||||
private Map<Integer, String> fProcessNames = new HashMap<Integer, String>();
|
private Map<Integer, String> fProcessNames = new HashMap<Integer, String>();
|
||||||
|
@ -114,10 +123,6 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
GDBProcesses.class.getName() },
|
GDBProcesses.class.getName() },
|
||||||
new Hashtable<String, String>());
|
new Hashtable<String, String>());
|
||||||
|
|
||||||
ICommandControlService commandControl = getServicesTracker().getService(ICommandControlService.class);
|
|
||||||
IContainerDMContext containerDmc = createContainerContextFromGroupId(commandControl.getContext(), MIProcesses.UNIQUE_GROUP_ID);
|
|
||||||
fGdb.getInferiorProcess().setContainerContext(containerDmc);
|
|
||||||
|
|
||||||
getSession().addServiceEventListener(this, null);
|
getSession().addServiceEventListener(this, null);
|
||||||
|
|
||||||
requestMonitor.done();
|
requestMonitor.done();
|
||||||
|
@ -195,11 +200,7 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void isDebuggerAttachSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
public void isDebuggerAttachSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
||||||
MIInferiorProcess inferiorProcess = fGdb.getInferiorProcess();
|
if (fBackend.getIsAttachSession() && !fConnected) {
|
||||||
if (!fGdb.isConnected() &&
|
|
||||||
inferiorProcess != null &&
|
|
||||||
inferiorProcess.getState() != MIInferiorProcess.State.TERMINATED) {
|
|
||||||
|
|
||||||
rm.setData(true);
|
rm.setData(true);
|
||||||
} else {
|
} else {
|
||||||
rm.setData(false);
|
rm.setData(false);
|
||||||
|
@ -213,7 +214,7 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
// For a local attach, GDB can figure out the binary automatically,
|
// For a local attach, GDB can figure out the binary automatically,
|
||||||
// so we don't specify it.
|
// so we don't specify it.
|
||||||
|
|
||||||
IMIContainerDMContext containerDmc = createContainerContext(procCtx, MIProcesses.UNIQUE_GROUP_ID);
|
final IMIContainerDMContext containerDmc = createContainerContext(procCtx, MIProcesses.UNIQUE_GROUP_ID);
|
||||||
|
|
||||||
DataRequestMonitor<MIInfo> attachRm = new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm) {
|
DataRequestMonitor<MIInfo> attachRm = new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -223,10 +224,9 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
new DataRequestMonitor<IDMContext>(ImmediateExecutor.getInstance(), rm) {
|
new DataRequestMonitor<IDMContext>(ImmediateExecutor.getInstance(), rm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
fGdb.setConnected(true);
|
|
||||||
|
|
||||||
MIInferiorProcess inferiorProcess = fGdb.getInferiorProcess();
|
MIInferiorProcess inferiorProcess = fGdb.getInferiorProcess();
|
||||||
if (inferiorProcess != null) {
|
if (inferiorProcess != null) {
|
||||||
|
inferiorProcess.setContainerContext(containerDmc);
|
||||||
inferiorProcess.setPid(((IMIProcessDMContext)procCtx).getProcId());
|
inferiorProcess.setPid(((IMIProcessDMContext)procCtx).getProcId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +258,11 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void canDetachDebuggerFromProcess(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
public void canDetachDebuggerFromProcess(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
||||||
rm.setData(false); // don't turn on yet, as we need to generate events to use this properly
|
if (fBackend.getIsAttachSession() && fConnected) {
|
||||||
|
rm.setData(true);
|
||||||
|
} else {
|
||||||
|
rm.setData(false);
|
||||||
|
}
|
||||||
rm.done();
|
rm.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,8 +273,6 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
new RequestMonitor(getExecutor(), rm) {
|
new RequestMonitor(getExecutor(), rm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
fGdb.setConnected(false);
|
|
||||||
|
|
||||||
MIInferiorProcess inferiorProcess = fGdb.getInferiorProcess();
|
MIInferiorProcess inferiorProcess = fGdb.getInferiorProcess();
|
||||||
if (inferiorProcess != null) {
|
if (inferiorProcess != null) {
|
||||||
inferiorProcess.setPid(null);
|
inferiorProcess.setPid(null);
|
||||||
|
@ -301,7 +303,7 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
@Override
|
@Override
|
||||||
public void getProcessesBeingDebugged(IDMContext dmc, DataRequestMonitor<IDMContext[]> rm) {
|
public void getProcessesBeingDebugged(IDMContext dmc, DataRequestMonitor<IDMContext[]> rm) {
|
||||||
MIInferiorProcess inferiorProcess = fGdb.getInferiorProcess();
|
MIInferiorProcess inferiorProcess = fGdb.getInferiorProcess();
|
||||||
if (fGdb.isConnected() &&
|
if (fConnected &&
|
||||||
inferiorProcess != null &&
|
inferiorProcess != null &&
|
||||||
inferiorProcess.getState() != MIInferiorProcess.State.TERMINATED) {
|
inferiorProcess.getState() != MIInferiorProcess.State.TERMINATED) {
|
||||||
|
|
||||||
|
@ -353,9 +355,37 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void terminate(IThreadDMContext thread, RequestMonitor rm) {
|
public void terminate(IThreadDMContext thread, final RequestMonitor rm) {
|
||||||
if (thread instanceof IMIProcessDMContext) {
|
if (thread instanceof IMIProcessDMContext) {
|
||||||
fGdb.terminate(rm);
|
getDebuggingContext(
|
||||||
|
thread,
|
||||||
|
new DataRequestMonitor<IDMContext>(ImmediateExecutor.getInstance(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
if (getData() instanceof IMIContainerDMContext) {
|
||||||
|
if (fGdb.getInferiorProcess().getState() == State.RUNNING) {
|
||||||
|
fBackend.interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
final IMIContainerDMContext container = (IMIContainerDMContext)getData();
|
||||||
|
fGdb.queueCommand(
|
||||||
|
fCommandFactory.createMIInterpreterExecConsoleKill(container),
|
||||||
|
new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
// Before GDB 7.0, we must send a container exited event ourselves
|
||||||
|
getSession().dispatchEvent(
|
||||||
|
new ContainerExitedDMEvent(container), getProperties());
|
||||||
|
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$
|
||||||
rm.done();
|
rm.done();
|
||||||
|
@ -405,12 +435,13 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
/**
|
/**
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
protected void createConsole(final boolean restart, final RequestMonitor rm) {
|
protected void createConsole(final IContainerDMContext containerDmc, final boolean restart, final RequestMonitor rm) {
|
||||||
fGdb.initInferiorInputOutput(new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
|
fGdb.initInferiorInputOutput(new RequestMonitor(ImmediateExecutor.getInstance(), rm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
fGdb.createInferiorProcess();
|
fGdb.createInferiorProcess();
|
||||||
final Process inferior = fGdb.getInferiorProcess();
|
final MIInferiorProcess inferior = fGdb.getInferiorProcess();
|
||||||
|
inferior.setContainerContext(containerDmc);
|
||||||
|
|
||||||
final String label = fBackend.getProgramPath().lastSegment();
|
final String label = fBackend.getProgramPath().lastSegment();
|
||||||
final ILaunch launch = (ILaunch)getSession().getModelAdapter(ILaunch.class);
|
final ILaunch launch = (ILaunch)getSession().getModelAdapter(ILaunch.class);
|
||||||
|
@ -459,7 +490,7 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
createConsole(restart, new RequestMonitor(ImmediateExecutor.getInstance(), requestMonitor) {
|
createConsole(containerDmc, restart, new RequestMonitor(ImmediateExecutor.getInstance(), requestMonitor) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleSuccess() {
|
protected void handleSuccess() {
|
||||||
|
|
||||||
|
@ -524,6 +555,31 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
|
||||||
return fBackend.getSessionType() == SessionType.REMOTE;
|
return fBackend.getSessionType() == SessionType.REMOTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@DsfServiceEventHandler
|
||||||
|
public void eventDispatched(IStartedDMEvent e) {
|
||||||
|
if (e.getDMContext() instanceof IContainerDMContext) {
|
||||||
|
fConnected = true;
|
||||||
|
}
|
||||||
|
super.eventDispatched(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@DsfServiceEventHandler
|
||||||
|
public void eventDispatched(IExitedDMEvent e) {
|
||||||
|
if (e.getDMContext() instanceof IContainerDMContext) {
|
||||||
|
fConnected = false;
|
||||||
|
|
||||||
|
if (Platform.getPreferencesService().getBoolean("org.eclipse.cdt.dsf.gdb.ui", //$NON-NLS-1$
|
||||||
|
IGdbDebugPreferenceConstants.PREF_AUTO_TERMINATE_GDB,
|
||||||
|
true, null)) {
|
||||||
|
// If the inferior finishes, let's terminate GDB
|
||||||
|
fGdb.terminate(new RequestMonitor(ImmediateExecutor.getInstance(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.eventDispatched(e);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -50,6 +50,7 @@ import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
|
import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
|
||||||
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
|
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
|
||||||
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.gdb.service.command.IGDBControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
||||||
|
@ -60,6 +61,8 @@ import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
|
import org.eclipse.cdt.dsf.mi.service.MIBreakpointsManager;
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
|
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess.State;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.events.MIThreadGroupCreatedEvent;
|
import org.eclipse.cdt.dsf.mi.service.command.events.MIThreadGroupCreatedEvent;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.events.MIThreadGroupExitedEvent;
|
import org.eclipse.cdt.dsf.mi.service.command.events.MIThreadGroupExitedEvent;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIConst;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIConst;
|
||||||
|
@ -79,6 +82,7 @@ import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
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;
|
||||||
import org.eclipse.debug.core.ILaunch;
|
import org.eclipse.debug.core.ILaunch;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
|
@ -436,6 +440,11 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
|
|
||||||
private static final String FAKE_THREAD_ID = "0"; //$NON-NLS-1$
|
private static final String FAKE_THREAD_ID = "0"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps track of how many processes we are currently connected to
|
||||||
|
*/
|
||||||
|
private int fNumConnected;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps track if we are dealing with the very first process of GDB.
|
* Keeps track if we are dealing with the very first process of GDB.
|
||||||
*/
|
*/
|
||||||
|
@ -725,7 +734,7 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
|
|
||||||
/** @since 4.0 */
|
/** @since 4.0 */
|
||||||
protected boolean doIsDebuggerAttachSupported() {
|
protected boolean doIsDebuggerAttachSupported() {
|
||||||
return fBackend.getIsAttachSession() && !fCommandControl.isConnected();
|
return fBackend.getIsAttachSession() && fNumConnected == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void isDebuggerAttachSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
public void isDebuggerAttachSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
||||||
|
@ -790,6 +799,13 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
public void execute(RequestMonitor rm) {
|
public void execute(RequestMonitor rm) {
|
||||||
// By now, GDB has reported the groupId that was created for this process
|
// By now, GDB has reported the groupId that was created for this process
|
||||||
fContainerDmc = createContainerContext(procCtx, getGroupFromPid(((IMIProcessDMContext)procCtx).getProcId()));
|
fContainerDmc = createContainerContext(procCtx, getGroupFromPid(((IMIProcessDMContext)procCtx).getProcId()));
|
||||||
|
|
||||||
|
MIInferiorProcess inferior = fCommandControl.getInferiorProcess();
|
||||||
|
if (inferior != null) {
|
||||||
|
inferior.setContainerContext(fContainerDmc);
|
||||||
|
inferior.setPid(((IMIProcessDMContext)procCtx).getProcId());
|
||||||
|
}
|
||||||
|
|
||||||
// Store the fully formed container context so it can be returned to the caller.
|
// Store the fully formed container context so it can be returned to the caller.
|
||||||
dataRm.setData(fContainerDmc);
|
dataRm.setData(fContainerDmc);
|
||||||
|
|
||||||
|
@ -835,7 +851,7 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
|
|
||||||
/** @since 4.0 */
|
/** @since 4.0 */
|
||||||
protected boolean doCanDetachDebuggerFromProcess() {
|
protected boolean doCanDetachDebuggerFromProcess() {
|
||||||
return fBackend.getIsAttachSession() && fCommandControl.isConnected();
|
return fBackend.getIsAttachSession() && fNumConnected > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void canDetachDebuggerFromProcess(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
public void canDetachDebuggerFromProcess(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
||||||
|
@ -857,7 +873,13 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
|
|
||||||
fCommandControl.queueCommand(
|
fCommandControl.queueCommand(
|
||||||
fCommandFactory.createMITargetDetach(controlDmc, procDmc.getProcId()),
|
fCommandFactory.createMITargetDetach(controlDmc, procDmc.getProcId()),
|
||||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
|
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
fCommandControl.getInferiorProcess().setPid(null);
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid context.", null)); //$NON-NLS-1$
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid context.", null)); //$NON-NLS-1$
|
||||||
rm.done();
|
rm.done();
|
||||||
|
@ -1096,9 +1118,27 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
rm.done();
|
rm.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void terminate(IThreadDMContext thread, RequestMonitor rm) {
|
public void terminate(IThreadDMContext thread, final RequestMonitor rm) {
|
||||||
if (thread instanceof IMIProcessDMContext) {
|
if (thread instanceof IMIProcessDMContext) {
|
||||||
fCommandControl.terminate(rm);
|
getDebuggingContext(
|
||||||
|
thread,
|
||||||
|
new DataRequestMonitor<IDMContext>(ImmediateExecutor.getInstance(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
if (getData() instanceof IMIContainerDMContext) {
|
||||||
|
if (fCommandControl.getInferiorProcess().getState() == State.RUNNING) {
|
||||||
|
fBackend.interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
fCommandControl.queueCommand(
|
||||||
|
fCommandFactory.createMIInterpreterExecConsoleKill((IMIContainerDMContext)getData()),
|
||||||
|
new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm));
|
||||||
|
} else {
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$
|
||||||
rm.done();
|
rm.done();
|
||||||
|
@ -1214,6 +1254,7 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
public void eventDispatched(IStartedDMEvent e) {
|
public void eventDispatched(IStartedDMEvent e) {
|
||||||
if (e instanceof ContainerStartedDMEvent) {
|
if (e instanceof ContainerStartedDMEvent) {
|
||||||
fContainerCommandCache.reset();
|
fContainerCommandCache.reset();
|
||||||
|
fNumConnected++;
|
||||||
} else {
|
} else {
|
||||||
fThreadCommandCache.reset();
|
fThreadCommandCache.reset();
|
||||||
}
|
}
|
||||||
|
@ -1224,6 +1265,22 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
public void eventDispatched(IExitedDMEvent e) {
|
public void eventDispatched(IExitedDMEvent e) {
|
||||||
if (e instanceof ContainerExitedDMEvent) {
|
if (e instanceof ContainerExitedDMEvent) {
|
||||||
fContainerCommandCache.reset();
|
fContainerCommandCache.reset();
|
||||||
|
|
||||||
|
assert fNumConnected > 0;
|
||||||
|
fNumConnected--;
|
||||||
|
|
||||||
|
if (Platform.getPreferencesService().getBoolean("org.eclipse.cdt.dsf.gdb.ui", //$NON-NLS-1$
|
||||||
|
IGdbDebugPreferenceConstants.PREF_AUTO_TERMINATE_GDB,
|
||||||
|
true, null)) {
|
||||||
|
if (fNumConnected == 0 &&
|
||||||
|
!(fBackend.getIsAttachSession() &&
|
||||||
|
fBackend.getSessionType() == SessionType.REMOTE)) {
|
||||||
|
// If the last process we are debugging finishes, let's terminate GDB
|
||||||
|
// but not for a remote attach session, since we could request to attach
|
||||||
|
// to another process
|
||||||
|
fCommandControl.terminate(new RequestMonitor(ImmediateExecutor.getInstance(), null));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fThreadCommandCache.reset();
|
fThreadCommandCache.reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
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.IMIContainerDMContext;
|
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.IMIProcessDMContext;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint;
|
||||||
|
@ -333,6 +334,11 @@ public class StartOrRestartProcessSequence_7_0 extends ReflectionSequence {
|
||||||
|
|
||||||
if (fContainerDmc instanceof IMIContainerDMContext) {
|
if (fContainerDmc instanceof IMIContainerDMContext) {
|
||||||
fContainerDmc = fProcService.createContainerContextFromGroupId(fCommandControl.getContext(), ((IMIContainerDMContext)fContainerDmc).getGroupId());
|
fContainerDmc = fProcService.createContainerContextFromGroupId(fCommandControl.getContext(), ((IMIContainerDMContext)fContainerDmc).getGroupId());
|
||||||
|
fCommandControl.getInferiorProcess().setContainerContext(fContainerDmc);
|
||||||
|
|
||||||
|
IMIProcessDMContext procDmc = DMContexts.getAncestorOfType(fContainerDmc, IMIProcessDMContext.class);
|
||||||
|
fCommandControl.getInferiorProcess().setPid(procDmc.getProcId());
|
||||||
|
|
||||||
// This is the container context that this sequence is supposed to return: set the dataRm
|
// This is the container context that this sequence is supposed to return: set the dataRm
|
||||||
fDataRequestMonitor.setData(fContainerDmc);
|
fDataRequestMonitor.setData(fContainerDmc);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -28,20 +28,17 @@ import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||||
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||||
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.Sequence;
|
import org.eclipse.cdt.dsf.concurrent.Sequence;
|
||||||
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
|
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
||||||
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
|
|
||||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
|
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.SessionType;
|
import org.eclipse.cdt.dsf.gdb.service.SessionType;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
|
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIBackend.BackendStateChangedEvent;
|
import org.eclipse.cdt.dsf.mi.service.IMIBackend.BackendStateChangedEvent;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.MIProcesses.ContainerExitedDMEvent;
|
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess;
|
import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.AbstractMIControl;
|
import org.eclipse.cdt.dsf.mi.service.command.AbstractMIControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.CLIEventProcessor;
|
import org.eclipse.cdt.dsf.mi.service.command.CLIEventProcessor;
|
||||||
|
@ -55,7 +52,6 @@ import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
import org.eclipse.cdt.utils.pty.PTY;
|
import org.eclipse.cdt.utils.pty.PTY;
|
||||||
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;
|
||||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
|
@ -95,8 +91,6 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
|
||||||
|
|
||||||
private IGDBBackend fMIBackend;
|
private IGDBBackend fMIBackend;
|
||||||
|
|
||||||
private boolean fConnected;
|
|
||||||
|
|
||||||
private MIRunControlEventProcessor fMIEventProcessor;
|
private MIRunControlEventProcessor fMIEventProcessor;
|
||||||
private CLIEventProcessor fCLICommandProcessor;
|
private CLIEventProcessor fCLICommandProcessor;
|
||||||
private AbstractCLIProcess fCLIProcess;
|
private AbstractCLIProcess fCLIProcess;
|
||||||
|
@ -264,9 +258,9 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
|
||||||
*/
|
*/
|
||||||
public void createInferiorProcess() {
|
public void createInferiorProcess() {
|
||||||
if (fPty == null) {
|
if (fPty == null) {
|
||||||
fInferiorProcess = new GDBInferiorProcess(GDBControl.this, fMIBackend, fMIBackend.getMIOutputStream());
|
fInferiorProcess = new MIInferiorProcess(GDBControl.this, fMIBackend.getMIOutputStream());
|
||||||
} else {
|
} else {
|
||||||
fInferiorProcess = new GDBInferiorProcess(GDBControl.this, fMIBackend, fPty);
|
fInferiorProcess = new MIInferiorProcess(GDBControl.this, fPty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the CLI event processor each time this method is called
|
// Create the CLI event processor each time this method is called
|
||||||
|
@ -278,15 +272,6 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
|
||||||
fCLICommandProcessor = new CLIEventProcessor(GDBControl.this, fControlDmc);
|
fCLICommandProcessor = new CLIEventProcessor(GDBControl.this, fControlDmc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isConnected() {
|
|
||||||
return fInferiorProcess.getState() != MIInferiorProcess.State.TERMINATED &&
|
|
||||||
(!fMIBackend.getIsAttachSession() || fConnected);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConnected(boolean connected) {
|
|
||||||
fConnected = connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AbstractCLIProcess getCLIProcess() {
|
public AbstractCLIProcess getCLIProcess() {
|
||||||
return fCLIProcess;
|
return fCLIProcess;
|
||||||
}
|
}
|
||||||
|
@ -341,17 +326,6 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 2.0 */
|
|
||||||
@DsfServiceEventHandler
|
|
||||||
public void eventDispatched(ContainerExitedDMEvent e) {
|
|
||||||
if (Platform.getPreferencesService().getBoolean("org.eclipse.cdt.dsf.gdb.ui", //$NON-NLS-1$
|
|
||||||
IGdbDebugPreferenceConstants.PREF_AUTO_TERMINATE_GDB,
|
|
||||||
true, null)) {
|
|
||||||
// If the inferior finishes, let's terminate GDB
|
|
||||||
terminate(new RequestMonitor(ImmediateExecutor.getInstance(), null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class InitializationShutdownStep extends Sequence.Step {
|
public static class InitializationShutdownStep extends Sequence.Step {
|
||||||
public enum Direction { INITIALIZING, SHUTTING_DOWN }
|
public enum Direction { INITIALIZING, SHUTTING_DOWN }
|
||||||
|
|
||||||
|
|
|
@ -28,16 +28,12 @@ import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||||
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||||
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.Sequence;
|
import org.eclipse.cdt.dsf.concurrent.Sequence;
|
||||||
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
|
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
||||||
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
|
|
||||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.GDBProcesses_7_0.ContainerExitedDMEvent;
|
|
||||||
import org.eclipse.cdt.dsf.gdb.service.GDBProcesses_7_0.ContainerStartedDMEvent;
|
|
||||||
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
|
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordSelectedChangedDMEvent;
|
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceRecordSelectedChangedDMEvent;
|
||||||
import org.eclipse.cdt.dsf.gdb.service.SessionType;
|
import org.eclipse.cdt.dsf.gdb.service.SessionType;
|
||||||
|
@ -58,7 +54,6 @@ import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
import org.eclipse.cdt.utils.pty.PTY;
|
import org.eclipse.cdt.utils.pty.PTY;
|
||||||
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;
|
||||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
|
@ -98,8 +93,6 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
|
||||||
|
|
||||||
private IGDBBackend fMIBackend;
|
private IGDBBackend fMIBackend;
|
||||||
|
|
||||||
private int fConnected = 0;
|
|
||||||
|
|
||||||
private MIRunControlEventProcessor_7_0 fMIEventProcessor;
|
private MIRunControlEventProcessor_7_0 fMIEventProcessor;
|
||||||
private CLIEventProcessor_7_0 fCLICommandProcessor;
|
private CLIEventProcessor_7_0 fCLICommandProcessor;
|
||||||
private AbstractCLIProcess fCLIProcess;
|
private AbstractCLIProcess fCLIProcess;
|
||||||
|
@ -281,22 +274,9 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
|
||||||
*/
|
*/
|
||||||
public void createInferiorProcess() {
|
public void createInferiorProcess() {
|
||||||
if (fPty == null) {
|
if (fPty == null) {
|
||||||
fInferiorProcess = new GDBInferiorProcess(GDBControl_7_0.this, fMIBackend, fMIBackend.getMIOutputStream());
|
fInferiorProcess = new MIInferiorProcess(GDBControl_7_0.this, fMIBackend.getMIOutputStream());
|
||||||
} else {
|
} else {
|
||||||
fInferiorProcess = new GDBInferiorProcess(GDBControl_7_0.this, fMIBackend, fPty);
|
fInferiorProcess = new MIInferiorProcess(GDBControl_7_0.this, fPty);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isConnected() {
|
|
||||||
return fInferiorProcess.getState() != MIInferiorProcess.State.TERMINATED &&
|
|
||||||
(!fMIBackend.getIsAttachSession() || fConnected > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConnected(boolean connected) {
|
|
||||||
if (connected) {
|
|
||||||
fConnected++;
|
|
||||||
} else {
|
|
||||||
if (fConnected > 0) fConnected--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,31 +339,6 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 2.0 */
|
|
||||||
@DsfServiceEventHandler
|
|
||||||
public void eventDispatched(ContainerStartedDMEvent e) {
|
|
||||||
setConnected(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @since 2.0 */
|
|
||||||
@DsfServiceEventHandler
|
|
||||||
public void eventDispatched(ContainerExitedDMEvent e) {
|
|
||||||
setConnected(false);
|
|
||||||
|
|
||||||
if (Platform.getPreferencesService().getBoolean("org.eclipse.cdt.dsf.gdb.ui", //$NON-NLS-1$
|
|
||||||
IGdbDebugPreferenceConstants.PREF_AUTO_TERMINATE_GDB,
|
|
||||||
true, null)) {
|
|
||||||
if (!isConnected() &&
|
|
||||||
!(fMIBackend.getIsAttachSession() &&
|
|
||||||
fMIBackend.getSessionType() == SessionType.REMOTE)) {
|
|
||||||
// If the last process we are debugging finishes, let's terminate GDB
|
|
||||||
// but not for a remote attach session, since we could request to attach
|
|
||||||
// to another process
|
|
||||||
terminate(new RequestMonitor(ImmediateExecutor.getInstance(), null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @since 3.0 */
|
/** @since 3.0 */
|
||||||
@DsfServiceEventHandler
|
@DsfServiceEventHandler
|
||||||
public void eventDispatched(ITraceRecordSelectedChangedDMEvent e) {
|
public void eventDispatched(ITraceRecordSelectedChangedDMEvent e) {
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2007, 2009 Wind River 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:
|
|
||||||
* Wind River Systems - initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.cdt.dsf.gdb.service.command;
|
|
||||||
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
|
||||||
import org.eclipse.cdt.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor;
|
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
|
||||||
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
|
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
|
|
||||||
import org.eclipse.cdt.utils.pty.PTY;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class GDBInferiorProcess extends MIInferiorProcess {
|
|
||||||
|
|
||||||
private IGDBBackend fBackend;
|
|
||||||
|
|
||||||
public GDBInferiorProcess(ICommandControlService commandControl, IGDBBackend backend, PTY p) {
|
|
||||||
super(commandControl, p);
|
|
||||||
fBackend = backend;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GDBInferiorProcess(ICommandControlService commandControl, IGDBBackend backend, OutputStream gdbOutputStream) {
|
|
||||||
super(commandControl, gdbOutputStream);
|
|
||||||
fBackend = backend;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@ThreadSafeAndProhibitedFromDsfExecutor("getSession#getExecutor")
|
|
||||||
public void destroy() {
|
|
||||||
try {
|
|
||||||
getSession().getExecutor().submit(new DsfRunnable() {
|
|
||||||
public void run() {
|
|
||||||
if (isDisposed() || !getSession().isActive()) return;
|
|
||||||
|
|
||||||
// An inferior will be destroy():interrupt and kill if
|
|
||||||
// - For attach session:
|
|
||||||
// never (we don't kill an independent process.)
|
|
||||||
// - For Program session:
|
|
||||||
// if the inferior is still running.
|
|
||||||
// - For PostMortem(Core):
|
|
||||||
// no need to do anything since the inferior
|
|
||||||
// is not running
|
|
||||||
if (fBackend.getIsAttachSession() == false) {
|
|
||||||
// Try to interrupt the inferior, first.
|
|
||||||
if (getState() == State.RUNNING) {
|
|
||||||
fBackend.interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).get();
|
|
||||||
} catch (RejectedExecutionException e) {
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
} finally {
|
|
||||||
super.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -28,10 +28,6 @@ public interface IGDBControl extends IMICommandControl {
|
||||||
|
|
||||||
void createInferiorProcess();
|
void createInferiorProcess();
|
||||||
|
|
||||||
boolean isConnected();
|
|
||||||
|
|
||||||
void setConnected(boolean connected);
|
|
||||||
|
|
||||||
AbstractCLIProcess getCLIProcess();
|
AbstractCLIProcess getCLIProcess();
|
||||||
|
|
||||||
MIInferiorProcess getInferiorProcess();
|
MIInferiorProcess getInferiorProcess();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2010 QNX Software Systems and others.
|
* Copyright (c) 2000, 2011 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
|
||||||
|
@ -68,6 +68,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataWriteMemory;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnablePrettyPrinting;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnablePrettyPrinting;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnvironmentCD;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnvironmentCD;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnvironmentDirectory;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnvironmentDirectory;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecArguments;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecContinue;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecContinue;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecFinish;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecFinish;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecInterrupt;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecInterrupt;
|
||||||
|
@ -103,6 +104,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBShowExitCode;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInferiorTTYSet;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInferiorTTYSet;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExec;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExec;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExecConsole;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExecConsole;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExecConsoleKill;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIListFeatures;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIListFeatures;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIListThreadGroups;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIListThreadGroups;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIRemoveInferior;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIRemoveInferior;
|
||||||
|
@ -143,7 +145,6 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarSetUpdateRange;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowAttributes;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowAttributes;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowFormat;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowFormat;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarUpdate;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarUpdate;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecArguments;
|
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLICatchInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.CLICatchInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoProgramInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoProgramInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoSharedLibraryInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoSharedLibraryInfo;
|
||||||
|
@ -632,6 +633,11 @@ public class CommandFactory {
|
||||||
return new MIInterpreterExecConsole<MIInfo>(ctx, cmd);
|
return new MIInterpreterExecConsole<MIInfo>(ctx, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 4.0 */
|
||||||
|
public ICommand<MIInfo> createMIInterpreterExecConsoleKill(IMIContainerDMContext ctx) {
|
||||||
|
return new MIInterpreterExecConsoleKill(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
/** @since 4.0 */
|
/** @since 4.0 */
|
||||||
public ICommand<MIListFeaturesInfo> createMIListFeatures(ICommandControlDMContext ctx) {
|
public ICommand<MIListFeaturesInfo> createMIListFeatures(ICommandControlDMContext ctx) {
|
||||||
return new MIListFeatures(ctx);
|
return new MIListFeatures(ctx);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2009, 2010 QNX Software Systems and others.
|
* Copyright (c) 2009, 2011 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
|
||||||
|
@ -28,11 +28,15 @@ import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||||
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||||
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.Query;
|
import org.eclipse.cdt.dsf.concurrent.Query;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||||
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
|
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
|
||||||
import org.eclipse.cdt.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor;
|
import org.eclipse.cdt.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor;
|
||||||
|
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IProcesses;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandListener;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandListener;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandResult;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandResult;
|
||||||
|
@ -52,6 +56,8 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIResult;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIResultRecord;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIResultRecord;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MITargetStreamOutput;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MITargetStreamOutput;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIValue;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIValue;
|
||||||
|
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||||
|
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
import org.eclipse.cdt.utils.pty.PTY;
|
import org.eclipse.cdt.utils.pty.PTY;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
@ -124,8 +130,6 @@ public class MIInferiorProcess extends Process
|
||||||
* to write the user standard input into.
|
* to write the user standard input into.
|
||||||
*
|
*
|
||||||
* @param commandControl Command control that this inferior process belongs to.
|
* @param commandControl Command control that this inferior process belongs to.
|
||||||
* @param inferiorExecCtx The execution context controlling the execution
|
|
||||||
* state of the inferior process.
|
|
||||||
* @param gdbOutputStream The output stream to use to write user IO into.
|
* @param gdbOutputStream The output stream to use to write user IO into.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@ -139,8 +143,6 @@ public class MIInferiorProcess extends Process
|
||||||
* to write the user standard input into.
|
* to write the user standard input into.
|
||||||
*
|
*
|
||||||
* @param commandControl Command control that this inferior process belongs to.
|
* @param commandControl Command control that this inferior process belongs to.
|
||||||
* @param inferiorExecCtx The execution context controlling the execution
|
|
||||||
* state of the inferior process.
|
|
||||||
* @param p The terminal to use to write user IO into.
|
* @param p The terminal to use to write user IO into.
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
|
@ -153,6 +155,7 @@ public class MIInferiorProcess extends Process
|
||||||
private MIInferiorProcess(ICommandControlService commandControl, final OutputStream gdbOutputStream, PTY p) {
|
private MIInferiorProcess(ICommandControlService commandControl, final OutputStream gdbOutputStream, PTY p) {
|
||||||
fCommandControl = commandControl;
|
fCommandControl = commandControl;
|
||||||
fSession = commandControl.getSession();
|
fSession = commandControl.getSession();
|
||||||
|
fSession.addServiceEventListener(this, null);
|
||||||
|
|
||||||
if (fCommandControl instanceof IMICommandControl) {
|
if (fCommandControl instanceof IMICommandControl) {
|
||||||
fCommandFactory = ((IMICommandControl)fCommandControl).getCommandFactory();
|
fCommandFactory = ((IMICommandControl)fCommandControl).getCommandFactory();
|
||||||
|
@ -173,7 +176,6 @@ public class MIInferiorProcess extends Process
|
||||||
fOutputStream = new OutputStream() {
|
fOutputStream = new OutputStream() {
|
||||||
@Override
|
@Override
|
||||||
public void write(int b) throws IOException {
|
public void write(int b) throws IOException {
|
||||||
// Have to re-dispatch to dispatch thread to check state
|
|
||||||
if (getState() != State.RUNNING) {
|
if (getState() != State.RUNNING) {
|
||||||
throw new IOException("Target is not running"); //$NON-NLS-1$
|
throw new IOException("Target is not running"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
@ -206,6 +208,8 @@ public class MIInferiorProcess extends Process
|
||||||
|
|
||||||
@ConfinedToDsfExecutor("fSession#getExecutor")
|
@ConfinedToDsfExecutor("fSession#getExecutor")
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
fSession.removeServiceEventListener(this);
|
||||||
|
|
||||||
fCommandControl.removeEventListener(this);
|
fCommandControl.removeEventListener(this);
|
||||||
fCommandControl.removeCommandListener(this);
|
fCommandControl.removeCommandListener(this);
|
||||||
|
|
||||||
|
@ -369,19 +373,16 @@ public class MIInferiorProcess extends Process
|
||||||
private void doDestroy() {
|
private void doDestroy() {
|
||||||
if (isDisposed() || !fSession.isActive() || getState() == State.TERMINATED) return;
|
if (isDisposed() || !fSession.isActive() || getState() == State.TERMINATED) return;
|
||||||
|
|
||||||
// To avoid a RejectedExecutionException, use an executor that
|
DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fSession.getId());
|
||||||
// immediately executes in the same dispatch cycle.
|
IProcesses procService = tracker.getService(IProcesses.class);
|
||||||
ICommand<MIInfo> cmd = fCommandFactory.createCLIExecAbort(getCommandControlService().getContext());
|
tracker.dispose();
|
||||||
getCommandControlService().queueCommand(
|
if (procService != null) {
|
||||||
cmd,
|
IProcessDMContext procDmc = DMContexts.getAncestorOfType(fContainerDMContext, IProcessDMContext.class);
|
||||||
new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), null) {
|
procService.terminate(procDmc, new RequestMonitor(ImmediateExecutor.getInstance(), null));
|
||||||
@Override
|
} else {
|
||||||
protected void handleCompleted() {
|
setState(State.TERMINATED);
|
||||||
setState(MIInferiorProcess.State.TERMINATED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
public synchronized State getState() {
|
public synchronized State getState() {
|
||||||
|
@ -406,12 +407,6 @@ public class MIInferiorProcess extends Process
|
||||||
if (fState == State.TERMINATED) return;
|
if (fState == State.TERMINATED) return;
|
||||||
fState = state;
|
fState = state;
|
||||||
if (fState == State.TERMINATED) {
|
if (fState == State.TERMINATED) {
|
||||||
if (fContainerDMContext != null) {
|
|
||||||
// This may not be necessary in 7.0 because of the =thread-group-exited event
|
|
||||||
getSession().dispatchEvent(
|
|
||||||
new ContainerExitedDMEvent(fContainerDMContext),
|
|
||||||
getCommandControlService().getProperties());
|
|
||||||
}
|
|
||||||
closeIO();
|
closeIO();
|
||||||
}
|
}
|
||||||
notifyAll();
|
notifyAll();
|
||||||
|
@ -466,7 +461,14 @@ public class MIInferiorProcess extends Process
|
||||||
if (value instanceof MIConst) {
|
if (value instanceof MIConst) {
|
||||||
String reason = ((MIConst) value).getString();
|
String reason = ((MIConst) value).getString();
|
||||||
if ("exited-signalled".equals(reason) || "exited-normally".equals(reason) || "exited".equals(reason)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
if ("exited-signalled".equals(reason) || "exited-normally".equals(reason) || "exited".equals(reason)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
|
if (fContainerDMContext != null) {
|
||||||
|
// This may not be necessary in 7.0 because of the =thread-group-exited event
|
||||||
|
getSession().dispatchEvent(
|
||||||
|
new ContainerExitedDMEvent(fContainerDMContext),
|
||||||
|
getCommandControlService().getProperties());
|
||||||
|
} else {
|
||||||
setState(State.TERMINATED);
|
setState(State.TERMINATED);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setState(State.STOPPED);
|
setState(State.STOPPED);
|
||||||
}
|
}
|
||||||
|
@ -520,10 +522,29 @@ public class MIInferiorProcess extends Process
|
||||||
String state = rr.getResultClass();
|
String state = rr.getResultClass();
|
||||||
|
|
||||||
if ("running".equals(state)) { setState(State.RUNNING); }//$NON-NLS-1$
|
if ("running".equals(state)) { setState(State.RUNNING); }//$NON-NLS-1$
|
||||||
else if ("exit".equals(state)) { setState(State.TERMINATED); }//$NON-NLS-1$
|
else if ("exit".equals(state)) { //$NON-NLS-1$
|
||||||
|
if (fContainerDMContext != null) {
|
||||||
|
// This may not be necessary in 7.0 because of the =thread-group-exited event
|
||||||
|
getSession().dispatchEvent(
|
||||||
|
new ContainerExitedDMEvent(fContainerDMContext),
|
||||||
|
getCommandControlService().getProperties());
|
||||||
|
} else {
|
||||||
|
setState(State.TERMINATED);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if ("error".equals(state)) { setState(State.STOPPED); }//$NON-NLS-1$
|
else if ("error".equals(state)) { setState(State.STOPPED); }//$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
@DsfServiceEventHandler
|
||||||
|
public void eventDispatched(IExitedDMEvent e) {
|
||||||
|
if (e.getDMContext() instanceof IContainerDMContext) {
|
||||||
|
setState(State.TERMINATED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Post-poned because 'info program' yields different result on different platforms.
|
// Post-poned because 'info program' yields different result on different platforms.
|
||||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=305385#c20
|
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=305385#c20
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2011 Ericsson 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:
|
||||||
|
* Ericsson - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MIInterpreterExecConsoleKill
|
||||||
|
* Send the CLI Kill command for a specific process.
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
public class MIInterpreterExecConsoleKill extends MIInterpreterExecConsole<MIInfo> {
|
||||||
|
|
||||||
|
public MIInterpreterExecConsoleKill(IMIContainerDMContext ctx) {
|
||||||
|
super(ctx, "kill"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue