1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 237306: First part of commit for multi-process on Linux (GDB 7.2). It allows for a multi-process session for an attach debug session or a remote attach debug session.

This commit is contained in:
Marc Khouzam 2010-12-16 03:13:31 +00:00
parent 47f70de67b
commit d9d0cd6f17
10 changed files with 369 additions and 17 deletions

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Ericsson - initial API and implementation
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
@ -689,7 +690,8 @@ public class GDBProcesses_7_0 extends AbstractDsfService
rm.done();
}
private boolean doIsDebuggerAttachSupported() {
/** @since 4.0 */
protected boolean doIsDebuggerAttachSupported() {
IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
if (backend != null) {
return backend.getIsAttachSession();
@ -728,7 +730,8 @@ public class GDBProcesses_7_0 extends AbstractDsfService
}
}
private boolean doCanDetachDebuggerFromProcess() {
/** @since 4.0 */
protected boolean doCanDetachDebuggerFromProcess() {
IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
if (backend != null) {
return backend.getIsAttachSession() && fCommandControl.isConnected();

View file

@ -0,0 +1,154 @@
/*******************************************************************************
* Copyright (c) 2010 TUBITAK BILGEM-ITI 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:
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
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.command.ICommandControlService.ICommandControlDMContext;
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.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.output.MIAddInferiorInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
/**
* Adding support for multi-process with GDB 7.2
*
* @since 4.0
*/
public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
private CommandFactory fCommandFactory;
private IGDBControl fCommandControl;
public GDBProcesses_7_2(DsfSession session) {
super(session);
}
@Override
public void initialize(final RequestMonitor requestMonitor) {
super.initialize(new RequestMonitor(getExecutor(), requestMonitor) {
@Override
protected void handleSuccess() {
doInitialize(requestMonitor);
}
});
}
/**
* This method initializes this service after our superclass's initialize()
* method succeeds.
*
* @param requestMonitor
* The call-back object to notify when this service's
* initialization is done.
*/
private void doInitialize(RequestMonitor requestMonitor) {
fCommandControl = getServicesTracker().getService(IGDBControl.class);
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
requestMonitor.done();
}
@Override
public void shutdown(RequestMonitor requestMonitor) {
super.shutdown(requestMonitor);
}
@Override
public void attachDebuggerToProcess(final IProcessDMContext procCtx, final DataRequestMonitor<IDMContext> rm) {
if (procCtx instanceof IMIProcessDMContext) {
if (!doIsDebuggerAttachSupported()) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Attach not supported.", null)); //$NON-NLS-1$
rm.done();
return;
}
ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(procCtx, ICommandControlDMContext.class);
fCommandControl.queueCommand(
fCommandFactory.createMIAddInferior(controlDmc),
new DataRequestMonitor<MIAddInferiorInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
final String groupId = getData().getGroupId();
if (groupId == null || groupId.trim().length() == 0) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid gdb group id.", null)); //$NON-NLS-1$
rm.done();
return;
}
final IMIContainerDMContext containerDmc = createContainerContext(procCtx, groupId);
fCommandControl.queueCommand(
fCommandFactory.createMITargetAttach(containerDmc, ((IMIProcessDMContext)procCtx).getProcId()),
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
rm.setData(containerDmc);
rm.done();
}
});
}
});
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$
rm.done();
}
}
@Override
public void detachDebuggerFromProcess(IDMContext dmc, final RequestMonitor rm) {
ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class);
final IMIContainerDMContext containerDmc = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
if (controlDmc != null && containerDmc != null) {
if (!doCanDetachDebuggerFromProcess()) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Detach not supported.", null)); //$NON-NLS-1$
rm.done();
return;
}
fCommandControl.queueCommand(
fCommandFactory.createMITargetDetach(controlDmc, containerDmc.getGroupId()),
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
// Bug in GDB 7.2 where removing an inferior will lead to a crash when running other processes.
// I'm hoping it will be fixed in 7.2.1
// fCommandControl.queueCommand(
// fCommandFactory.createMIRemoveInferior(fCommandControl.getContext(), containerDmc.getGroupId()),
// new DataRequestMonitor<MIInfo>(getExecutor(), rm));
} else {
// This command fails with GDB 7.2 because of a GDB bug, which was fixed with GDB 7.2.1
// In case we get here, we assume we are using GDB 7.2 (although we should not) and we work
// around it.
// Also, with GDB 7.2, removing the inferior does not work because of another bug, so we just don't do it.
fCommandControl.queueCommand(
fCommandFactory.createMITargetDetach(containerDmc),
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
}
}
});
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid context.", null)); //$NON-NLS-1$
rm.done();
}
}
}

View file

@ -8,6 +8,7 @@
* Contributors:
* Ericsson - initial API and implementation
* Nokia - create and use backend service.
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
@ -27,6 +28,7 @@ import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
import org.eclipse.cdt.dsf.gdb.service.command.CommandFactory_6_8;
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl;
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_0;
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_2;
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints;
@ -100,6 +102,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
}
protected ICommandControl createCommandControl(DsfSession session, ILaunchConfiguration config) {
if (GDB_7_2_VERSION.compareTo(fVersion) <= 0) {
return new GDBControl_7_2(session, config, new CommandFactory_6_8());
}
if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) {
return new GDBControl_7_0(session, config, new CommandFactory_6_8());
}
@ -139,6 +144,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
@Override
protected IProcesses createProcessesService(DsfSession session) {
if (GDB_7_2_VERSION.compareTo(fVersion) <= 0) {
return new GDBProcesses_7_2(session);
}
if (GDB_7_1_VERSION.compareTo(fVersion) <= 0) {
return new GDBProcesses_7_1(session);
}

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2010 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.gdb.service.command;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.debug.core.ILaunchConfiguration;
/**
* Turn on the use of the --thread-group option for GDB 7.2
* @since 4.0
*/
public class GDBControl_7_2 extends GDBControl_7_0 implements IGDBControl {
public GDBControl_7_2(DsfSession session, ILaunchConfiguration config, CommandFactory factory) {
super(session, config, factory);
setUseThreadGroupOptions(true);
}
}

View file

@ -9,6 +9,7 @@
* Wind River Systems - initial API and implementation
* Ericsson - Modified for handling of multiple stacks and threads
* Nokia - create and use backend service.
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command;
@ -40,6 +41,7 @@ import org.eclipse.cdt.dsf.debug.service.command.ICommandToken;
import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand;
import org.eclipse.cdt.dsf.mi.service.command.commands.RawCommand;
@ -86,6 +88,9 @@ public abstract class AbstractMIControl extends AbstractDsfService
private int fCurrentStackLevel = -1;
private String fCurrentThreadId = null;
// boolean for --thread-group option which helps to handle multiple inferior behavior.
// Since GDB.7.1
private boolean fUseThreadGroupOption;
private final BlockingQueue<CommandHandle> fTxCommands = new LinkedBlockingQueue<CommandHandle>();
private final Map<Integer, CommandHandle> fRxCommands = Collections.synchronizedMap(new HashMap<Integer, CommandHandle>());
@ -124,17 +129,32 @@ public abstract class AbstractMIControl extends AbstractDsfService
private CommandFactory fCommandFactory;
public AbstractMIControl(DsfSession session) {
super(session);
fUseThreadAndFrameOptions = false;
fCommandFactory = new CommandFactory();
this(session, false, false, new CommandFactory());
}
/**
* @since 3.0
*/
public AbstractMIControl(DsfSession session, boolean useThreadAndFrameOptions, CommandFactory factory) {
this(session, false, useThreadAndFrameOptions, factory);
}
/**
* @since 4.0
*/
public AbstractMIControl(DsfSession session, boolean useThreadGroupOption, boolean useThreadAndFrameOptions, CommandFactory factory) {
super(session);
// If we use the --thread-group option, we should automatically use the --thread/--frame option
// since the --thread-group was added to GDB later than the --thread/--frame option
assert useThreadGroupOption ? useThreadAndFrameOptions : true;
fUseThreadGroupOption = useThreadGroupOption;
fUseThreadAndFrameOptions = useThreadAndFrameOptions;
if (fUseThreadGroupOption) {
// If we use --thread-group option, we should automatically use the --thread option
fUseThreadAndFrameOptions = true;
}
fCommandFactory = factory;
}
@ -164,6 +184,16 @@ public abstract class AbstractMIControl extends AbstractDsfService
fUseThreadAndFrameOptions = shouldUse;
}
/**
* @since 4.0
*/
protected void setUseThreadGroupOptions(boolean shouldUse) {
fUseThreadGroupOption = shouldUse;
if (shouldUse) {
fUseThreadAndFrameOptions = true;
}
}
/**
* @since 3.0
*/
@ -510,6 +540,13 @@ public abstract class AbstractMIControl extends AbstractDsfService
return null;
}
public String getGroupId() {
IMIContainerDMContext containerCtx = DMContexts.getAncestorOfType(fCommand.getContext(), IMIContainerDMContext.class);
if(containerCtx != null)
return containerCtx.getGroupId();
return null;
}
@Override
public String toString() {
return Integer.toString(fTokenId) + fCommand;
@ -567,13 +604,17 @@ public abstract class AbstractMIControl extends AbstractDsfService
*/
final String str;
// Not all commands support the --thread/--frame options (e.g., CLI commands)
if (fUseThreadAndFrameOptions && commandHandle.getCommand().supportsThreadAndFrameOptions()) {
str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand(commandHandle.getThreadId(),
commandHandle.getStackFrameId());
} else if (commandHandle.getCommand() instanceof RawCommand) {
if (commandHandle.getCommand() instanceof RawCommand) {
// RawCommands CANNOT have a token id: GDB would read it as part of the RawCommand!
str = commandHandle.getCommand().constructCommand();
} else if (fUseThreadGroupOption) {
// Implies that fUseThreadAndFrameOptions == true
str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand(commandHandle.getGroupId(),
commandHandle.getThreadId(),
commandHandle.getStackFrameId());
} else if (fUseThreadAndFrameOptions) {
str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand(commandHandle.getThreadId(),
commandHandle.getStackFrameId());
} else {
str = commandHandle.getTokenId() + commandHandle.getCommand().constructCommand();
}

View file

@ -12,6 +12,7 @@
* Anna Dushistova (Mentor Graphics) - [318322] Add set solib-absolute-prefix
* Vladimir Prus (CodeSourcery) - Support for -data-read-memory-bytes (bug 322658)
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command;
@ -28,6 +29,7 @@ import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.gdb.service.IGDBTraceControl.ITraceTargetDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIAttach;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICatch;
@ -525,14 +527,26 @@ public class CommandFactory {
return new MIExecUntil(dmc, loc);
}
@Deprecated
public ICommand<MIInfo> createMIFileExecAndSymbols(ICommandControlDMContext dmc, String file) {
return new MIFileExecAndSymbols(dmc, file);
}
@Deprecated
public ICommand<MIInfo> createMIFileExecAndSymbols(ICommandControlDMContext dmc) {
return new MIFileExecAndSymbols(dmc);
}
/** @since 4.0 */
public ICommand<MIInfo> createMIFileExecAndSymbols(IMIContainerDMContext dmc, String file) {
return new MIFileExecAndSymbols(dmc, file);
}
/** @since 4.0 */
public ICommand<MIInfo> createMIFileExecAndSymbols(IMIContainerDMContext dmc) {
return new MIFileExecAndSymbols(dmc);
}
public ICommand<MIInfo> createMIFileExecFile(ICommandControlDMContext dmc, String file) {
return new MIFileExecFile(dmc, file);
}
@ -682,14 +696,25 @@ public class CommandFactory {
return new MIStackSelectFrame(ctx, frameNum);
}
@Deprecated
public ICommand<MIInfo> createMITargetAttach(ICommandControlDMContext ctx, String groupId) {
return new MITargetAttach(ctx, groupId);
}
/** @since 4.0 */
public ICommand<MIInfo> createMITargetAttach(IMIContainerDMContext ctx, String groupId) {
return new MITargetAttach(ctx, groupId);
}
public ICommand<MIInfo> createMITargetDetach(ICommandControlDMContext ctx, String groupId) {
return new MITargetDetach(ctx, groupId);
}
/** @since 4.0 */
public ICommand<MIInfo> createMITargetDetach(IMIContainerDMContext ctx) {
return new MITargetDetach(ctx);
}
public ICommand<MIInfo> createMITargetSelect(IDMContext ctx, String[] params) {
return new MITargetSelect(ctx, params);
}

View file

@ -9,6 +9,7 @@
* QNX Software Systems - Initial API and implementation
* Wind River Systems - Modified for new DSF Reference Implementation
* Ericsson - Modified for additional features in DSF Reference implementation and bug 219920
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
@ -141,16 +142,27 @@ public class MICommand<V extends MIInfo> implements ICommand<V> {
* @since 1.1
*/
public String constructCommand(String threadId, int frameId) {
return constructCommand(null, threadId, frameId);
}
/**
* With GDB 7.1 the --thread-group option is used to support multiple processes.
* @since 4.0
*/
public String constructCommand(String groupId, String threadId, int frameId) {
StringBuffer command = new StringBuffer(getOperation());
// Add the --thread option
if (threadId != null) {
if (supportsThreadAndFrameOptions() && threadId != null) {
command.append(" --thread " + threadId); //$NON-NLS-1$
// Add the --frame option, but only if we are using the --thread option
if (frameId >= 0) {
command.append(" --frame " + frameId); //$NON-NLS-1$
}
} else if (supportsThreadGroupOption() && groupId != null) {
// The --thread-group option is only allowed if we are not using the --thread option
command.append(" --thread-group " + groupId); //$NON-NLS-1$
}
String opt = optionsToString();
@ -242,6 +254,11 @@ public class MICommand<V extends MIInfo> implements ICommand<V> {
*/
public boolean supportsThreadAndFrameOptions() { return true; }
/**
* @since 4.0
*/
public boolean supportsThreadGroupOption() { return false; }
/**
* Compare commands based on the MI command string that they generate,
* without the token.

View file

@ -7,11 +7,13 @@
*
* Contributors:
* Ericsson - Initial API and implementation
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
/**
@ -27,15 +29,36 @@ public class MIFileExecAndSymbols extends MICommand<MIInfo>
{
/**
* @since 1.1
* @deprecated Replaced with MIFileExecAndSymbols(IMIContainerDMContext, String)
* since this command is container-specific
*/
@Deprecated
public MIFileExecAndSymbols(ICommandControlDMContext dmc, String file) {
super(dmc, "-file-exec-and-symbols", null, new String[] {file}); //$NON-NLS-1$
}
/**
* @since 1.1
* @deprecated Replaced with MIFileExecAndSymbols(IMIContainerDMContext)
* since this command is container-specific
*/
@Deprecated
public MIFileExecAndSymbols(ICommandControlDMContext dmc) {
super(dmc, "-file-exec-and-symbols"); //$NON-NLS-1$
}
/** @since 4.0 */
public MIFileExecAndSymbols(IMIContainerDMContext dmc) {
this(dmc, null);
}
/** @since 4.0 */
public MIFileExecAndSymbols(IMIContainerDMContext dmc, String file) {
super(dmc, "-file-exec-and-symbols", null, file == null ? null : new String[] {file}); //$NON-NLS-1$
}
@Override
public boolean supportsThreadGroupOption() {
return true;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Ericsson and others.
* Copyright (c) 2008, 2010 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
@ -7,22 +7,47 @@
*
* Contributors:
* Ericsson - Initial API and implementation
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
/**
* -target-attach < --pid PID | THREAD_GROUP_ID >
* -target-attach < PID | THREAD_GROUP_ID >
*
* This command attaches to the process specified by the PID
* or THREAD_GROUP_ID
* or THREAD_GROUP_ID. If attaching to a thread group, the id
* previously returned by `-list-thread-groups --available' must be used.
*
* @since 1.1
*/
public class MITargetAttach extends MICommand<MIInfo> {
/**
* @deprecated Replaced with MITargetAttach(IMIContainerDMContext, String)
* since this command is container-specific
*/
@Deprecated
public MITargetAttach(ICommandControlDMContext ctx, String groupId) {
super(ctx, "-target-attach", new String[] {groupId}); //$NON-NLS-1$
}
/**
* @param ctx indicates which inferior should be used when doing the attach
* @param id the pid of the process to attach to
*
* @since 4.0
*/
public MITargetAttach(IMIContainerDMContext ctx, String pid) {
super(ctx, "-target-attach", new String[] { pid }); //$NON-NLS-1$
}
@Override
public boolean supportsThreadGroupOption() {
return true;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Ericsson and others.
* Copyright (c) 2008, 2010 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
@ -7,14 +7,16 @@
*
* Contributors:
* Ericsson - Initial API and implementation
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
/**
* -target-detach < --pid PID | THREAD_GROUP_ID >
* -target-detach < PID | THREAD_GROUP_ID >
*
* This command detaches from the process specified by the PID
* or THREAD_GROUP_ID
@ -22,7 +24,35 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
*/
public class MITargetDetach extends MICommand<MIInfo> {
/*
* No need to specify an IMIContainerDMContext because
* only one such context is associated with ID; therefore,
* GDB will know which inferior to detach using only ID.
*/
public MITargetDetach(ICommandControlDMContext ctx, String groupId) {
super(ctx, "-target-detach", new String[] {groupId}); //$NON-NLS-1$
}
/*
* This method does not follow our convention of passing the highest required
* context and proper parameters. The proper way is handled by the method above
* MITargetDetach(ICommandControlDMContext, String)
* However, this method here will trigger the command in the form
* Form 1: -target-detach --thread-group i2
* instead of the way the above method does, which is
* Form 2: -target-detach i2
* Because of a bug in GDB 7.2, form 2 does not work.
* However, this has been fixed with GDB 7.2.1, which is why we keep both
* approaches.
*/
/** @since 4.0 */
public MITargetDetach(IMIContainerDMContext ctx) {
super(ctx, "-target-detach"); //$NON-NLS-1$
}
@Override
public boolean supportsThreadGroupOption() {
return true;
}
}