mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 239050
This patch adds more usage of the IProcesses service. I believe the patch is backwards compatible with our 1.0 release (not with the latest HEAD). The patch does the following: 1- cleanup context hierarchy to become: MIControlDMContext | MIProcessDMC (IProcess) MIExecutionGroupDMC __/ | (IContainer) | | MIThreadDMC (IThread) MIExecutionDMC _____/ (IExecution) Notice how I put MIControlDMContext at the top. The create*DMC methods have been updated accordingly. The constructors of the MI*DMC classes have been updated accordingly. 2- Deprecated GDBRunControl.getThreadData() and GDBRunControl.getProcessData() and have GdbThreadFilterEditor and ThreadVMNode use IProcesses instead. 3- because of (2) I was able to remove IGDBRunControl and GDBRunControlNS completely. 4- Made MIProcesses.getExecutionData() fetch the thread data using CLIInfoThreads as is done (but deprecated) in GDBRunControl.getThreadData() 5- Added a cache and event listeners to MIProcesses to cache CLIInfoThreads. 6- Update MIRunControlEventProcessor and CLIEventProcessor to use MIControlDMContext as their top context instead of IContainerDMContext
This commit is contained in:
parent
2bbc19a848
commit
0db5876d62
16 changed files with 267 additions and 325 deletions
|
@ -24,14 +24,15 @@ import org.eclipse.dd.dsf.concurrent.IDsfStatusConstants;
|
|||
import org.eclipse.dd.dsf.concurrent.ImmediateExecutor;
|
||||
import org.eclipse.dd.dsf.concurrent.Query;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IThreadDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IThreadDMData;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.gdb.internal.provisional.breakpoints.CBreakpointGdbThreadsFilterExtension;
|
||||
import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBThreadData;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
|
||||
import org.eclipse.dd.gdb.internal.ui.GdbUIPlugin;
|
||||
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
|
||||
|
@ -493,12 +494,14 @@ public class GdbThreadFilterEditor {
|
|||
return;
|
||||
}
|
||||
|
||||
ServiceTracker tracker = new ServiceTracker(GdbUIPlugin.getBundleContext(), IGDBRunControl.class
|
||||
ServiceTracker tracker = new ServiceTracker(GdbUIPlugin.getBundleContext(), IProcesses.class
|
||||
.getName(), null);
|
||||
tracker.open();
|
||||
IGDBRunControl runControl = (IGDBRunControl) tracker.getService();
|
||||
if (runControl != null) {
|
||||
runControl.getThreadData((IMIExecutionDMContext) thread, new DataRequestMonitor<IGDBThreadData>(
|
||||
IProcesses procService = (IProcesses) tracker.getService();
|
||||
if (procService != null) {
|
||||
IThreadDMContext threadDmc = DMContexts.getAncestorOfType(thread, IThreadDMContext.class);
|
||||
procService.getExecutionData(threadDmc, new DataRequestMonitor<IThreadDMData>(
|
||||
// Is it ok to use the ImmediateExecutor here?
|
||||
ImmediateExecutor.getInstance(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
|
@ -513,7 +516,7 @@ public class GdbThreadFilterEditor {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
rm.setStatus(getFailStatus(IDsfStatusConstants.INVALID_STATE, "GDB Control not accessible.")); //$NON-NLS-1$
|
||||
rm.setStatus(getFailStatus(IDsfStatusConstants.INVALID_STATE, "IProcesses service not accessible.")); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
tracker.close();
|
||||
|
|
|
@ -13,16 +13,17 @@ package org.eclipse.dd.gdb.internal.ui.viewmodel.launch;
|
|||
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel.launch.AbstractThreadVMNode;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IThreadDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IThreadDMData;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.dsf.ui.concurrent.ViewerDataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
|
||||
import org.eclipse.dd.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBThreadData;
|
||||
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIRunControl;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider;
|
||||
|
@ -49,24 +50,27 @@ public class ThreadVMNode extends AbstractThreadVMNode
|
|||
@Override
|
||||
protected void updateLabelInSessionThread(ILabelUpdate[] updates) {
|
||||
for (final ILabelUpdate update : updates) {
|
||||
final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class);
|
||||
if ( runControl == null ) {
|
||||
final IMIRunControl runControl = getServicesTracker().getService(IMIRunControl.class);
|
||||
if (runControl == null) {
|
||||
handleFailedUpdate(update);
|
||||
continue;
|
||||
}
|
||||
|
||||
final IMIExecutionDMContext dmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IMIExecutionDMContext.class);
|
||||
final IMIExecutionDMContext execDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IMIExecutionDMContext.class);
|
||||
|
||||
String imageKey = null;
|
||||
if (getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) {
|
||||
final boolean threadSuspended;
|
||||
if (runControl.isSuspended(execDmc)) {
|
||||
threadSuspended = true;
|
||||
imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED;
|
||||
} else {
|
||||
threadSuspended = false;
|
||||
imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING;
|
||||
}
|
||||
update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0);
|
||||
|
||||
// Find the Reason for the State
|
||||
runControl.getExecutionData(dmc,
|
||||
runControl.getExecutionData(execDmc,
|
||||
new ViewerDataRequestMonitor<IExecutionDMData>(getSession().getExecutor(), update) {
|
||||
@Override
|
||||
public void handleCompleted(){
|
||||
|
@ -76,10 +80,8 @@ public class ThreadVMNode extends AbstractThreadVMNode
|
|||
return;
|
||||
}
|
||||
|
||||
// We're in a new dispatch cycle, and we have to check whether the
|
||||
// service reference is still valid.
|
||||
final IGDBRunControl runControl = getServicesTracker().getService(IGDBRunControl.class);
|
||||
if ( runControl == null ) {
|
||||
final IProcesses procService = getServicesTracker().getService(IProcesses.class);
|
||||
if ( procService == null ) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
@ -87,9 +89,11 @@ public class ThreadVMNode extends AbstractThreadVMNode
|
|||
final StateChangeReason reason = getData().getStateChangeReason();
|
||||
|
||||
// Retrieve the rest of the thread information
|
||||
runControl.getThreadData(
|
||||
dmc,
|
||||
new ViewerDataRequestMonitor<IGDBThreadData>(getSession().getExecutor(), update) {
|
||||
final IThreadDMContext threadDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IThreadDMContext.class);
|
||||
|
||||
procService.getExecutionData(
|
||||
threadDmc,
|
||||
new ViewerDataRequestMonitor<IThreadDMData>(getSession().getExecutor(), update) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (!isSuccess()) {
|
||||
|
@ -99,11 +103,11 @@ public class ThreadVMNode extends AbstractThreadVMNode
|
|||
// Create Labels of type Thread[GDBthreadId]RealThreadID/Name (State: Reason)
|
||||
// Thread[1] 3457 (Suspended:BREAKPOINT)
|
||||
final StringBuilder builder = new StringBuilder("Thread["); //$NON-NLS-1$
|
||||
builder.append(dmc.getThreadId());
|
||||
builder.append(execDmc.getThreadId());
|
||||
builder.append("] "); //$NON-NLS-1$
|
||||
builder.append(getData().getId());
|
||||
builder.append(getData().getName());
|
||||
if(getServicesTracker().getService(IRunControl.class).isSuspended(dmc))
|
||||
if(threadSuspended)
|
||||
builder.append(" (Suspended"); //$NON-NLS-1$
|
||||
else
|
||||
builder.append(" (Running"); //$NON-NLS-1$
|
||||
|
|
|
@ -393,7 +393,8 @@ public class FinalLaunchSequence extends Sequence {
|
|||
try {
|
||||
Object result = prompter.handleStatus(processPromptStatus, fProcessList);
|
||||
if (result instanceof Integer) {
|
||||
fRequestMonitor.setData(fProcService.createProcessContext(Integer.toString((Integer)result)));
|
||||
fRequestMonitor.setData(fProcService.createProcessContext(fCommandControl.getGDBDMContext(),
|
||||
Integer.toString((Integer)result)));
|
||||
} else {
|
||||
fRequestMonitor.setStatus(NO_PID_STATUS);
|
||||
}
|
||||
|
@ -420,7 +421,7 @@ public class FinalLaunchSequence extends Sequence {
|
|||
|
||||
if (pid != -1) {
|
||||
fProcService.attachDebuggerToProcess(
|
||||
fProcService.createProcessContext(Integer.toString(pid)),
|
||||
fProcService.createProcessContext(fCommandControl.getGDBDMContext(), Integer.toString(pid)),
|
||||
new DataRequestMonitor<IDMContext>(getExecutor(), requestMonitor));
|
||||
} else {
|
||||
fProcService.getRunningProcesses(
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.eclipse.core.runtime.IStatus;
|
|||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
|
@ -29,6 +30,7 @@ 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.MIProcesses;
|
||||
import org.eclipse.dd.mi.service.command.MIControlDMContext;
|
||||
import org.eclipse.dd.mi.service.command.MIInferiorProcess;
|
||||
import org.eclipse.dd.mi.service.command.commands.CLIMonitorListProcesses;
|
||||
import org.eclipse.dd.mi.service.command.output.CLIMonitorListProcessesInfo;
|
||||
|
@ -97,7 +99,7 @@ public class GDBProcesses extends MIProcesses {
|
|||
public void getExecutionData(IThreadDMContext dmc, DataRequestMonitor<IThreadDMData> rm) {
|
||||
// We must first check for GdbProcessDMC because it is also a GdbThreadDMC
|
||||
if (dmc instanceof MIProcessDMC) {
|
||||
String pidStr = ((MIProcessDMC)dmc).getId();
|
||||
String pidStr = ((MIProcessDMC)dmc).getProcId();
|
||||
int pid = -1;
|
||||
try {
|
||||
pid = Integer.parseInt(pidStr);
|
||||
|
@ -126,6 +128,7 @@ public class GDBProcesses extends MIProcesses {
|
|||
|
||||
@Override
|
||||
public void getRunningProcesses(IDMContext dmc, final DataRequestMonitor<IProcessDMContext[]> rm) {
|
||||
final MIControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, MIControlDMContext.class);
|
||||
if (fGdb.getSessionType() == SessionType.LOCAL) {
|
||||
IProcessList list = null;
|
||||
try {
|
||||
|
@ -142,7 +145,7 @@ public class GDBProcesses extends MIProcesses {
|
|||
for (IProcessInfo procInfo : list.getProcessList()) {
|
||||
fProcessNames.put(procInfo.getPid(), procInfo.getName());
|
||||
}
|
||||
rm.setData(makeProcessDMCs(list.getProcessList()));
|
||||
rm.setData(makeProcessDMCs(controlDmc, list.getProcessList()));
|
||||
}
|
||||
rm.done();
|
||||
} else {
|
||||
|
@ -156,7 +159,7 @@ public class GDBProcesses extends MIProcesses {
|
|||
for (IProcessInfo procInfo : getData().getProcessList()) {
|
||||
fProcessNames.put(procInfo.getPid(), procInfo.getName());
|
||||
}
|
||||
rm.setData(makeProcessDMCs(getData().getProcessList()));
|
||||
rm.setData(makeProcessDMCs(controlDmc, getData().getProcessList()));
|
||||
} else {
|
||||
// The monitor list command is not supported.
|
||||
// Just return an empty list and let the caller deal with it.
|
||||
|
@ -170,10 +173,10 @@ public class GDBProcesses extends MIProcesses {
|
|||
}
|
||||
}
|
||||
|
||||
private IProcessDMContext[] makeProcessDMCs(IProcessInfo[] processes) {
|
||||
private IProcessDMContext[] makeProcessDMCs(MIControlDMContext controlDmc, IProcessInfo[] processes) {
|
||||
IProcessDMContext[] procDmcs = new MIProcessDMC[processes.length];
|
||||
for (int i=0; i<procDmcs.length; i++) {
|
||||
procDmcs[i] = createProcessContext(Integer.toString(processes[i].getPid()));
|
||||
procDmcs[i] = createProcessContext(controlDmc, Integer.toString(processes[i].getPid()));
|
||||
}
|
||||
return procDmcs;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
|||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
|
||||
|
@ -36,14 +37,14 @@ import org.eclipse.dd.mi.service.command.events.MIEvent;
|
|||
import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent;
|
||||
import org.eclipse.dd.mi.service.command.output.CLIInfoThreadsInfo;
|
||||
|
||||
public class GDBRunControl extends MIRunControl implements IGDBRunControl {
|
||||
public class GDBRunControl extends MIRunControl {
|
||||
|
||||
/**
|
||||
* Implement a custom execution data for threads in order to provide additional
|
||||
* information. This object can be made separate from IExecutionDMData after
|
||||
* the deprecated method: IDMService.getModelData() is no longer used.
|
||||
*/
|
||||
public static class GDBThreadData implements IGDBThreadData {
|
||||
public static class GDBThreadData {
|
||||
private final String fId;
|
||||
private final String fName;
|
||||
|
||||
|
@ -65,7 +66,7 @@ public class GDBRunControl extends MIRunControl implements IGDBRunControl {
|
|||
* information. This object can be made separate from IExecutionDMData after
|
||||
* the deprecated method: IDMService.getModelData() is no longer used.
|
||||
*/
|
||||
public static class GDBProcessData implements IGDBProcessData {
|
||||
public static class GDBProcessData {
|
||||
private final String fName;
|
||||
|
||||
GDBProcessData(String name) {
|
||||
|
@ -102,7 +103,7 @@ public class GDBRunControl extends MIRunControl implements IGDBRunControl {
|
|||
fGdb = getServicesTracker().getService(GDBControl.class);
|
||||
register(new String[]{IRunControl.class.getName(),
|
||||
IMIRunControl.class.getName(), MIRunControl.class.getName(),
|
||||
IGDBRunControl.class.getName(), GDBRunControl.class.getName()}, new Hashtable<String,String>());
|
||||
GDBRunControl.class.getName()}, new Hashtable<String,String>());
|
||||
requestMonitor.done();
|
||||
}
|
||||
|
||||
|
@ -152,15 +153,16 @@ public class GDBRunControl extends MIRunControl implements IGDBRunControl {
|
|||
super.getExecutionContexts(c, rm1);
|
||||
}
|
||||
|
||||
public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<IGDBProcessData> rm) {
|
||||
@Deprecated
|
||||
public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<GDBProcessData> rm) {
|
||||
rm.setData( new GDBProcessData(fGdb.getExecutablePath().lastSegment()) );
|
||||
rm.done();
|
||||
}
|
||||
|
||||
public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<IGDBThreadData> rm) {
|
||||
IContainerDMContext containerDmc = DMContexts.getAncestorOfType(execDmc, IContainerDMContext.class);
|
||||
assert containerDmc != null; // Every exec context should have a container as an ancestor.
|
||||
getCache().execute(new CLIInfoThreads(containerDmc),
|
||||
@Deprecated
|
||||
public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<GDBThreadData> rm) {
|
||||
IProcessDMContext prodDmc = DMContexts.getAncestorOfType(execDmc, IProcessDMContext.class);
|
||||
getCache().execute(new CLIInfoThreads(prodDmc),
|
||||
new DataRequestMonitor<CLIInfoThreadsInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
|
|
|
@ -1,129 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2008 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
|
||||
* Ericsson AB - Modified for additional functionality
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.dd.gdb.internal.provisional.service;
|
||||
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIRunControl;
|
||||
import org.eclipse.dd.mi.service.MIRunControlNS;
|
||||
import org.eclipse.dd.mi.service.command.commands.MIThreadInfo;
|
||||
import org.eclipse.dd.mi.service.command.output.MIThreadInfoInfo;
|
||||
|
||||
public class GDBRunControlNS extends MIRunControlNS implements IGDBRunControl
|
||||
{
|
||||
/**
|
||||
* Implement a custom execution data for threads in order to provide additional
|
||||
* information. This object can be made separate from IExecutionDMData after
|
||||
* the deprecated method: IDMService.getModelData() is no longer used.
|
||||
*/
|
||||
private static class GDBThreadData implements IGDBThreadData {
|
||||
private final String fId;
|
||||
private final String fName;
|
||||
|
||||
GDBThreadData(String id, String name) {
|
||||
fId = id;
|
||||
fName = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return fName;
|
||||
}
|
||||
public String getId() { return fId; }
|
||||
|
||||
public boolean isDebuggerAttached() { return true; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement a custom execution data the process in order to provide additional
|
||||
* information. This object can be made separate from IExecutionDMData after
|
||||
* the deprecated method: IDMService.getModelData() is no longer used.
|
||||
*/
|
||||
private static class GDBProcessData implements IGDBProcessData {
|
||||
private final String fName;
|
||||
|
||||
GDBProcessData(String name) {
|
||||
fName = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return fName;
|
||||
}
|
||||
}
|
||||
|
||||
private GDBControl fGdb;
|
||||
|
||||
public GDBRunControlNS(DsfSession session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(final RequestMonitor requestMonitor) {
|
||||
super.initialize(
|
||||
new RequestMonitor(getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
public void handleSuccess() {
|
||||
doInitialize(requestMonitor);
|
||||
}});
|
||||
}
|
||||
|
||||
private void doInitialize(final RequestMonitor requestMonitor) {
|
||||
|
||||
fGdb = getServicesTracker().getService(GDBControl.class);
|
||||
register(new String[]{IRunControl.class.getName(), IMIRunControl.class.getName(), IGDBRunControl.class.getName()}, new Hashtable<String,String>());
|
||||
|
||||
requestMonitor.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown(final RequestMonitor requestMonitor) {
|
||||
unregister();
|
||||
super.shutdown(requestMonitor);
|
||||
}
|
||||
|
||||
public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<IGDBProcessData> rm) {
|
||||
rm.setData( new GDBProcessData(fGdb.getExecutablePath().lastSegment()) );
|
||||
rm.done();
|
||||
}
|
||||
|
||||
public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<IGDBThreadData> rm) {
|
||||
IContainerDMContext containerDmc = DMContexts.getAncestorOfType(execDmc, IContainerDMContext.class);
|
||||
getCache().execute(new MIThreadInfo(containerDmc, execDmc.getThreadId()),
|
||||
new DataRequestMonitor<MIThreadInfoInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(createThreadInfo(execDmc, getData()));
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private GDBThreadData createThreadInfo(IMIExecutionDMContext dmc, MIThreadInfoInfo info) {
|
||||
// There should be only 1 thread in the result, but just in case...
|
||||
for (MIThreadInfoInfo.ThreadInfo thread : info.getThreadInfoList()) {
|
||||
if (Integer.parseInt(thread.getGdbId()) == dmc.getThreadId()){
|
||||
return new GDBThreadData(thread.getOsId(), ""); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
return new GDBThreadData("", ""); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
}
|
|
@ -13,6 +13,7 @@ package org.eclipse.dd.gdb.internal.provisional.service;
|
|||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.mi.service.MIRunControlNS;
|
||||
import org.eclipse.dd.mi.service.MIStackNS;
|
||||
|
||||
public class GdbDebugServicesFactoryNS extends GdbDebugServicesFactory {
|
||||
|
@ -28,6 +29,6 @@ public class GdbDebugServicesFactoryNS extends GdbDebugServicesFactory {
|
|||
|
||||
@Override
|
||||
protected IRunControl createRunControlService(DsfSession session) {
|
||||
return new GDBRunControlNS(session);
|
||||
return new MIRunControlNS(session);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2008 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
|
||||
* Ericsson - Modified for additional functionality
|
||||
*******************************************************************************/
|
||||
package org.eclipse.dd.gdb.internal.provisional.service;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControlDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIRunControl;
|
||||
|
||||
/**
|
||||
* This interface provides access to controlling and monitoring the execution
|
||||
* state of a process being debugged. This interface does not actually
|
||||
* provide methods for creating or destroying execution contexts, it doesn't
|
||||
* even have methods for getting labels. That's because it is expected that
|
||||
* higher level services, ones that deal with processes, kernels, or target
|
||||
* features will provide that functionality.
|
||||
*/
|
||||
public interface IGDBRunControl extends IMIRunControl
|
||||
{
|
||||
public interface IGDBThreadData {
|
||||
public String getName();
|
||||
public String getId();
|
||||
public boolean isDebuggerAttached();
|
||||
}
|
||||
|
||||
public interface IGDBProcessData {
|
||||
public String getName();
|
||||
}
|
||||
|
||||
public void getProcessData(GDBControlDMContext gdbDmc, DataRequestMonitor<IGDBProcessData> rm);
|
||||
public void getThreadData(final IMIExecutionDMContext execDmc, final DataRequestMonitor<IGDBThreadData> dataRequestMonitor);
|
||||
}
|
|
@ -20,17 +20,40 @@ import org.eclipse.dd.dsf.datamodel.DMContexts;
|
|||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.command.ICommandControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason;
|
||||
import org.eclipse.dd.dsf.debug.service.command.CommandCache;
|
||||
import org.eclipse.dd.dsf.service.AbstractDsfService;
|
||||
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.mi.internal.MIPlugin;
|
||||
import org.eclipse.dd.mi.service.command.AbstractMIControl;
|
||||
import org.eclipse.dd.mi.service.command.MIControlDMContext;
|
||||
import org.eclipse.dd.mi.service.command.commands.CLIAttach;
|
||||
import org.eclipse.dd.mi.service.command.commands.CLIInfoThreads;
|
||||
import org.eclipse.dd.mi.service.command.output.CLIInfoThreadsInfo;
|
||||
import org.eclipse.dd.mi.service.command.output.MIInfo;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
|
||||
public class MIProcesses extends AbstractDsfService implements IProcesses {
|
||||
/*
|
||||
|
||||
// Below is the context hierarchy that is implemented between the
|
||||
// MIProcesses service and the MIRunControl service for the MI
|
||||
// implementation of DSF:
|
||||
//
|
||||
// MIControlDMContext
|
||||
// |
|
||||
// MIProcessDMC (IProcess)
|
||||
// MIExecutionGroupDMC __/ |
|
||||
// (IContainer) |
|
||||
// | MIThreadDMC (IThread)
|
||||
// MIExecutionDMC _____/
|
||||
// (IExecution)
|
||||
//
|
||||
|
||||
/**
|
||||
* Context representing a thread group of GDB/MI.
|
||||
*/
|
||||
@Immutable
|
||||
|
@ -48,16 +71,11 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
* to create instances of this context based on the group name.
|
||||
*
|
||||
* @param sessionId Session that this context belongs to.
|
||||
* @param containerDmc The container that this context belongs to.
|
||||
* @param processDmc The process dmc that also is the parent of this context.
|
||||
* @param processDmc The process context that is the parent of this context.
|
||||
* @param groupId GDB/MI thread group identifier.
|
||||
*/
|
||||
protected MIExecutionGroupDMC(String sessionId, IContainerDMContext containerDmc,
|
||||
IProcessDMContext processDmc, String groupId) {
|
||||
super(sessionId, containerDmc == null && processDmc == null ? new IDMContext[0] :
|
||||
containerDmc == null ? new IDMContext[] { processDmc } :
|
||||
processDmc == null ? new IDMContext[] { containerDmc } :
|
||||
new IDMContext[] { processDmc, containerDmc });
|
||||
protected MIExecutionGroupDMC(String sessionId, IProcessDMContext processDmc, String groupId) {
|
||||
super(sessionId, processDmc == null ? new IDMContext[0] : new IDMContext[] { processDmc });
|
||||
fId = groupId;
|
||||
}
|
||||
|
||||
|
@ -71,21 +89,25 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return super.baseEquals(obj) && ((MIExecutionGroupDMC)obj).fId.equals(fId);
|
||||
return super.baseEquals(obj) &&
|
||||
(((MIExecutionGroupDMC)obj).fId == null ? fId == null : ((MIExecutionGroupDMC)obj).fId.equals(fId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() { return super.baseHashCode() + fId.hashCode(); }
|
||||
public int hashCode() { return super.baseHashCode() ^ (fId == null ? 0 : fId.hashCode()); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Context representing a thread.
|
||||
*/
|
||||
@Immutable
|
||||
protected class MIThreadDMC extends AbstractDMContext
|
||||
implements IThreadDMContext
|
||||
{
|
||||
/**
|
||||
* ID given by the OS.
|
||||
* ID used by GDB to refer to threads.
|
||||
*/
|
||||
private final String fOSId;
|
||||
private final String fId;
|
||||
|
||||
/**
|
||||
* Constructor for the context. It should not be called directly by clients.
|
||||
|
@ -98,32 +120,38 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
* @param id thread identifier.
|
||||
*/
|
||||
protected MIThreadDMC(String sessionId, IProcessDMContext processDmc, String id) {
|
||||
super(sessionId, processDmc != null ? new IDMContext[] { processDmc } : new IDMContext[0]);
|
||||
fOSId = id;
|
||||
super(sessionId, processDmc == null ? new IDMContext[0] : new IDMContext[] { processDmc });
|
||||
fId = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the thread identifier of this context.
|
||||
* @return
|
||||
*/
|
||||
public String getId(){ return fOSId; }
|
||||
public String getId(){ return fId; }
|
||||
|
||||
@Override
|
||||
public String toString() { return baseToString() + ".OSthread[" + fOSId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$
|
||||
public String toString() { return baseToString() + ".OSthread[" + fId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return super.baseEquals(obj) && ((MIThreadDMC)obj).fOSId.equals(fOSId);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return super.baseEquals(obj) &&
|
||||
(((MIThreadDMC)obj).fId == null ? fId == null : ((MIThreadDMC)obj).fId.equals(fId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() { return super.baseHashCode() ^ (fOSId == null ? 0 : fOSId.hashCode()); }
|
||||
@Override
|
||||
public int hashCode() { return super.baseHashCode() ^ (fId == null ? 0 : fId.hashCode()); }
|
||||
}
|
||||
|
||||
@Immutable
|
||||
protected class MIProcessDMC extends MIThreadDMC
|
||||
protected class MIProcessDMC extends AbstractDMContext
|
||||
implements IMIProcessDMContext
|
||||
{
|
||||
/**
|
||||
* ID given by the OS.
|
||||
*/
|
||||
private final String fId;
|
||||
|
||||
/**
|
||||
* Constructor for the context. It should not be called directly by clients.
|
||||
* Instead clients should call {@link MIProcesses#createProcessContext}
|
||||
|
@ -131,24 +159,27 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
* <p/>
|
||||
*
|
||||
* @param sessionId Session that this context belongs to.
|
||||
* @param controlDmc The control context parent of this process.
|
||||
* @param id process identifier.
|
||||
*/
|
||||
protected MIProcessDMC(String sessionId, String id) {
|
||||
super(sessionId, null, id);
|
||||
protected MIProcessDMC(String sessionId, MIControlDMContext controlDmc, String id) {
|
||||
super(sessionId, controlDmc == null ? new IDMContext[0] : new IDMContext[] { controlDmc });
|
||||
fId = id;
|
||||
}
|
||||
|
||||
public String getProcId() { return getId(); }
|
||||
public String getProcId() { return fId; }
|
||||
|
||||
@Override
|
||||
public String toString() { return baseToString() + ".proc[" + getId() + "]"; } //$NON-NLS-1$ //$NON-NLS-2$
|
||||
public String toString() { return baseToString() + ".proc[" + fId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return super.baseEquals(obj) &&
|
||||
(((MIProcessDMC)obj).fId == null ? fId == null : ((MIProcessDMC)obj).fId.equals(fId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() { return super.hashCode(); }
|
||||
@Override
|
||||
public int hashCode() { return super.baseHashCode() ^ (fId == null ? 0 : fId.hashCode()); }
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -171,7 +202,8 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
}
|
||||
}
|
||||
|
||||
private ICommandControl fCommandControl;
|
||||
private AbstractMIControl fCommandControl;
|
||||
private CommandCache fCommandCache;
|
||||
|
||||
public MIProcesses(DsfSession session) {
|
||||
super(session);
|
||||
|
@ -208,7 +240,10 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
// MIProcesses.class.getName() },
|
||||
// new Hashtable<String, String>());
|
||||
|
||||
fCommandControl = getServicesTracker().getService(ICommandControl.class);
|
||||
fCommandControl = getServicesTracker().getService(AbstractMIControl.class);
|
||||
fCommandCache = new CommandCache(getSession(), fCommandControl);
|
||||
fCommandCache.setContextAvailable(fCommandControl.getControlDMContext(), true);
|
||||
getSession().addServiceEventListener(this, null);
|
||||
|
||||
requestMonitor.done();
|
||||
}
|
||||
|
@ -223,6 +258,7 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
@Override
|
||||
public void shutdown(RequestMonitor requestMonitor) {
|
||||
// unregister();
|
||||
getSession().removeServiceEventListener(this);
|
||||
super.shutdown(requestMonitor);
|
||||
}
|
||||
|
||||
|
@ -249,29 +285,23 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
*
|
||||
* @param pid The OS Id of the process
|
||||
*/
|
||||
public IProcessDMContext createProcessContext(String pid) {
|
||||
return new MIProcessDMC(getSession().getId(), pid);
|
||||
public IProcessDMContext createProcessContext(MIControlDMContext controlDmc, String pid) {
|
||||
return new MIProcessDMC(getSession().getId(), controlDmc, pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a executionGroup context.
|
||||
*
|
||||
* @param containerDmc The parent container context of this context
|
||||
* @param processDmc The parent process context of this context
|
||||
* @param groupId The thread group id of the process
|
||||
*/
|
||||
public IMIExecutionGroupDMContext createExecutionGroupContext(IContainerDMContext containerDmc,
|
||||
IProcessDMContext processDmc,
|
||||
public IMIExecutionGroupDMContext createExecutionGroupContext(IProcessDMContext processDmc,
|
||||
String groupId) {
|
||||
return new MIExecutionGroupDMC(getSession().getId(), containerDmc, processDmc, groupId);
|
||||
}
|
||||
|
||||
public IMIExecutionGroupDMContext createExecutionGroupContext(IContainerDMContext containerDmc, String groupId) {
|
||||
return createExecutionGroupContext(containerDmc, createProcessContext(""), groupId); //$NON-NLS-1$
|
||||
return new MIExecutionGroupDMC(getSession().getId(), processDmc, groupId);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method obtains the model data for a given GdbThreadDMC object
|
||||
* This method obtains the model data for a given IThreadDMContext object
|
||||
* which can represent a thread or a process.
|
||||
*
|
||||
* @param dmc
|
||||
|
@ -285,23 +315,37 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
getExecutionData((IThreadDMContext) dmc,
|
||||
(DataRequestMonitor<IThreadDMData>) rm);
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
|
||||
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void getExecutionData(IThreadDMContext dmc, DataRequestMonitor<IThreadDMData> rm) {
|
||||
// We must first do the if check for MIProcessDMC because it is also a GMIThreadDMC
|
||||
public void getExecutionData(IThreadDMContext dmc, final DataRequestMonitor<IThreadDMData> rm) {
|
||||
if (dmc instanceof MIProcessDMC) {
|
||||
rm.setData(new MIThreadDMData("", ((MIProcessDMC)dmc).getId())); //$NON-NLS-1$
|
||||
rm.setData(new MIThreadDMData("", ((MIProcessDMC)dmc).getProcId())); //$NON-NLS-1$
|
||||
rm.done();
|
||||
} else if (dmc instanceof MIThreadDMC) {
|
||||
rm.setData(new MIThreadDMData("", ((MIThreadDMC)dmc).getId())); //$NON-NLS-1$
|
||||
rm.done();
|
||||
final MIThreadDMC threadDmc = (MIThreadDMC)dmc;
|
||||
|
||||
IProcessDMContext procDmc = DMContexts.getAncestorOfType(dmc, IProcessDMContext.class);
|
||||
fCommandCache.execute(new CLIInfoThreads(procDmc),
|
||||
new DataRequestMonitor<CLIInfoThreadsInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
IThreadDMData threadData = new MIThreadDMData("", ""); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
for (CLIInfoThreadsInfo.ThreadInfo thread : getData().getThreadInfo()) {
|
||||
if (thread.getId().equals(threadDmc.getId())) {
|
||||
threadData = new MIThreadDMData(thread.getName(), thread.getOsId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
rm.setData(threadData);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Unknown DMC type", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,8 +362,9 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
|
||||
public void attachDebuggerToProcess(IProcessDMContext procCtx, final DataRequestMonitor<IDMContext> rm) {
|
||||
if (procCtx instanceof IMIProcessDMContext) {
|
||||
MIControlDMContext controlDmc = DMContexts.getAncestorOfType(procCtx, MIControlDMContext.class);
|
||||
fCommandControl.queueCommand(
|
||||
new CLIAttach((IMIProcessDMContext)procCtx),
|
||||
new CLIAttach(controlDmc, ((IMIProcessDMContext)procCtx).getProcId()),
|
||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
|
@ -382,11 +427,10 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
|
||||
public void getProcessesBeingDebugged(IDMContext dmc, DataRequestMonitor<IDMContext[]> rm) {
|
||||
// This service version only handles a single process to debug, therefore, we can simply
|
||||
// create the context describing this process ourselves. This context's content is not
|
||||
// used since it is the only context of its kind (only one process to debug) and can be recognized that way.
|
||||
IContainerDMContext parentDmc = DMContexts.getAncestorOfType(dmc, IContainerDMContext.class);
|
||||
IContainerDMContext containerDmc = createExecutionGroupContext(parentDmc, createProcessContext(""), "");//$NON-NLS-1$//$NON-NLS-2$
|
||||
rm.setData(new IContainerDMContext[] {containerDmc});
|
||||
// create the context describing this process ourselves.
|
||||
MIControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, MIControlDMContext.class);
|
||||
IMIExecutionGroupDMContext groupDmc = createExecutionGroupContext(createProcessContext(controlDmc, ""), "");//$NON-NLS-1$//$NON-NLS-2$
|
||||
rm.setData(new IContainerDMContext[] {groupDmc});
|
||||
rm.done();
|
||||
}
|
||||
|
||||
|
@ -400,7 +444,6 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
rm.setData(false);
|
||||
rm.done();
|
||||
}
|
||||
|
||||
public void runNewProcess(String file, DataRequestMonitor<IProcessDMContext> rm) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID,
|
||||
NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$
|
||||
|
@ -412,4 +455,20 @@ public class MIProcesses extends AbstractDsfService implements IProcesses {
|
|||
NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(IResumedDMEvent e) {
|
||||
fCommandCache.setContextAvailable(e.getDMContext(), false);
|
||||
fCommandCache.setContextAvailable(fCommandControl.getControlDMContext(), true);
|
||||
if (e.getReason() != StateChangeReason.STEP) {
|
||||
fCommandCache.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(ISuspendedDMEvent e) {
|
||||
fCommandCache.setContextAvailable(e.getDMContext(), true);
|
||||
fCommandCache.reset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
|
|||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IThreadDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.command.CommandCache;
|
||||
import org.eclipse.dd.dsf.service.AbstractDsfService;
|
||||
|
@ -72,7 +74,7 @@ import org.osgi.framework.BundleContext;
|
|||
*/
|
||||
public class MIRunControl extends AbstractDsfService implements IMIRunControl
|
||||
{
|
||||
class MIExecutionDMC extends AbstractDMContext implements IMIExecutionDMContext
|
||||
protected class MIExecutionDMC extends AbstractDMContext implements IMIExecutionDMContext
|
||||
{
|
||||
/**
|
||||
* Integer ID that is used to identify the thread in the GDB/MI protocol.
|
||||
|
@ -89,10 +91,26 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl
|
|||
*
|
||||
* @param sessionId Session that this context belongs to.
|
||||
* @param containerDmc The container that this context belongs to.
|
||||
* @param threadDmc The thread context parents of this context.
|
||||
* @param threadId GDB/MI thread identifier.
|
||||
*/
|
||||
protected MIExecutionDMC(String sessionId, IContainerDMContext containerDmc, IThreadDMContext threadDmc, int threadId) {
|
||||
super(sessionId,
|
||||
containerDmc == null && threadDmc == null ? new IDMContext[0] :
|
||||
containerDmc == null ? new IDMContext[] { threadDmc } :
|
||||
threadDmc == null ? new IDMContext[] { containerDmc } :
|
||||
new IDMContext[] { containerDmc, threadDmc });
|
||||
fThreadId = threadId;
|
||||
}
|
||||
|
||||
protected MIExecutionDMC(String sessionId, IContainerDMContext containerDmc, int threadId) {
|
||||
super(sessionId, containerDmc != null ? new IDMContext[] { containerDmc } : new IDMContext[0]);
|
||||
super(sessionId,
|
||||
containerDmc == null ? new IDMContext[0]
|
||||
: new IDMContext[] { containerDmc,
|
||||
fProcService.createThreadContext(DMContexts.getAncestorOfType(containerDmc,
|
||||
IProcessDMContext.class),
|
||||
Integer.toString(threadId)) });
|
||||
|
||||
fThreadId = threadId;
|
||||
}
|
||||
|
||||
|
@ -274,6 +292,7 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl
|
|||
|
||||
private AbstractMIControl fConnection;
|
||||
private CommandCache fMICommandCache;
|
||||
private MIProcesses fProcService;
|
||||
|
||||
// State flags
|
||||
private boolean fSuspended = true;
|
||||
|
@ -304,6 +323,7 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl
|
|||
fConnection = getServicesTracker().getService(AbstractMIControl.class);
|
||||
fMICommandCache = new CommandCache(getSession(), fConnection);
|
||||
fMICommandCache.setContextAvailable(fConnection.getControlDMContext(), true);
|
||||
fProcService = getServicesTracker().getService(MIProcesses.class);
|
||||
getSession().addServiceEventListener(this, null);
|
||||
rm.done();
|
||||
}
|
||||
|
@ -330,7 +350,16 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl
|
|||
public CommandCache getCache() { return fMICommandCache; }
|
||||
|
||||
public IMIExecutionDMContext createMIExecutionContext(IContainerDMContext container, int threadId) {
|
||||
return new MIExecutionDMC(getSession().getId(), container, threadId);
|
||||
MIProcesses procService = getServicesTracker().getService(MIProcesses.class);
|
||||
IProcessDMContext procDmc = DMContexts.getAncestorOfType(container, IProcessDMContext.class);
|
||||
|
||||
IThreadDMContext threadDmc = null;
|
||||
if (procService != null && procDmc != null) {
|
||||
// For now, reuse the threadId as the OSThreadId
|
||||
threadDmc = procService.createThreadContext(procDmc, Integer.toString(threadId));
|
||||
}
|
||||
|
||||
return new MIExecutionDMC(getSession().getId(), container, threadDmc, threadId);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -376,7 +405,7 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl
|
|||
@DsfServiceEventHandler
|
||||
public void eventDispatched(final MIThreadCreatedEvent e) {
|
||||
IContainerDMContext containerDmc = e.getDMContext();
|
||||
IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null;
|
||||
IMIExecutionDMContext executionCtx = e.getId() != -1 ? createMIExecutionContext(containerDmc, e.getId()) : null;
|
||||
getSession().dispatchEvent(new StartedDMEvent(executionCtx, e), getProperties());
|
||||
}
|
||||
|
||||
|
@ -387,7 +416,7 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl
|
|||
@DsfServiceEventHandler
|
||||
public void eventDispatched(final MIThreadExitEvent e) {
|
||||
IContainerDMContext containerDmc = e.getDMContext();
|
||||
IMIExecutionDMContext executionCtx = e.getId() != -1 ? new MIExecutionDMC(getSession().getId(), containerDmc, e.getId()) : null;
|
||||
IMIExecutionDMContext executionCtx = e.getId() != -1 ? createMIExecutionContext(containerDmc, e.getId()) : null;
|
||||
getSession().dispatchEvent(new ExitedDMEvent(executionCtx, e), getProperties());
|
||||
}
|
||||
|
||||
|
@ -628,11 +657,11 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl
|
|||
if (info.getThreadIds().length == 0) {
|
||||
//Main thread always exist even if it is not reported by GDB.
|
||||
//So create thread-id= 0 when no thread is reported
|
||||
return new IMIExecutionDMContext[]{new MIExecutionDMC(getSession().getId(), containerCtx, DEFAULT_THREAD_ID)};
|
||||
return new IMIExecutionDMContext[]{createMIExecutionContext(containerCtx, DEFAULT_THREAD_ID)};
|
||||
} else {
|
||||
IExecutionDMContext[] executionDmcs = new IMIExecutionDMContext[info.getThreadIds().length];
|
||||
for (int i = 0; i < info.getThreadIds().length; i++) {
|
||||
executionDmcs[i] = new MIExecutionDMC(getSession().getId(), containerCtx, info.getThreadIds()[i]);
|
||||
executionDmcs[i] = createMIExecutionContext(containerCtx, info.getThreadIds()[i]);
|
||||
}
|
||||
return executionDmcs;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
package org.eclipse.dd.mi.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
|
@ -25,6 +26,7 @@ import org.eclipse.dd.dsf.datamodel.AbstractDMEvent;
|
|||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.command.CommandCache;
|
||||
import org.eclipse.dd.dsf.service.AbstractDsfService;
|
||||
|
@ -319,6 +321,7 @@ public class MIRunControlNS extends AbstractDsfService implements IMIRunControl
|
|||
}
|
||||
|
||||
private void doInitialize(final RequestMonitor rm) {
|
||||
register(new String[]{IRunControl.class.getName(), IMIRunControl.class.getName()}, new Hashtable<String,String>());
|
||||
fConnection = getServicesTracker().getService(AbstractMIControl.class);
|
||||
fMICommandCache = new CommandCache(getSession(), fConnection);
|
||||
fMICommandCache.setContextAvailable(fConnection.getControlDMContext(), true);
|
||||
|
@ -328,6 +331,7 @@ public class MIRunControlNS extends AbstractDsfService implements IMIRunControl
|
|||
|
||||
@Override
|
||||
public void shutdown(final RequestMonitor rm) {
|
||||
unregister();
|
||||
getSession().removeServiceEventListener(this);
|
||||
fMICommandCache.reset();
|
||||
super.shutdown(rm);
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
|
|||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.ISignals.ISignalsDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.command.ICommandListener;
|
||||
|
@ -54,7 +55,7 @@ public class CLIEventProcessor
|
|||
{
|
||||
private final AbstractMIControl fCommandControl;
|
||||
private MIInferiorProcess fInferior;
|
||||
private final IContainerDMContext fContainerDmc;
|
||||
private final MIControlDMContext fControlDmc;
|
||||
private final List<Object> fEventList = new LinkedList<Object>();
|
||||
|
||||
// Last Thread ID created
|
||||
|
@ -65,7 +66,7 @@ public class CLIEventProcessor
|
|||
public CLIEventProcessor(AbstractMIControl connection, IContainerDMContext containerDmc, MIInferiorProcess inferior) {
|
||||
fCommandControl = connection;
|
||||
fInferior = inferior;
|
||||
fContainerDmc = containerDmc;
|
||||
fControlDmc = DMContexts.getAncestorOfType(containerDmc, MIControlDMContext.class);
|
||||
fServicesTracker = new DsfServicesTracker(MIPlugin.getBundleContext(), fCommandControl.getSession().getId());
|
||||
connection.addCommandListener(this);
|
||||
connection.addEventListener(this);
|
||||
|
@ -123,7 +124,8 @@ public class CLIEventProcessor
|
|||
Matcher matcher = pattern.matcher(exec.getCString());
|
||||
if (matcher.find()) {
|
||||
MIProcesses procService = fServicesTracker.getService(MIProcesses.class);
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, ""); //$NON-NLS-1$
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, ""); //$NON-NLS-1$
|
||||
MIEvent<?> e = new MIThreadCreatedEvent(processContainerDmc, ++fLastThreadId);
|
||||
fCommandControl.getSession().dispatchEvent(e, fCommandControl.getProperties());
|
||||
}
|
||||
|
@ -145,7 +147,8 @@ public class CLIEventProcessor
|
|||
if (fInferior.getState() == MIInferiorProcess.State.RUNNING) {
|
||||
fInferior.setState(MIInferiorProcess.State.STOPPED);
|
||||
MIProcesses procService = fServicesTracker.getService(MIProcesses.class);
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, ""); //$NON-NLS-1$
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, ""); //$NON-NLS-1$
|
||||
fCommandControl.getSession().dispatchEvent(
|
||||
MIErrorEvent.parse(processContainerDmc, rr.getToken(), rr.getMIResults(), null),
|
||||
fCommandControl.getProperties());
|
||||
|
@ -157,7 +160,7 @@ public class CLIEventProcessor
|
|||
|
||||
private void processStateChanges(CLICommand<? extends ICommandResult> cmd) {
|
||||
String operation = cmd.getOperation().trim();
|
||||
// In refactoring we are no longer genwerating the token id as
|
||||
// In refactoring we are no longer generating the token id as
|
||||
// part of the command. It is passed here and stored away and
|
||||
// then never really used. So it has just been changed to 0.
|
||||
processStateChanges(0, operation);
|
||||
|
@ -166,7 +169,7 @@ public class CLIEventProcessor
|
|||
private void processStateChanges(MIInterpreterExecConsole<? extends ICommandResult> exec) {
|
||||
String[] operations = exec.getParameters();
|
||||
if (operations != null && operations.length > 0) {
|
||||
// In refactoring we are no longer genwerating the token id as
|
||||
// In refactoring we are no longer generating the token id as
|
||||
// part of the command. It is passed here and stored away and
|
||||
// then never really used. So it has just been changed to 0.
|
||||
processStateChanges(0, operations[0]);
|
||||
|
@ -188,7 +191,8 @@ public class CLIEventProcessor
|
|||
if (type != -1) {
|
||||
// if it was a step instruction set state running
|
||||
MIProcesses procService = fServicesTracker.getService(MIProcesses.class);
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, ""); //$NON-NLS-1$
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, ""); //$NON-NLS-1$
|
||||
MIEvent<?> event = new MIRunningEvent(processContainerDmc, token, type);
|
||||
fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ package org.eclipse.dd.mi.service.command;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.command.ICommand;
|
||||
|
@ -77,7 +79,7 @@ public class MIRunControlEventProcessor
|
|||
* Container context used as the context for the run control events generated
|
||||
* by this processor.
|
||||
*/
|
||||
private final IContainerDMContext fContainerDmc;
|
||||
private final MIControlDMContext fControlDmc;
|
||||
|
||||
private final DsfServicesTracker fServicesTracker;
|
||||
|
||||
|
@ -89,7 +91,7 @@ public class MIRunControlEventProcessor
|
|||
*/
|
||||
public MIRunControlEventProcessor(AbstractMIControl connection, IContainerDMContext containerDmc) {
|
||||
fCommandControl = connection;
|
||||
fContainerDmc = containerDmc;
|
||||
fControlDmc = DMContexts.getAncestorOfType(containerDmc, MIControlDMContext.class);
|
||||
fServicesTracker = new DsfServicesTracker(MIPlugin.getBundleContext(), fCommandControl.getSession().getId());
|
||||
connection.addEventListener(this);
|
||||
connection.addCommandListener(this);
|
||||
|
@ -171,10 +173,8 @@ public class MIRunControlEventProcessor
|
|||
}
|
||||
|
||||
MIProcesses procService = fServicesTracker.getService(MIProcesses.class);
|
||||
IContainerDMContext processContainerDmc = fContainerDmc;
|
||||
if (procService != null && groupId != null) {
|
||||
processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, groupId);
|
||||
}
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, groupId);
|
||||
|
||||
MIEvent<?> event = null;
|
||||
if ("thread-created".equals(miEvent)) { //$NON-NLS-1$
|
||||
|
@ -216,20 +216,18 @@ public class MIRunControlEventProcessor
|
|||
IMIRunControl runControl = fServicesTracker.getService(IMIRunControl.class);
|
||||
MIProcesses procService = fServicesTracker.getService(MIProcesses.class);
|
||||
|
||||
IExecutionDMContext execDmc = fContainerDmc;
|
||||
if (procService != null && groupId != null) {
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, groupId);
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, groupId);
|
||||
|
||||
execDmc = processContainerDmc;
|
||||
if (runControl != null && threadId != null) {
|
||||
int threadIdInt = -1;
|
||||
try {
|
||||
threadIdInt = Integer.parseInt(threadId);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
if (threadIdInt != -1) {
|
||||
execDmc = runControl.createMIExecutionContext(processContainerDmc, threadIdInt);
|
||||
}
|
||||
IExecutionDMContext execDmc = processContainerDmc;
|
||||
if (runControl != null && threadId != null) {
|
||||
int threadIdInt = -1;
|
||||
try {
|
||||
threadIdInt = Integer.parseInt(threadId);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
if (threadIdInt != -1) {
|
||||
execDmc = runControl.createMIExecutionContext(processContainerDmc, threadIdInt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,7 +298,8 @@ public class MIRunControlEventProcessor
|
|||
else { type = MIRunningEvent.CONTINUE; }
|
||||
|
||||
MIProcesses procService = fServicesTracker.getService(MIProcesses.class);
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(fContainerDmc, ""); //$NON-NLS-1$
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, ""); //$NON-NLS-1$
|
||||
|
||||
fCommandControl.getSession().dispatchEvent(
|
||||
new MIRunningEvent(processContainerDmc, id, type), fCommandControl.getProperties());
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
package org.eclipse.dd.mi.service.command.commands;
|
||||
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIProcessDMContext;
|
||||
import org.eclipse.dd.mi.service.command.MIControlDMContext;
|
||||
import org.eclipse.dd.mi.service.command.output.MIInfo;
|
||||
|
||||
/**
|
||||
|
@ -19,13 +19,11 @@ import org.eclipse.dd.mi.service.command.output.MIInfo;
|
|||
*/
|
||||
public class CLIAttach extends CLICommand<MIInfo> {
|
||||
|
||||
@Deprecated
|
||||
public CLIAttach(IDMContext ctx, int pid) {
|
||||
super(ctx, "attach " + Integer.toString(pid)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public CLIAttach(IMIProcessDMContext ctx) {
|
||||
super(ctx, "attach " + ctx.getProcId()); //$NON-NLS-1$
|
||||
public CLIAttach(MIControlDMContext ctx, String pid) {
|
||||
super(ctx, "attach " + pid); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
}
|
|
@ -14,6 +14,7 @@ package org.eclipse.dd.mi.service.command.commands;
|
|||
|
||||
|
||||
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.mi.service.command.output.CLIInfoThreadsInfo;
|
||||
import org.eclipse.dd.mi.service.command.output.MIInfo;
|
||||
|
@ -30,6 +31,10 @@ public class CLIInfoThreads extends CLICommand<CLIInfoThreadsInfo> {
|
|||
super(ctx, "info threads"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public CLIInfoThreads(IProcessDMContext ctx) {
|
||||
super(ctx, "info threads"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public CLIInfoThreadsInfo getResult(MIOutput output) {
|
||||
return (CLIInfoThreadsInfo)getMIInfo(output);
|
||||
|
|
|
@ -24,8 +24,8 @@ import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
|||
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBProcessData;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.IGDBRunControl.IGDBThreadData;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBProcessData;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl.GDBThreadData;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
|
||||
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.dd.tests.gdb.framework.AsyncCompletionWaitor;
|
||||
|
@ -91,8 +91,8 @@ public class GDBProcessesTest extends BaseTestCase {
|
|||
/*
|
||||
* Create a request monitor
|
||||
*/
|
||||
final DataRequestMonitor<IGDBProcessData> rm =
|
||||
new DataRequestMonitor<IGDBProcessData>(fSession.getExecutor(), null) {
|
||||
final DataRequestMonitor<GDBProcessData> rm =
|
||||
new DataRequestMonitor<GDBProcessData>(fSession.getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
|
@ -123,7 +123,7 @@ public class GDBProcessesTest extends BaseTestCase {
|
|||
/*
|
||||
* Get process data
|
||||
*/
|
||||
IGDBProcessData processData = rm.getData();
|
||||
GDBProcessData processData = rm.getData();
|
||||
|
||||
if(processData == null)
|
||||
Assert.fail("No process data is returned for Process DMC");
|
||||
|
@ -141,8 +141,8 @@ public class GDBProcessesTest extends BaseTestCase {
|
|||
*/
|
||||
@Test
|
||||
public void getThreadData() throws InterruptedException{
|
||||
final DataRequestMonitor<IGDBThreadData> rm =
|
||||
new DataRequestMonitor<IGDBThreadData>(fSession.getExecutor(), null) {
|
||||
final DataRequestMonitor<GDBThreadData> rm =
|
||||
new DataRequestMonitor<GDBThreadData>(fSession.getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
|
@ -166,7 +166,7 @@ public class GDBProcessesTest extends BaseTestCase {
|
|||
fWait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
assertTrue(fWait.getMessage(), fWait.isOK());
|
||||
|
||||
IGDBThreadData threadData = rm.getData();
|
||||
GDBThreadData threadData = rm.getData();
|
||||
if(threadData == null)
|
||||
fail("Thread data not returned for thread id = " + fExecDmc.getThreadId());
|
||||
else{
|
||||
|
|
Loading…
Add table
Reference in a new issue