mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 350365: Remote attach session should use specified binary
This commit is contained in:
parent
97771a4879
commit
9aae4c9dec
2 changed files with 55 additions and 16 deletions
|
@ -13,6 +13,7 @@ package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
|
@ -41,8 +42,10 @@ 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;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
import org.eclipse.core.runtime.Status;
|
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;
|
||||||
|
@ -58,6 +61,16 @@ public class GdbConnectCommand implements IConnect {
|
||||||
private final DsfExecutor fExecutor;
|
private final DsfExecutor fExecutor;
|
||||||
private final DsfServicesTracker fTracker;
|
private final DsfServicesTracker fTracker;
|
||||||
|
|
||||||
|
// A map of processName to path, that allows us to remember the path to the binary file
|
||||||
|
// for a process with a particular name. We can then re-use the same binary for another
|
||||||
|
// process with the same name. This allows a user to connect to multiple processes
|
||||||
|
// with the same name without having to be prompted each time for a path.
|
||||||
|
// This map is associated to the current debug session only, therefore the user can
|
||||||
|
// reset it by using a new debug session.
|
||||||
|
// This map is only needed for remote sessions, since we don't need to specify
|
||||||
|
// the binary location for a local attach session.
|
||||||
|
private Map<String, String> fProcessNameToBinaryMap = new HashMap<String, String>();
|
||||||
|
|
||||||
public GdbConnectCommand(DsfSession session) {
|
public GdbConnectCommand(DsfSession session) {
|
||||||
fExecutor = session.getExecutor();
|
fExecutor = session.getExecutor();
|
||||||
fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId());
|
fTracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), session.getId());
|
||||||
|
@ -131,7 +144,7 @@ public class GdbConnectCommand implements IConnect {
|
||||||
Object result = prompter.handleStatus(processPromptStatus, info);
|
Object result = prompter.handleStatus(processPromptStatus, info);
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
fRequestMonitor.cancel();
|
fRequestMonitor.cancel();
|
||||||
} else if (result instanceof Integer || result instanceof String) {
|
} else if (result instanceof IProcessExtendedInfo || result instanceof String) {
|
||||||
fRequestMonitor.setData(result);
|
fRequestMonitor.setData(result);
|
||||||
} else {
|
} else {
|
||||||
fRequestMonitor.setStatus(NO_PID_STATUS);
|
fRequestMonitor.setStatus(NO_PID_STATUS);
|
||||||
|
@ -150,27 +163,54 @@ public class GdbConnectCommand implements IConnect {
|
||||||
private class PromptAndAttachToProcessJob extends UIJob {
|
private class PromptAndAttachToProcessJob extends UIJob {
|
||||||
private final String fPid;
|
private final String fPid;
|
||||||
private final RequestMonitor fRm;
|
private final RequestMonitor fRm;
|
||||||
|
private final String fProcName;
|
||||||
public PromptAndAttachToProcessJob(String pid, RequestMonitor rm) {
|
|
||||||
|
public PromptAndAttachToProcessJob(String pid, String procName, RequestMonitor rm) {
|
||||||
super(""); //$NON-NLS-1$
|
super(""); //$NON-NLS-1$
|
||||||
fPid = pid;
|
fPid = pid;
|
||||||
|
fProcName = procName;
|
||||||
fRm = rm;
|
fRm = rm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||||
String binaryPath = null;
|
|
||||||
|
|
||||||
Shell shell = Display.getCurrent().getActiveShell();
|
// If this is the very first attach of a remote session, check if the user
|
||||||
if (shell != null) {
|
// specified the binary in the launch. If so, let's add it to our map to
|
||||||
FileDialog fd = new FileDialog(shell, SWT.NONE);
|
// avoid having to prompt the user for that binary.
|
||||||
binaryPath = fd.open();
|
// This would be particularly annoying since we didn't use to have
|
||||||
|
// to do that before we supported multi-process.
|
||||||
|
// Bug 350365
|
||||||
|
if (fProcessNameToBinaryMap.isEmpty()) {
|
||||||
|
IGDBBackend backend = fTracker.getService(IGDBBackend.class);
|
||||||
|
if (backend != null) {
|
||||||
|
IPath binaryPath = backend.getProgramPath();
|
||||||
|
if (binaryPath != null && !binaryPath.isEmpty()) {
|
||||||
|
fProcessNameToBinaryMap.put(binaryPath.lastSegment(), binaryPath.toOSString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Have we already see the binary for a process with this name?
|
||||||
|
String binaryPath = fProcessNameToBinaryMap.get(fProcName);
|
||||||
|
|
||||||
|
if (binaryPath == null) {
|
||||||
|
// prompt for the binary path
|
||||||
|
Shell shell = Display.getCurrent().getActiveShell();
|
||||||
|
if (shell != null) {
|
||||||
|
FileDialog fd = new FileDialog(shell, SWT.NONE);
|
||||||
|
binaryPath = fd.open();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binaryPath == null) {
|
if (binaryPath == null) {
|
||||||
// The user pressed the cancel button, so we cancel the attach gracefully
|
// The user pressed the cancel button, so we cancel the attach gracefully
|
||||||
fRm.done();
|
fRm.done();
|
||||||
} else {
|
} else {
|
||||||
|
// Store the path of the binary so we can use it again for another process
|
||||||
|
// with the same name
|
||||||
|
fProcessNameToBinaryMap.put(fProcName, binaryPath);
|
||||||
|
|
||||||
final String finalBinaryPath = binaryPath;
|
final String finalBinaryPath = binaryPath;
|
||||||
fExecutor.execute(new DsfRunnable() {
|
fExecutor.execute(new DsfRunnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -250,17 +290,19 @@ public class GdbConnectCommand implements IConnect {
|
||||||
String binaryPath = (String)data;
|
String binaryPath = (String)data;
|
||||||
procService.debugNewProcess(
|
procService.debugNewProcess(
|
||||||
controlCtx, binaryPath,
|
controlCtx, binaryPath,
|
||||||
// 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 IProcessExtendedInfo) {
|
||||||
String pidStr = Integer.toString((Integer)data);
|
IProcessExtendedInfo process = (IProcessExtendedInfo)data;
|
||||||
|
String pidStr = Integer.toString(process.getPid());
|
||||||
final IGDBBackend backend = fTracker.getService(IGDBBackend.class);
|
final IGDBBackend backend = fTracker.getService(IGDBBackend.class);
|
||||||
if (backend != null && backend.getSessionType() == SessionType.REMOTE) {
|
if (backend != null && backend.getSessionType() == SessionType.REMOTE) {
|
||||||
// For remote attach, we must set the binary first so we need to prompt the user.
|
// For remote attach, we must set the binary first so we need to prompt the user.
|
||||||
// Because the prompt is a very long operation, we need to run outside the
|
// Because the prompt is a very long operation, we need to run outside the
|
||||||
// executor, so we don't lock it.
|
// executor, so we don't lock it.
|
||||||
// Bug 344892
|
// Bug 344892
|
||||||
new PromptAndAttachToProcessJob(pidStr, rm).schedule();
|
IPath processPath = new Path(process.getName());
|
||||||
|
String processShortName = processPath.lastSegment();
|
||||||
|
new PromptAndAttachToProcessJob(pidStr, processShortName, rm).schedule();
|
||||||
} else {
|
} else {
|
||||||
// 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 need to prompt for it.
|
// so we don't need to prompt for it.
|
||||||
|
|
|
@ -158,10 +158,7 @@ public class ProcessPrompter implements IStatusHandler {
|
||||||
return binaryPath;
|
return binaryPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
IProcessExtendedInfo processInfo = (IProcessExtendedInfo)dialog.getFirstResult();
|
return dialog.getFirstResult();
|
||||||
if (processInfo != null) {
|
|
||||||
return new Integer(processInfo.getPid());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue