mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 239050
Make the FinalLaunchSequence use the IProcesses.getRunningProcesses() call instead of doing the work itself.
This commit is contained in:
parent
6f836fba11
commit
65b52f3a07
3 changed files with 213 additions and 89 deletions
|
@ -15,9 +15,7 @@ import java.io.FileNotFoundException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.IProcessInfo;
|
||||
import org.eclipse.cdt.core.IProcessList;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
||||
import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector;
|
||||
|
@ -33,12 +31,14 @@ import org.eclipse.core.runtime.Path;
|
|||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.core.variables.VariablesPlugin;
|
||||
import org.eclipse.dd.dsf.concurrent.CountingRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.Sequence;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IThreadDMData;
|
||||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants;
|
||||
|
@ -47,7 +47,7 @@ import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
|
|||
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType;
|
||||
import org.eclipse.dd.mi.service.CSourceLookup;
|
||||
import org.eclipse.dd.mi.service.MIBreakpointsManager;
|
||||
import org.eclipse.dd.mi.service.command.commands.CLIMonitorListProcesses;
|
||||
import org.eclipse.dd.mi.service.ProcessInfo;
|
||||
import org.eclipse.dd.mi.service.command.commands.CLISource;
|
||||
import org.eclipse.dd.mi.service.command.commands.MIEnvironmentCD;
|
||||
import org.eclipse.dd.mi.service.command.commands.MIFileExecAndSymbols;
|
||||
|
@ -56,10 +56,8 @@ import org.eclipse.dd.mi.service.command.commands.MIGDBSetAutoSolib;
|
|||
import org.eclipse.dd.mi.service.command.commands.MIGDBSetSolibSearchPath;
|
||||
import org.eclipse.dd.mi.service.command.commands.MIGDBSetSysroot;
|
||||
import org.eclipse.dd.mi.service.command.commands.MITargetSelect;
|
||||
import org.eclipse.dd.mi.service.command.output.CLIMonitorListProcessesInfo;
|
||||
import org.eclipse.dd.mi.service.command.output.MIInfo;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.IStatusHandler;
|
||||
|
||||
public class FinalLaunchSequence extends Sequence {
|
||||
|
@ -361,72 +359,53 @@ public class FinalLaunchSequence extends Sequence {
|
|||
* If attach session, perform the attach.
|
||||
*/
|
||||
new Step() {
|
||||
private void promptForProcessID(final ILaunchConfiguration config, final DataRequestMonitor<Integer> rm) {
|
||||
|
||||
// Need a job because prompter.handleStatus will block
|
||||
class PromptForPidJob extends Job {
|
||||
|
||||
// The list of processes used in the case of an ATTACH session
|
||||
IProcessInfo[] fProcessList = null;
|
||||
DataRequestMonitor<IProcessDMContext> fRequestMonitor;
|
||||
|
||||
public PromptForPidJob(String name, IProcessInfo[] procs, DataRequestMonitor<IProcessDMContext> rm) {
|
||||
super(name);
|
||||
fProcessList = procs;
|
||||
fRequestMonitor = rm;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
IStatus promptStatus = new Status(IStatus.INFO, "org.eclipse.debug.ui", 200/*STATUS_HANDLER_PROMPT*/, "", null); //$NON-NLS-1$//$NON-NLS-2$
|
||||
final IStatus processPromptStatus = new Status(IStatus.INFO, "org.eclipse.dd.gdb.ui", 100, "", null); //$NON-NLS-1$//$NON-NLS-2$
|
||||
|
||||
final IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(promptStatus);
|
||||
|
||||
final Status noPidStatus = new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1,
|
||||
final Status NO_PID_STATUS = new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1,
|
||||
LaunchMessages.getString("LocalAttachLaunchDelegate.No_Process_ID_selected"), //$NON-NLS-1$
|
||||
null);
|
||||
|
||||
if (prompter == null) {
|
||||
rm.setStatus(noPidStatus);
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
// Need a job because prompter.handleStatus will block
|
||||
final Job promptForPid = new Job("Prompt for Process") { //$NON-NLS-1$
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
try {
|
||||
Object result = prompter.handleStatus(processPromptStatus, fProcessList);
|
||||
if (result instanceof Integer) {
|
||||
rm.setData((Integer)result);
|
||||
} else {
|
||||
rm.setStatus(noPidStatus);
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
rm.setStatus(noPidStatus);
|
||||
}
|
||||
rm.done();
|
||||
fRequestMonitor.setStatus(NO_PID_STATUS);
|
||||
fRequestMonitor.done();
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
return Status.OK_STATUS;
|
||||
try {
|
||||
Object result = prompter.handleStatus(processPromptStatus, fProcessList);
|
||||
if (result instanceof Integer) {
|
||||
fRequestMonitor.setData(fProcService.createProcessContext(Integer.toString((Integer)result)));
|
||||
} else {
|
||||
fRequestMonitor.setStatus(NO_PID_STATUS);
|
||||
}
|
||||
};
|
||||
|
||||
if (fSessionType == SessionType.LOCAL) {
|
||||
try {
|
||||
IProcessList list = CCorePlugin.getDefault().getProcessList();
|
||||
if (list != null) fProcessList = list.getProcessList();
|
||||
} catch (CoreException e) {
|
||||
} finally {
|
||||
// If the list is null, the prompter will deal with it
|
||||
promptForPid.schedule();
|
||||
}
|
||||
} else {
|
||||
fCommandControl.queueCommand(
|
||||
new CLIMonitorListProcesses(fCommandControl.getControlDMContext()),
|
||||
new DataRequestMonitor<CLIMonitorListProcessesInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
fProcessList = getData().getProcessList();
|
||||
} else {
|
||||
// The monitor list command is not supported.
|
||||
// Just set the list to empty and let the user
|
||||
// put in the pid directly.
|
||||
fProcessList = new IProcessInfo[0];
|
||||
}
|
||||
|
||||
promptForPid.schedule();
|
||||
}
|
||||
});
|
||||
} catch (CoreException e) {
|
||||
fRequestMonitor.setStatus(NO_PID_STATUS);
|
||||
}
|
||||
}
|
||||
fRequestMonitor.done();
|
||||
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void execute(final RequestMonitor requestMonitor) {
|
||||
if (fAttach) {
|
||||
|
@ -440,25 +419,61 @@ public class FinalLaunchSequence extends Sequence {
|
|||
}
|
||||
|
||||
if (pid != -1) {
|
||||
//FIXME
|
||||
IProcessDMContext procDmc =
|
||||
fProcService.createProcessContext(Integer.toString(pid));
|
||||
|
||||
fProcService.attachDebuggerToProcess(
|
||||
procDmc,
|
||||
new DataRequestMonitor<IDMContext>(getExecutor(), requestMonitor));
|
||||
new DataRequestMonitor<IDMContext>(getExecutor(), requestMonitor));
|
||||
} else {
|
||||
promptForProcessID(fLaunch.getLaunchConfiguration(),
|
||||
new DataRequestMonitor<Integer>(getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
IProcessDMContext procDmc =
|
||||
fProcService.createProcessContext(Integer.toString(getData()));
|
||||
fProcService.getRunningProcesses(
|
||||
fCommandControl.getGDBDMContext(),
|
||||
new DataRequestMonitor<IProcessDMContext[]>(getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
|
||||
final List<IProcessInfo> procInfoList = new ArrayList<IProcessInfo>();
|
||||
|
||||
// For each process, obtain its name
|
||||
// Once all the names are obtained, prompt the user the pid to use
|
||||
final CountingRequestMonitor countingRm =
|
||||
new CountingRequestMonitor(getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
new PromptForPidJob(
|
||||
"Prompt for Process", procInfoList.toArray(new IProcessInfo[0]), //$NON-NLS-1$
|
||||
new DataRequestMonitor<IProcessDMContext>(getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
fProcService.attachDebuggerToProcess(
|
||||
getData(),
|
||||
new DataRequestMonitor<IDMContext>(getExecutor(), requestMonitor));
|
||||
}
|
||||
}).schedule();
|
||||
}
|
||||
};
|
||||
|
||||
fProcService.attachDebuggerToProcess(
|
||||
procDmc,
|
||||
new DataRequestMonitor<IDMContext>(getExecutor(), requestMonitor));
|
||||
}
|
||||
});
|
||||
countingRm.setDoneCount(getData().length);
|
||||
|
||||
for (IProcessDMContext processCtx : getData()) {
|
||||
fProcService.getExecutionData(
|
||||
processCtx,
|
||||
new DataRequestMonitor<IThreadDMData> (getExecutor(), countingRm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
int pid = 0;
|
||||
try {
|
||||
pid = Integer.parseInt(getData().getId());
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
procInfoList.add(new ProcessInfo(pid, getData().getName()));
|
||||
countingRm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
requestMonitor.done();
|
||||
|
@ -492,10 +507,7 @@ public class FinalLaunchSequence extends Sequence {
|
|||
|
||||
GDBControl fCommandControl;
|
||||
GDBProcesses fProcService;
|
||||
|
||||
// The list of processes used in the case of an ATTACH session
|
||||
IProcessInfo[] fProcessList = null;
|
||||
|
||||
|
||||
public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType sessionType, boolean attach) {
|
||||
super(executor);
|
||||
fLaunch = launch;
|
||||
|
|
|
@ -10,9 +10,14 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.gdb.internal.provisional.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.IProcessInfo;
|
||||
import org.eclipse.cdt.core.IProcessList;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
|
@ -25,6 +30,7 @@ import org.eclipse.dd.dsf.service.AbstractDsfService;
|
|||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType;
|
||||
import org.eclipse.dd.mi.service.command.commands.CLIAttach;
|
||||
import org.eclipse.dd.mi.service.command.commands.CLIMonitorListProcesses;
|
||||
import org.eclipse.dd.mi.service.command.output.CLIMonitorListProcessesInfo;
|
||||
|
@ -126,6 +132,10 @@ public class GDBProcesses extends AbstractDsfService implements IProcesses {
|
|||
}
|
||||
|
||||
private GDBControl fCommandControl;
|
||||
|
||||
// A map of pid to names. It is filled when we get all the
|
||||
// processes that are running
|
||||
private Map<Integer, String> fProcessNames = new HashMap<Integer, String>();
|
||||
|
||||
public GDBProcesses(DsfSession session) {
|
||||
super(session);
|
||||
|
@ -231,8 +241,17 @@ public class GDBProcesses extends AbstractDsfService implements IProcesses {
|
|||
public void getExecutionData(IThreadDMContext dmc, DataRequestMonitor<IThreadDMData> rm) {
|
||||
// We must first check for GdbProcessDMC because it is also a GdbThreadDMC
|
||||
if (dmc instanceof GdbProcessDMC) {
|
||||
rm.setData(new GdbThreadDMData(fCommandControl.getExecutablePath().lastSegment(),
|
||||
((GdbProcessDMC)dmc).getId()));
|
||||
String pidStr = ((GdbProcessDMC)dmc).getId();
|
||||
int pid = 0;
|
||||
try {
|
||||
pid = Integer.parseInt(pidStr);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
|
||||
String name = fProcessNames.get(pid);
|
||||
// If we don't find the name in our list, return the default name of our program
|
||||
if (name == null) name = fCommandControl.getExecutablePath().lastSegment();
|
||||
rm.setData(new GdbThreadDMData(name, pidStr));
|
||||
rm.done();
|
||||
} else if (dmc instanceof GdbThreadDMC) {
|
||||
rm.setData(new GdbThreadDMData("", ((GdbThreadDMC)dmc).getId())); //$NON-NLS-1$
|
||||
|
@ -317,22 +336,60 @@ public class GDBProcesses extends AbstractDsfService implements IProcesses {
|
|||
rm.done();
|
||||
}
|
||||
|
||||
public void getRunningProcesses(IDMContext dmc, DataRequestMonitor<IProcessDMContext[]> rm) {
|
||||
// monitor list processes is only for remote session
|
||||
fCommandControl.queueCommand(
|
||||
new CLIMonitorListProcesses(dmc),
|
||||
new DataRequestMonitor<CLIMonitorListProcessesInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
IProcessInfo[] processes = getData().getProcessList();
|
||||
IProcessDMContext[] procDmcs = new GdbProcessDMC[processes.length];
|
||||
for (int i=0; i<procDmcs.length; i++) {
|
||||
procDmcs[i] = createProcessContext(Integer.toString(processes[i].getPid()));
|
||||
public void getRunningProcesses(IDMContext dmc, final DataRequestMonitor<IProcessDMContext[]> rm) {
|
||||
if (fCommandControl.getSessionType() == SessionType.LOCAL) {
|
||||
IProcessList list = null;
|
||||
try {
|
||||
list = CCorePlugin.getDefault().getProcessList();
|
||||
} catch (CoreException e) {
|
||||
}
|
||||
|
||||
if (list == null) {
|
||||
// If the list is null, the prompter will deal with it
|
||||
fProcessNames.clear();
|
||||
rm.setData(null);
|
||||
} else {
|
||||
fProcessNames.clear();
|
||||
for (IProcessInfo procInfo : list.getProcessList()) {
|
||||
fProcessNames.put(procInfo.getPid(), procInfo.getName());
|
||||
}
|
||||
rm.setData(makeProcessDMCs(list.getProcessList()));
|
||||
}
|
||||
rm.done();
|
||||
} else {
|
||||
// monitor list processes is only for remote session
|
||||
fCommandControl.queueCommand(
|
||||
new CLIMonitorListProcesses(dmc),
|
||||
new DataRequestMonitor<CLIMonitorListProcessesInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
for (IProcessInfo procInfo : getData().getProcessList()) {
|
||||
fProcessNames.put(procInfo.getPid(), procInfo.getName());
|
||||
}
|
||||
rm.setData(makeProcessDMCs(getData().getProcessList()));
|
||||
} else {
|
||||
// The monitor list command is not supported.
|
||||
// Just return an empty list and let the caller deal with it.
|
||||
fProcessNames.clear();
|
||||
rm.setData(new IProcessDMContext[0]);
|
||||
}
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private IProcessDMContext[] makeProcessDMCs(IProcessInfo[] processes) {
|
||||
IProcessDMContext[] procDmcs = new GdbProcessDMC[processes.length];
|
||||
for (int i=0; i<procDmcs.length; i++) {
|
||||
procDmcs[i] = createProcessContext(Integer.toString(processes[i].getPid()));
|
||||
}
|
||||
return procDmcs;
|
||||
}
|
||||
|
||||
|
||||
public void runNewProcess(String file, DataRequestMonitor<IProcessDMContext> rm) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID,
|
||||
NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 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.dd.mi.service;
|
||||
|
||||
import org.eclipse.cdt.core.IProcessInfo;
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
public class ProcessInfo implements IProcessInfo, Comparable<ProcessInfo> {
|
||||
private final int pid;
|
||||
private final String name;
|
||||
|
||||
public ProcessInfo(String pidString, String name) {
|
||||
int tmpPid = 0;
|
||||
try {
|
||||
tmpPid = Integer.parseInt(pidString);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
this.pid = tmpPid;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ProcessInfo(int pid, String name) {
|
||||
this.pid = pid;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.IProcessInfo#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.IProcessInfo#getPid()
|
||||
*/
|
||||
public int getPid() {
|
||||
return pid;
|
||||
}
|
||||
|
||||
public int compareTo(ProcessInfo other) {
|
||||
int nameCompare = getName().compareTo(other.getName());
|
||||
if (nameCompare != 0) return nameCompare;
|
||||
else return (getPid() < other.getPid()) ? -1 : 1;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue