1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-09 10:46:02 +02:00

Bug 237306: Support for Multi-Process debugging. Prompting the user for the path to the binary when doing a remote attach.

This commit is contained in:
Marc Khouzam 2011-03-11 16:35:34 +00:00
parent 461e44b498
commit c2239d41b8
6 changed files with 82 additions and 41 deletions

View file

@ -34,8 +34,10 @@ import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.dsf.gdb.internal.ui.launching.ProcessPrompter.PrompterInfo; import org.eclipse.cdt.dsf.gdb.internal.ui.launching.ProcessPrompter.PrompterInfo;
import org.eclipse.cdt.dsf.gdb.launching.IProcessExtendedInfo; import org.eclipse.cdt.dsf.gdb.launching.IProcessExtendedInfo;
import org.eclipse.cdt.dsf.gdb.launching.LaunchMessages; import org.eclipse.cdt.dsf.gdb.launching.LaunchMessages;
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses;
import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.IGdbThreadDMData; import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.IGdbThreadDMData;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses; import org.eclipse.cdt.dsf.gdb.service.SessionType;
import org.eclipse.cdt.dsf.service.DsfServicesTracker; import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -45,6 +47,11 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IStatusHandler; import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
public class GdbConnectCommand implements IConnect { public class GdbConnectCommand implements IConnect {
@ -181,7 +188,7 @@ public class GdbConnectCommand implements IConnect {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
// New cycle, look for service again // New cycle, look for service again
final IMIProcesses procService = fTracker.getService(IMIProcesses.class); final IGDBProcesses procService = fTracker.getService(IGDBProcesses.class);
if (procService != null) { if (procService != null) {
Object data = getData(); Object data = getData();
if (data instanceof String) { if (data instanceof String) {
@ -192,9 +199,27 @@ public class GdbConnectCommand implements IConnect {
// khouzam, maybe we should at least pass stopOnMain? // khouzam, maybe we should at least pass stopOnMain?
new HashMap<String, Object>(), new DataRequestMonitor<IDMContext>(fExecutor, rm)); new HashMap<String, Object>(), new DataRequestMonitor<IDMContext>(fExecutor, rm));
} else if (data instanceof Integer) { } else if (data instanceof Integer) {
final String[] binaryPath = new String[1];
binaryPath[0] = null;
final IGDBBackend backend = fTracker.getService(IGDBBackend.class);
if (backend != null && backend.getSessionType() == SessionType.REMOTE) {
// For remote attach, we must set the binary first
// For a local attach, GDB can figure out the binary automatically,
// so we don't specify it.
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
public void run() {
Shell shell = Display.getCurrent().getActiveShell();
if (shell != null) {
FileDialog fd = new FileDialog(shell, SWT.NONE);
binaryPath[0] = fd.open();
}
}
});
}
IProcessDMContext procDmc = procService.createProcessContext(controlCtx, IProcessDMContext procDmc = procService.createProcessContext(controlCtx,
Integer.toString((Integer)getData())); Integer.toString((Integer)getData()));
procService.attachDebuggerToProcess(procDmc, new DataRequestMonitor<IDMContext>(fExecutor, rm)); procService.attachDebuggerToProcess(procDmc, binaryPath[0], new DataRequestMonitor<IDMContext>(fExecutor, rm));
} else { } else {
rm.setStatus(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid return type for process prompter", null)); //$NON-NLS-1$ rm.setStatus(new Status(IStatus.ERROR, GdbUIPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid return type for process prompter", null)); //$NON-NLS-1$
rm.done(); rm.done();

View file

@ -30,7 +30,7 @@ public class ProcessPrompterDialog extends TwoPaneElementSelector {
@Override @Override
protected void buttonPressed(int buttonId) { protected void buttonPressed(int buttonId) {
if (buttonId == NEW_BUTTON_ID) { if (buttonId == NEW_BUTTON_ID) {
FileDialog fd = new FileDialog(getShell(), SWT.SAVE); FileDialog fd = new FileDialog(getShell(), SWT.NONE);
fBinaryPath = fd.open(); fBinaryPath = fd.open();
setReturnCode(OK); setReturnCode(OK);

View file

@ -57,7 +57,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.CoreException; import org.eclipse.core.runtime.CoreException;
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.Platform;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
@ -224,11 +223,14 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
} }
@Override @Override
public void attachDebuggerToProcess(final IProcessDMContext procCtx, final DataRequestMonitor<IDMContext> rm) { public void attachDebuggerToProcess(IProcessDMContext procCtx, DataRequestMonitor<IDMContext> rm) {
// For remote attach, we must set the binary first attachDebuggerToProcess(procCtx, null, rm);
// For a local attach, GDB can figure out the binary automatically, }
// so we don't specify it.
/**
* @since 4.0
*/
public void attachDebuggerToProcess(final IProcessDMContext procCtx, String binaryPath, final DataRequestMonitor<IDMContext> rm) {
final 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) {
@ -253,14 +255,11 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses {
} }
}; };
if (fBackend.getSessionType() == SessionType.REMOTE) { if (binaryPath != null) {
final IPath execPath = fBackend.getProgramPath(); fGdb.queueCommand(
if (execPath != null && !execPath.isEmpty()) { fCommandFactory.createMIFileExecAndSymbols(containerDmc, binaryPath),
fGdb.queueCommand( attachRm);
fCommandFactory.createMIFileExecAndSymbols(containerDmc, execPath.toPortableString()), return;
attachRm);
return;
}
} }
// If we get here, let's do the attach by completing the requestMonitor // If we get here, let's do the attach by completing the requestMonitor

View file

@ -79,7 +79,6 @@ import org.eclipse.cdt.dsf.service.AbstractDsfService;
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.CoreException; import org.eclipse.core.runtime.CoreException;
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.Platform;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
@ -754,7 +753,14 @@ public class GDBProcesses_7_0 extends AbstractDsfService
rm.done(); rm.done();
} }
public void attachDebuggerToProcess(final IProcessDMContext procCtx, final DataRequestMonitor<IDMContext> dataRm) { public void attachDebuggerToProcess(IProcessDMContext procCtx, DataRequestMonitor<IDMContext> rm) {
attachDebuggerToProcess(procCtx, null, rm);
}
/**
* @since 4.0
*/
public void attachDebuggerToProcess(final IProcessDMContext procCtx, final String binaryPath, final DataRequestMonitor<IDMContext> dataRm) {
if (procCtx instanceof IMIProcessDMContext) { if (procCtx instanceof IMIProcessDMContext) {
if (!doIsDebuggerAttachSupported()) { if (!doIsDebuggerAttachSupported()) {
dataRm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Attach not supported.", null)); //$NON-NLS-1$ dataRm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Attach not supported.", null)); //$NON-NLS-1$
@ -784,14 +790,11 @@ public class GDBProcesses_7_0 extends AbstractDsfService
// There is no groupId until we attach, so we can use the default groupId // There is no groupId until we attach, so we can use the default groupId
fContainerDmc = createContainerContext(procCtx, MIProcesses.UNIQUE_GROUP_ID); fContainerDmc = createContainerContext(procCtx, MIProcesses.UNIQUE_GROUP_ID);
if (fBackend.getSessionType() == SessionType.REMOTE) { if (binaryPath != null) {
final IPath execPath = fBackend.getProgramPath(); fCommandControl.queueCommand(
if (execPath != null && !execPath.isEmpty()) { fCommandFactory.createMIFileExecAndSymbols(fContainerDmc, binaryPath),
fCommandControl.queueCommand( new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm));
fCommandFactory.createMIFileExecAndSymbols(fContainerDmc, execPath.toPortableString()), return;
new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm));
return;
}
} }
rm.done(); rm.done();

View file

@ -33,7 +33,6 @@ 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.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.service.DsfSession; 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.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunch;
@ -100,7 +99,15 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
} }
@Override @Override
public void attachDebuggerToProcess(final IProcessDMContext procCtx, final DataRequestMonitor<IDMContext> dataRm) { public void attachDebuggerToProcess(IProcessDMContext procCtx, DataRequestMonitor<IDMContext> rm) {
attachDebuggerToProcess(procCtx, null, rm);
}
/**
* @since 4.0
*/
@Override
public void attachDebuggerToProcess(final IProcessDMContext procCtx, final String binaryPath, final DataRequestMonitor<IDMContext> dataRm) {
if (procCtx instanceof IMIProcessDMContext) { if (procCtx instanceof IMIProcessDMContext) {
if (!doIsDebuggerAttachSupported()) { if (!doIsDebuggerAttachSupported()) {
dataRm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Attach not supported.", null)); //$NON-NLS-1$ dataRm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Attach not supported.", null)); //$NON-NLS-1$
@ -143,20 +150,14 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
}); });
} }
}, },
// For remote attach, we must set the binary first
// For a local attach, GDB can figure out the binary automatically,
// so we don't specify it.
new Step() { new Step() {
@Override @Override
public void execute(RequestMonitor rm) { public void execute(RequestMonitor rm) {
if (fBackend.getSessionType() == SessionType.REMOTE) { if (binaryPath != null) {
final IPath execPath = fBackend.getProgramPath(); fCommandControl.queueCommand(
if (execPath != null && !execPath.isEmpty()) { fCommandFactory.createMIFileExecAndSymbols(fContainerDmc, binaryPath),
fCommandControl.queueCommand( new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm));
fCommandFactory.createMIFileExecAndSymbols(fContainerDmc, execPath.toPortableString()), return;
new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm));
return;
}
} }
rm.done(); rm.done();

View file

@ -14,6 +14,7 @@ package org.eclipse.cdt.dsf.gdb.service;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext; import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
@ -91,4 +92,16 @@ public interface IGDBProcesses extends IMIProcesses {
*/ */
void start(IContainerDMContext containerDmc, Map<String, Object> attributes, DataRequestMonitor<IContainerDMContext> rm); void start(IContainerDMContext containerDmc, Map<String, Object> attributes, DataRequestMonitor<IContainerDMContext> rm);
/**
* Attaches debugger to the given process.
* When attaching to a process, a debugging context can now be used to characterize the process.
* This method can optionally choose to return this IDMContext inside the DataRequestMonitor.
* This can be useful for backends that do not have the ability to obtain the different
* debugging IDMContexts through {@link #getProcessesBeingDebugged(IDMContext, DataRequestMonitor)
*
* @param file Binary to use for the process.
* @since 4.0
*/
void attachDebuggerToProcess(IProcessDMContext procCtx, String file, DataRequestMonitor<IDMContext> rm);
} }