mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 240507
Adds a GDBMultiProcesses service which uses the new GDB -list-thread-group commands. Also adds some support for =thread-group-created/exited events. Since the public GDB is not ready yet, I have commented out the instantiation of this new service, for now.
This commit is contained in:
parent
0d74c407e4
commit
55a4d47017
19 changed files with 1011 additions and 168 deletions
|
@ -501,7 +501,6 @@ public class GdbThreadFilterEditor {
|
|||
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() {
|
||||
|
|
|
@ -86,7 +86,7 @@ public class ContainerVMNode extends AbstractContainerVMNode
|
|||
protected void updateLabelInSessionThread(final ILabelUpdate update) {
|
||||
IProcesses processService = getServicesTracker().getService(IProcesses.class);
|
||||
IRunControl runControl = getServicesTracker().getService(IRunControl.class);
|
||||
if (processService == null) {
|
||||
if (processService == null || runControl == null) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -37,10 +37,10 @@ import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
|||
import org.eclipse.dd.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants;
|
||||
import org.eclipse.dd.gdb.internal.provisional.actions.IConnect;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.GDBProcesses;
|
||||
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.IMIProcesses;
|
||||
import org.eclipse.dd.mi.service.MIBreakpointsManager;
|
||||
import org.eclipse.dd.mi.service.command.commands.CLISource;
|
||||
import org.eclipse.dd.mi.service.command.commands.MIEnvironmentCD;
|
||||
|
@ -73,7 +73,7 @@ public class FinalLaunchSequence extends Sequence {
|
|||
new Step() { @Override
|
||||
public void execute(RequestMonitor requestMonitor) {
|
||||
fCommandControl = fTracker.getService(GDBControl.class);
|
||||
fProcService = fTracker.getService(GDBProcesses.class);
|
||||
fProcService = fTracker.getService(IMIProcesses.class);
|
||||
if (fCommandControl == null || fProcService == null) {
|
||||
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, "Cannot obtain service", null)); //$NON-NLS-1$
|
||||
}
|
||||
|
@ -464,7 +464,7 @@ public class FinalLaunchSequence extends Sequence {
|
|||
boolean fAttach;
|
||||
|
||||
GDBControl fCommandControl;
|
||||
GDBProcesses fProcService;
|
||||
IMIProcesses fProcService;
|
||||
DsfServicesTracker fTracker;
|
||||
|
||||
public FinalLaunchSequence(DsfExecutor executor, GdbLaunch launch, SessionType sessionType, boolean attach) {
|
||||
|
|
|
@ -0,0 +1,698 @@
|
|||
/*******************************************************************************
|
||||
* 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.gdb.internal.provisional.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
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.Immutable;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.AbstractDMContext;
|
||||
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.debug.service.IProcesses;
|
||||
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.IRunControl.IExitedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IResumedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IStartedDMEvent;
|
||||
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.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
|
||||
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIExecutionGroupDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIProcessDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIProcesses;
|
||||
import org.eclipse.dd.mi.service.command.MIControlDMContext;
|
||||
import org.eclipse.dd.mi.service.command.commands.MIListThreadGroups;
|
||||
import org.eclipse.dd.mi.service.command.commands.MITargetAttach;
|
||||
import org.eclipse.dd.mi.service.command.commands.MITargetDetach;
|
||||
import org.eclipse.dd.mi.service.command.events.MIThreadGroupCreatedEvent;
|
||||
import org.eclipse.dd.mi.service.command.events.MIThreadGroupExitedEvent;
|
||||
import org.eclipse.dd.mi.service.command.output.MIInfo;
|
||||
import org.eclipse.dd.mi.service.command.output.MIListThreadGroupsInfo;
|
||||
import org.eclipse.dd.mi.service.command.output.MIListThreadGroupsInfo.IThreadGroupInfo;
|
||||
import org.eclipse.dd.mi.service.command.output.MIListThreadGroupsInfo.IThreadInfo;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
|
||||
public class GDBMultiProcesses extends AbstractDsfService implements IMIProcesses {
|
||||
|
||||
// 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 in GDB/MI
|
||||
*/
|
||||
@Immutable
|
||||
private static class MIExecutionDMC extends AbstractDMContext
|
||||
implements IMIExecutionDMContext
|
||||
{
|
||||
/**
|
||||
* String ID that is used to identify the thread in the GDB/MI protocol.
|
||||
*/
|
||||
private final String fThreadId;
|
||||
|
||||
/**
|
||||
* Constructor for the context. It should not be called directly by clients.
|
||||
* Instead clients should call {@link IMIProcesses#createExecutionContext()}
|
||||
* to create instances of this context based on the thread ID.
|
||||
* <p/>
|
||||
*
|
||||
* @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, String 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the GDB/MI thread identifier of this context.
|
||||
* @return
|
||||
*/
|
||||
public int getThreadId(){
|
||||
try {
|
||||
return Integer.parseInt(fThreadId);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getId(){
|
||||
return fThreadId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() { return baseToString() + ".thread[" + fThreadId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return super.baseEquals(obj) && ((MIExecutionDMC)obj).fThreadId.equals(fThreadId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() { return super.baseHashCode() ^ fThreadId.hashCode(); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Context representing a thread group of GDB/MI.
|
||||
*/
|
||||
@Immutable
|
||||
private static class MIExecutionGroupDMC extends AbstractDMContext
|
||||
implements IMIExecutionGroupDMContext
|
||||
{
|
||||
/**
|
||||
* String ID that is used to identify the thread group in the GDB/MI protocol.
|
||||
*/
|
||||
private final String fId;
|
||||
|
||||
/**
|
||||
* Constructor for the context. It should not be called directly by clients.
|
||||
* Instead clients should call {@link IMIProcesses#createExecutionGroupContext
|
||||
* to create instances of this context based on the group name.
|
||||
*
|
||||
* @param sessionId Session that this context belongs to.
|
||||
* @param processDmc The process context that is the parent of this context.
|
||||
* @param groupId GDB/MI thread group identifier.
|
||||
*/
|
||||
public MIExecutionGroupDMC(String sessionId, IProcessDMContext processDmc, String groupId) {
|
||||
super(sessionId, processDmc == null ? new IDMContext[0] : new IDMContext[] { processDmc });
|
||||
fId = groupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the GDB/MI thread group identifier of this context.
|
||||
*/
|
||||
public String getGroupId(){ return fId; }
|
||||
|
||||
@Override
|
||||
public String toString() { return baseToString() + ".threadGroup[" + fId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return super.baseEquals(obj) &&
|
||||
(((MIExecutionGroupDMC)obj).fId == null ? fId == null : ((MIExecutionGroupDMC)obj).fId.equals(fId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() { return super.baseHashCode() ^ (fId == null ? 0 : fId.hashCode()); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Context representing a thread.
|
||||
*/
|
||||
@Immutable
|
||||
private static class MIThreadDMC extends AbstractDMContext
|
||||
implements IThreadDMContext
|
||||
{
|
||||
/**
|
||||
* ID used by GDB to refer to threads.
|
||||
*/
|
||||
private final String fId;
|
||||
|
||||
/**
|
||||
* Constructor for the context. It should not be called directly by clients.
|
||||
* Instead clients should call {@link IMIProcesses#createThreadContext}
|
||||
* to create instances of this context based on the thread ID.
|
||||
* <p/>
|
||||
*
|
||||
* @param sessionId Session that this context belongs to.
|
||||
* @param processDmc The process that this thread belongs to.
|
||||
* @param id thread identifier.
|
||||
*/
|
||||
public MIThreadDMC(String sessionId, IProcessDMContext processDmc, String 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 fId; }
|
||||
|
||||
@Override
|
||||
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).fId == null ? fId == null : ((MIThreadDMC)obj).fId.equals(fId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() { return super.baseHashCode() ^ (fId == null ? 0 : fId.hashCode()); }
|
||||
}
|
||||
|
||||
@Immutable
|
||||
private static 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 IMIProcesses#createProcessContext}
|
||||
* to create instances of this context based on the PID.
|
||||
* <p/>
|
||||
*
|
||||
* @param sessionId Session that this context belongs to.
|
||||
* @param controlDmc The control context parent of this process.
|
||||
* @param id process identifier.
|
||||
*/
|
||||
public MIProcessDMC(String sessionId, MIControlDMContext controlDmc, String id) {
|
||||
super(sessionId, controlDmc == null ? new IDMContext[0] : new IDMContext[] { controlDmc });
|
||||
fId = id;
|
||||
}
|
||||
|
||||
public String getProcId() { return fId; }
|
||||
|
||||
@Override
|
||||
public String toString() { return baseToString() + ".proc[" + fId + "]"; } //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
@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.baseHashCode() ^ (fId == null ? 0 : fId.hashCode()); }
|
||||
}
|
||||
|
||||
/*
|
||||
* The data of a corresponding thread or process.
|
||||
*/
|
||||
@Immutable
|
||||
protected static class MIThreadDMData implements IThreadDMData {
|
||||
final String fName;
|
||||
final String fId;
|
||||
|
||||
public MIThreadDMData(String name, String id) {
|
||||
fName = name;
|
||||
fId = id;
|
||||
}
|
||||
|
||||
public String getId() { return fId; }
|
||||
public String getName() { return fName; }
|
||||
public boolean isDebuggerAttached() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event indicating that an execution group (debugged process) has started. This event
|
||||
* implements the {@link IStartedMDEvent} from the IRunControl service.
|
||||
*/
|
||||
public static class ExecutionGroupStartedDMEvent extends AbstractDMEvent<IExecutionDMContext>
|
||||
implements IStartedDMEvent
|
||||
{
|
||||
public ExecutionGroupStartedDMEvent(IMIExecutionGroupDMContext context) {
|
||||
super(context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event indicating that an execution group is no longer being debugged. This event
|
||||
* implements the {@link IExitedMDEvent} from the IRunControl service.
|
||||
*/
|
||||
public static class ExecutionGroupExitedDMEvent extends AbstractDMEvent<IExecutionDMContext>
|
||||
implements IExitedDMEvent
|
||||
{
|
||||
public ExecutionGroupExitedDMEvent(IContainerDMContext context) {
|
||||
super(context);
|
||||
}
|
||||
}
|
||||
|
||||
private GDBControl fCommandControl;
|
||||
private CommandCache fCommandCache;
|
||||
|
||||
// A map of process id to process names. It is filled when we get all the processes that are running
|
||||
private Map<String, String> fProcessNames = new HashMap<String, String>();
|
||||
// A map of thread id to thread group id. We use this to find out to which threadGroup a thread belongs.
|
||||
private Map<String, String> fGroupIdMap = new HashMap<String, String>();
|
||||
|
||||
private static final String FAKE_THREAD_ID = "0"; //$NON-NLS-1$
|
||||
|
||||
public GDBMultiProcesses(DsfSession session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes this service.
|
||||
*
|
||||
* @param requestMonitor
|
||||
* The request monitor indicating the operation is finished
|
||||
*/
|
||||
@Override
|
||||
public void initialize(final RequestMonitor requestMonitor) {
|
||||
super.initialize(new RequestMonitor(getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
doInitialize(requestMonitor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes this service after our superclass's initialize()
|
||||
* method succeeds.
|
||||
*
|
||||
* @param requestMonitor
|
||||
* The call-back object to notify when this service's
|
||||
* initialization is done.
|
||||
*/
|
||||
private void doInitialize(RequestMonitor requestMonitor) {
|
||||
|
||||
fCommandControl = getServicesTracker().getService(GDBControl.class);
|
||||
fCommandCache = new CommandCache(getSession(), fCommandControl);
|
||||
fCommandCache.setContextAvailable(fCommandControl.getControlDMContext(), true);
|
||||
getSession().addServiceEventListener(this, null);
|
||||
|
||||
// Register this service.
|
||||
register(new String[] { IProcesses.class.getName(),
|
||||
IMIProcesses.class.getName(),
|
||||
GDBMultiProcesses.class.getName() },
|
||||
new Hashtable<String, String>());
|
||||
|
||||
requestMonitor.done();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method shuts down this service. It unregisters the service, stops
|
||||
* receiving service events, and calls the superclass shutdown() method to
|
||||
* finish the shutdown process.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@Override
|
||||
public void shutdown(RequestMonitor requestMonitor) {
|
||||
unregister();
|
||||
getSession().removeServiceEventListener(this);
|
||||
super.shutdown(requestMonitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The bundle context of the plug-in to which this service belongs.
|
||||
*/
|
||||
@Override
|
||||
protected BundleContext getBundleContext() {
|
||||
return GdbPlugin.getBundleContext();
|
||||
}
|
||||
|
||||
public IThreadDMContext createThreadContext(IProcessDMContext processDmc, String threadId) {
|
||||
return new MIThreadDMC(getSession().getId(), processDmc, threadId);
|
||||
}
|
||||
|
||||
public IProcessDMContext createProcessContext(MIControlDMContext controlDmc, String pid) {
|
||||
return new MIProcessDMC(getSession().getId(), controlDmc, pid);
|
||||
}
|
||||
|
||||
public IMIExecutionDMContext createExecutionContext(IContainerDMContext containerDmc,
|
||||
IThreadDMContext threadDmc,
|
||||
String threadId) {
|
||||
return new MIExecutionDMC(getSession().getId(), containerDmc, threadDmc, threadId);
|
||||
}
|
||||
|
||||
public IMIExecutionGroupDMContext createExecutionGroupContext(IProcessDMContext processDmc,
|
||||
String groupId) {
|
||||
return new MIExecutionGroupDMC(getSession().getId(), processDmc, groupId);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method obtains the model data for a given IThreadDMContext object
|
||||
* which can represent a thread or a process.
|
||||
*
|
||||
* @param dmc
|
||||
* The context for which we are requesting the data
|
||||
* @param rm
|
||||
* The request monitor that will contain the requested data
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void getModelData(IDMContext dmc, DataRequestMonitor<?> rm) {
|
||||
if (dmc instanceof IThreadDMContext) {
|
||||
getExecutionData((IThreadDMContext) dmc,
|
||||
(DataRequestMonitor<IThreadDMData>) rm);
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
public void getExecutionData(IThreadDMContext dmc, final DataRequestMonitor<IThreadDMData> rm) {
|
||||
if (dmc instanceof IMIProcessDMContext) {
|
||||
String id = ((IMIProcessDMContext)dmc).getProcId();
|
||||
String name = fProcessNames.get(id);
|
||||
if (name == null) name = "Unknown name"; //$NON-NLS-1$
|
||||
rm.setData(new MIThreadDMData(name, id));
|
||||
rm.done();
|
||||
} else if (dmc instanceof MIThreadDMC) {
|
||||
final MIThreadDMC threadDmc = (MIThreadDMC)dmc;
|
||||
|
||||
MIControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, MIControlDMContext.class);
|
||||
IMIProcessDMContext procDmc = DMContexts.getAncestorOfType(dmc, IMIProcessDMContext.class);
|
||||
fCommandCache.execute(new MIListThreadGroups(controlDmc, procDmc.getProcId()),
|
||||
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
IThreadDMData threadData = new MIThreadDMData("", ""); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
for (IThreadInfo thread : getData().getThreadList()) {
|
||||
if (thread.getThreadId().equals(threadDmc.getId())) {
|
||||
threadData = new MIThreadDMData("", thread.getOSId()); //$NON-NLS-1$
|
||||
break;
|
||||
}
|
||||
}
|
||||
rm.setData(threadData);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
public void getDebuggingContext(IThreadDMContext dmc, DataRequestMonitor<IDMContext> rm) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID,
|
||||
NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
|
||||
public void isDebuggerAttachSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
||||
rm.setData(fCommandControl.getIsAttachSession());
|
||||
rm.done();
|
||||
}
|
||||
|
||||
public void attachDebuggerToProcess(final IProcessDMContext procCtx, final DataRequestMonitor<IDMContext> rm) {
|
||||
if (procCtx instanceof IMIProcessDMContext) {
|
||||
MIControlDMContext controlDmc = DMContexts.getAncestorOfType(procCtx, MIControlDMContext.class);
|
||||
fCommandControl.queueCommand(
|
||||
new MITargetAttach(controlDmc, ((IMIProcessDMContext)procCtx).getProcId()),
|
||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
fCommandControl.setConnected(true);
|
||||
|
||||
IMIExecutionGroupDMContext groupDmc = createExecutionGroupContext(procCtx,
|
||||
((IMIProcessDMContext)procCtx).getProcId());
|
||||
rm.setData(groupDmc);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
public void canDetachDebuggerFromProcess(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
||||
rm.setData(fCommandControl.getIsAttachSession() && fCommandControl.isConnected());
|
||||
rm.done();
|
||||
}
|
||||
|
||||
public void detachDebuggerFromProcess(final IDMContext dmc, final RequestMonitor rm) {
|
||||
MIControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, MIControlDMContext.class);
|
||||
IMIProcessDMContext procDmc = DMContexts.getAncestorOfType(dmc, IMIProcessDMContext.class);
|
||||
|
||||
if (controlDmc != null && procDmc != null) {
|
||||
fCommandControl.queueCommand(
|
||||
new MITargetDetach(controlDmc, procDmc.getProcId()),
|
||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
// only if it is the last detach
|
||||
fCommandControl.setConnected(false);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid context.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
public void canTerminate(IThreadDMContext thread, DataRequestMonitor<Boolean> rm) {
|
||||
rm.setData(true);
|
||||
rm.done();
|
||||
}
|
||||
|
||||
public void isDebugNewProcessSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
||||
rm.setData(false);
|
||||
rm.done();
|
||||
}
|
||||
|
||||
public void debugNewProcess(String file, DataRequestMonitor<IProcessDMContext> rm) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID,
|
||||
NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
|
||||
public void getProcessesBeingDebugged(final IDMContext dmc, final DataRequestMonitor<IDMContext[]> rm) {
|
||||
// MIInferiorProcess inferiorProcess = fCommandControl.getInferiorProcess();
|
||||
// if (fCommandControl.isConnected() &&
|
||||
// inferiorProcess != null &&
|
||||
// inferiorProcess.getState() != MIInferiorProcess.State.TERMINATED) {
|
||||
|
||||
final MIControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, MIControlDMContext.class);
|
||||
final IMIExecutionGroupDMContext groupDmc = DMContexts.getAncestorOfType(dmc, IMIExecutionGroupDMContext.class);
|
||||
if (groupDmc != null) {
|
||||
fCommandCache.execute(
|
||||
new MIListThreadGroups(controlDmc, groupDmc.getGroupId()),
|
||||
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(makeExecutionDMCs(groupDmc, getData().getThreadList()));
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
fCommandCache.execute(
|
||||
new MIListThreadGroups(controlDmc),
|
||||
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(makeExecutionGroupDMCs(controlDmc, getData().getGroupList()));
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
// } else {
|
||||
// rm.setData(new IDMContext[0]);
|
||||
// rm.done();
|
||||
// }
|
||||
}
|
||||
|
||||
private IExecutionDMContext[] makeExecutionDMCs(IContainerDMContext containerDmc, IThreadInfo[] threadInfos) {
|
||||
final IProcessDMContext procDmc = DMContexts.getAncestorOfType(containerDmc, IProcessDMContext.class);
|
||||
|
||||
if (threadInfos.length == 0) {
|
||||
// Main thread always exist even if it is not reported by GDB.
|
||||
// So create thread-id = 0 when no thread is reported.
|
||||
// This hack is necessary to prevent AbstractMIControl from issuing a thread-select
|
||||
// because it doesn't work if the application was not compiled with pthread.
|
||||
return new IMIExecutionDMContext[]{createExecutionContext(containerDmc,
|
||||
createThreadContext(procDmc, FAKE_THREAD_ID),
|
||||
FAKE_THREAD_ID)};
|
||||
} else {
|
||||
IExecutionDMContext[] executionDmcs = new IMIExecutionDMContext[threadInfos.length];
|
||||
for (int i = 0; i < threadInfos.length; i++) {
|
||||
String threadId = threadInfos[i].getThreadId();
|
||||
executionDmcs[i] = createExecutionContext(containerDmc,
|
||||
createThreadContext(procDmc, threadId),
|
||||
threadId);
|
||||
}
|
||||
return executionDmcs;
|
||||
}
|
||||
}
|
||||
|
||||
private IMIExecutionGroupDMContext[] makeExecutionGroupDMCs(MIControlDMContext controlDmc, IThreadGroupInfo[] groups) {
|
||||
IProcessDMContext[] procDmcs = makeProcessDMCs(controlDmc, groups);
|
||||
|
||||
IMIExecutionGroupDMContext[] groupDmcs = new IMIExecutionGroupDMContext[groups.length];
|
||||
for (int i = 0; i < procDmcs.length; i++) {
|
||||
String groupId = groups[i].getGroupId();
|
||||
IProcessDMContext procDmc = createProcessContext(controlDmc, groupId);
|
||||
groupDmcs[i] = createExecutionGroupContext(procDmc, groupId);
|
||||
}
|
||||
return groupDmcs;
|
||||
}
|
||||
|
||||
public void getRunningProcesses(IDMContext dmc, final DataRequestMonitor<IProcessDMContext[]> rm) {
|
||||
final MIControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, MIControlDMContext.class);
|
||||
|
||||
if (controlDmc != null) {
|
||||
fCommandCache.execute(
|
||||
new MIListThreadGroups(controlDmc, true),
|
||||
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
for (IThreadGroupInfo groupInfo : getData().getGroupList()) {
|
||||
fProcessNames.put(groupInfo.getPid(), groupInfo.getName());
|
||||
}
|
||||
rm.setData(makeProcessDMCs(controlDmc, getData().getGroupList()));
|
||||
} else {
|
||||
rm.setData(new IProcessDMContext[0]);
|
||||
}
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid context.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private IProcessDMContext[] makeProcessDMCs(MIControlDMContext controlDmc, IThreadGroupInfo[] processes) {
|
||||
IProcessDMContext[] procDmcs = new IMIProcessDMContext[processes.length];
|
||||
for (int i=0; i<procDmcs.length; i++) {
|
||||
procDmcs[i] = createProcessContext(controlDmc, processes[i].getGroupId());
|
||||
}
|
||||
return procDmcs;
|
||||
}
|
||||
|
||||
public void isRunNewProcessSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
||||
rm.setData(false);
|
||||
rm.done();
|
||||
}
|
||||
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$
|
||||
rm.done();
|
||||
}
|
||||
|
||||
public void terminate(IThreadDMContext thread, RequestMonitor rm) {
|
||||
if (thread instanceof IMIProcessDMContext) {
|
||||
fCommandControl.terminate(rm);
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
public String getExecutionGroupIdFromThread(String threadId) {
|
||||
String groupId = fGroupIdMap.get(threadId);
|
||||
if (groupId == null) return "162"; //$NON-NLS-1$
|
||||
else return groupId;
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(IResumedDMEvent e) {
|
||||
fCommandCache.setContextAvailable(e.getDMContext(), false);
|
||||
// I need to put this so that in non-stop mode, we can send the CLIInfo
|
||||
// command while some threads are running.
|
||||
// However, in all-stop, this line breaks a thread exiting, and threads running
|
||||
// because it allows us to send the thread-list-ids although we don't have a prompt
|
||||
// We need to find a proper solution for the cache.
|
||||
// fCommandCache.setContextAvailable(fCommandControl.getControlDMContext(), true);
|
||||
if (e.getReason() != StateChangeReason.STEP) {
|
||||
fCommandCache.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(ISuspendedDMEvent e) {
|
||||
fCommandCache.setContextAvailable(e.getDMContext(), true);
|
||||
fCommandCache.setContextAvailable(fCommandControl.getControlDMContext(), true);
|
||||
fCommandCache.reset();
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(final MIThreadGroupCreatedEvent e) {
|
||||
IProcessDMContext procDmc = e.getDMContext();
|
||||
IMIExecutionGroupDMContext groupDmc = e.getGroupId() != null ? createExecutionGroupContext(procDmc, e.getGroupId()) : null;
|
||||
getSession().dispatchEvent(new ExecutionGroupStartedDMEvent(groupDmc), getProperties());
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(final MIThreadGroupExitedEvent e) {
|
||||
IProcessDMContext procDmc = e.getDMContext();
|
||||
IMIExecutionGroupDMContext groupDmc = e.getGroupId() != null ? createExecutionGroupContext(procDmc, e.getGroupId()) : null;
|
||||
getSession().dispatchEvent(new ExecutionGroupExitedDMEvent(groupDmc), getProperties());
|
||||
|
||||
}
|
||||
}
|
|
@ -98,6 +98,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
|
|||
|
||||
@Override
|
||||
protected IProcesses createProcessesService(DsfSession session) {
|
||||
// if (fVersion.startsWith("6.8.50.20080730")) { //$NON-NLS-1$
|
||||
// return new GDBMultiProcesses(session);
|
||||
// }
|
||||
return new GDBProcesses(session);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.gdb.internal.provisional.service;
|
||||
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl;
|
||||
import org.eclipse.dd.dsf.debug.service.IStack;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
|
@ -21,7 +22,15 @@ public class GdbDebugServicesFactoryNS extends GdbDebugServicesFactory {
|
|||
public GdbDebugServicesFactoryNS(String version) {
|
||||
super(version);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected IProcesses createProcessesService(DsfSession session) {
|
||||
// if (getVersion().startsWith("6.8.50.20080730")) { //$NON-NLS-1$
|
||||
// return new GDBMultiProcesses(session);
|
||||
// }
|
||||
return new GDBProcesses(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IStack createStackService(DsfSession session) {
|
||||
return new MIStackNS(session);
|
||||
|
|
|
@ -53,5 +53,7 @@ public interface IMIProcesses extends IProcesses
|
|||
*/
|
||||
IMIExecutionGroupDMContext createExecutionGroupContext(IProcessDMContext processDmc,
|
||||
String groupId);
|
||||
|
||||
String getExecutionGroupIdFromThread(String threadId);
|
||||
}
|
||||
|
||||
|
|
|
@ -297,6 +297,7 @@ public class MIProcesses extends AbstractDsfService implements IMIProcesses {
|
|||
private CommandCache fCommandCache;
|
||||
|
||||
private static final String FAKE_THREAD_ID = "0"; //$NON-NLS-1$
|
||||
private static final String UNIQUE_GROUP_ID = "0"; //$NON-NLS-1$
|
||||
|
||||
public MIProcesses(DsfSession session) {
|
||||
super(session);
|
||||
|
@ -444,13 +445,15 @@ public class MIProcesses extends AbstractDsfService implements IMIProcesses {
|
|||
|
||||
public void attachDebuggerToProcess(final IProcessDMContext procCtx, final DataRequestMonitor<IDMContext> rm) {
|
||||
if (procCtx instanceof IMIProcessDMContext) {
|
||||
|
||||
MIControlDMContext controlDmc = DMContexts.getAncestorOfType(procCtx, MIControlDMContext.class);
|
||||
fCommandControl.queueCommand(
|
||||
new CLIAttach(controlDmc, ((IMIProcessDMContext)procCtx).getProcId()),
|
||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
IMIExecutionGroupDMContext groupDmc = createExecutionGroupContext(procCtx, ""); //$NON-NLS-1$
|
||||
IMIExecutionGroupDMContext groupDmc = createExecutionGroupContext(procCtx,
|
||||
((IMIProcessDMContext)procCtx).getProcId());
|
||||
getSession().dispatchEvent(new ExecutionGroupStartedDMEvent(groupDmc),
|
||||
getProperties());
|
||||
rm.setData(groupDmc);
|
||||
|
@ -526,7 +529,8 @@ public class MIProcesses extends AbstractDsfService implements IMIProcesses {
|
|||
// This service version only handles a single process to debug, therefore, we can simply
|
||||
// create the context describing this process ourselves.
|
||||
MIControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, MIControlDMContext.class);
|
||||
IMIExecutionGroupDMContext newGroupDmc = createExecutionGroupContext(createProcessContext(controlDmc, ""), "");//$NON-NLS-1$//$NON-NLS-2$
|
||||
IProcessDMContext procDmc = createProcessContext(controlDmc, UNIQUE_GROUP_ID);
|
||||
IMIExecutionGroupDMContext newGroupDmc = createExecutionGroupContext(procDmc, UNIQUE_GROUP_ID);
|
||||
rm.setData(new IContainerDMContext[] {newGroupDmc});
|
||||
rm.done();
|
||||
}
|
||||
|
@ -577,6 +581,10 @@ public class MIProcesses extends AbstractDsfService implements IMIProcesses {
|
|||
rm.done();
|
||||
}
|
||||
|
||||
public String getExecutionGroupIdFromThread(String threadId) {
|
||||
return UNIQUE_GROUP_ID;
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(IResumedDMEvent e) {
|
||||
fCommandCache.setContextAvailable(e.getDMContext(), false);
|
||||
|
|
|
@ -44,7 +44,6 @@ import org.eclipse.dd.mi.service.command.commands.MIExecNextInstruction;
|
|||
import org.eclipse.dd.mi.service.command.commands.MIExecStep;
|
||||
import org.eclipse.dd.mi.service.command.commands.MIExecStepInstruction;
|
||||
import org.eclipse.dd.mi.service.command.commands.MIExecUntil;
|
||||
import org.eclipse.dd.mi.service.command.commands.MIThreadListIds;
|
||||
import org.eclipse.dd.mi.service.command.events.IMIDMEvent;
|
||||
import org.eclipse.dd.mi.service.command.events.MIBreakpointHitEvent;
|
||||
import org.eclipse.dd.mi.service.command.events.MIErrorEvent;
|
||||
|
@ -58,7 +57,6 @@ import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent;
|
|||
import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent;
|
||||
import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent;
|
||||
import org.eclipse.dd.mi.service.command.output.MIInfo;
|
||||
import org.eclipse.dd.mi.service.command.output.MIThreadListIdsInfo;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
|
@ -286,7 +284,6 @@ public class MIRunControlNS extends AbstractDsfService implements IRunControl
|
|||
public void shutdown(final RequestMonitor rm) {
|
||||
unregister();
|
||||
getSession().removeServiceEventListener(this);
|
||||
fMICommandCache.reset();
|
||||
super.shutdown(rm);
|
||||
}
|
||||
|
||||
|
@ -647,24 +644,22 @@ public class MIRunControlNS extends AbstractDsfService implements IRunControl
|
|||
// ------------------------------------------------------------------------
|
||||
|
||||
public void getExecutionContexts(final IContainerDMContext containerDmc, final DataRequestMonitor<IExecutionDMContext[]> rm) {
|
||||
fMICommandCache.execute(new MIThreadListIds(containerDmc),
|
||||
new DataRequestMonitor<MIThreadListIdsInfo>(getExecutor(), rm) {
|
||||
IMIProcesses procService = getServicesTracker().getService(IMIProcesses.class);
|
||||
procService.getProcessesBeingDebugged(
|
||||
containerDmc,
|
||||
new DataRequestMonitor<IDMContext[]>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(makeExecutionDMCs(containerDmc, getData()));
|
||||
if (getData() instanceof IExecutionDMContext[]) {
|
||||
rm.setData((IExecutionDMContext[])getData());
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid contexts", null)); //$NON-NLS-1$
|
||||
}
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private IExecutionDMContext[] makeExecutionDMCs(IContainerDMContext containerCtx, MIThreadListIdsInfo info) {
|
||||
IExecutionDMContext[] executionDmcs = new IMIExecutionDMContext[info.getStrThreadIds().length];
|
||||
for (int i = 0; i < info.getStrThreadIds().length; i++) {
|
||||
executionDmcs[i] = createMIExecutionContext(containerCtx, info.getStrThreadIds()[i]);
|
||||
}
|
||||
return executionDmcs;
|
||||
}
|
||||
|
||||
public void getExecutionData(IExecutionDMContext dmc, DataRequestMonitor<IExecutionDMData> rm) {
|
||||
MIThreadRunState threadState = fThreadRunStates.get(dmc);
|
||||
if (threadState == null) {
|
||||
|
|
|
@ -123,10 +123,14 @@ public class CLIEventProcessor
|
|||
Pattern pattern = Pattern.compile("(^\\[New Thread.*LWP\\s*)(\\d*)", Pattern.MULTILINE); //$NON-NLS-1$
|
||||
Matcher matcher = pattern.matcher(exec.getCString());
|
||||
if (matcher.find()) {
|
||||
String threadId = Integer.toString(++fLastThreadId);
|
||||
|
||||
IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, ""); //$NON-NLS-1$
|
||||
MIEvent<?> e = new MIThreadCreatedEvent(processContainerDmc, Integer.toString(++fLastThreadId));
|
||||
String groupId = procService.getExecutionGroupIdFromThread(threadId);
|
||||
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, groupId);
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, groupId);
|
||||
MIEvent<?> e = new MIThreadCreatedEvent(processContainerDmc, threadId);
|
||||
fCommandControl.getSession().dispatchEvent(e, fCommandControl.getProperties());
|
||||
}
|
||||
|
||||
|
@ -147,8 +151,10 @@ public class CLIEventProcessor
|
|||
if (fInferior.getState() == MIInferiorProcess.State.RUNNING) {
|
||||
fInferior.setState(MIInferiorProcess.State.STOPPED);
|
||||
IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, ""); //$NON-NLS-1$
|
||||
String groupId = procService.getExecutionGroupIdFromThread(null);
|
||||
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, groupId);
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, groupId);
|
||||
fCommandControl.getSession().dispatchEvent(
|
||||
MIErrorEvent.parse(processContainerDmc, rr.getToken(), rr.getMIResults(), null),
|
||||
fCommandControl.getProperties());
|
||||
|
@ -191,8 +197,10 @@ public class CLIEventProcessor
|
|||
if (type != -1) {
|
||||
// if it was a step instruction set state running
|
||||
IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, ""); //$NON-NLS-1$
|
||||
String groupId = procService.getExecutionGroupIdFromThread(null);
|
||||
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, groupId);
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, groupId);
|
||||
MIEvent<?> event = new MIRunningEvent(processContainerDmc, token, type);
|
||||
fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ import org.eclipse.dd.mi.service.command.events.MISteppingRangeEvent;
|
|||
import org.eclipse.dd.mi.service.command.events.MIStoppedEvent;
|
||||
import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent;
|
||||
import org.eclipse.dd.mi.service.command.events.MIThreadExitEvent;
|
||||
import org.eclipse.dd.mi.service.command.events.MIThreadGroupCreatedEvent;
|
||||
import org.eclipse.dd.mi.service.command.events.MIThreadGroupExitedEvent;
|
||||
import org.eclipse.dd.mi.service.command.events.MIWatchpointScopeEvent;
|
||||
import org.eclipse.dd.mi.service.command.events.MIWatchpointTriggerEvent;
|
||||
import org.eclipse.dd.mi.service.command.output.MIConst;
|
||||
|
@ -157,9 +159,8 @@ public class MIRunControlEventProcessor
|
|||
MINotifyAsyncOutput exec = (MINotifyAsyncOutput) oobr;
|
||||
String miEvent = exec.getAsyncClass();
|
||||
if ("thread-created".equals(miEvent) || "thread-exited".equals(miEvent)) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
// For now, since GDB does not support thread-groups, fake an empty one
|
||||
String groupId = "";//null; //$NON-NLS-1$
|
||||
String threadId = null;
|
||||
String groupId = null;
|
||||
|
||||
MIResult[] results = exec.getMIResults();
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
|
@ -169,33 +170,74 @@ public class MIRunControlEventProcessor
|
|||
if (val instanceof MIConst) {
|
||||
groupId = ((MIConst) val).getString();
|
||||
}
|
||||
}
|
||||
} else if (var.equals("id")) { //$NON-NLS-1$
|
||||
if (val instanceof MIConst) {
|
||||
threadId = ((MIConst) val).getString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$
|
||||
|
||||
if (groupId == null) {
|
||||
groupId = procService.getExecutionGroupIdFromThread(threadId);
|
||||
}
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, groupId);
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, groupId);
|
||||
|
||||
MIEvent<?> event = null;
|
||||
if ("thread-created".equals(miEvent)) { //$NON-NLS-1$
|
||||
event = MIThreadCreatedEvent.parse(processContainerDmc, exec.getToken(), exec.getMIResults());
|
||||
event = new MIThreadCreatedEvent(processContainerDmc, exec.getToken(), threadId);
|
||||
} else if ("thread-exited".equals(miEvent)) { //$NON-NLS-1$
|
||||
event = MIThreadExitEvent.parse(processContainerDmc, exec.getToken(), exec.getMIResults());
|
||||
event = new MIThreadExitEvent(processContainerDmc, exec.getToken(), threadId);
|
||||
}
|
||||
|
||||
if (event != null) {
|
||||
fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
|
||||
}
|
||||
}
|
||||
} else if (oobr instanceof MINotifyAsyncOutput) {
|
||||
// Parse the string and dispatch the corresponding event
|
||||
MINotifyAsyncOutput exec = (MINotifyAsyncOutput) oobr;
|
||||
String miEvent = exec.getAsyncClass();
|
||||
if ("thread-group-created".equals(miEvent) || "thread-group-exited".equals(miEvent)) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
String groupId = null;
|
||||
|
||||
MIResult[] results = exec.getMIResults();
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
String var = results[i].getVariable();
|
||||
MIValue val = results[i].getMIValue();
|
||||
if (var.equals("id")) { //$NON-NLS-1$
|
||||
if (val instanceof MIConst) {
|
||||
groupId = ((MIConst) val).getString().trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (groupId != null) {
|
||||
IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, groupId);
|
||||
|
||||
MIEvent<?> event = null;
|
||||
if ("thread-group-created".equals(miEvent)) { //$NON-NLS-1$
|
||||
event = new MIThreadGroupCreatedEvent(procDmc, exec.getToken(), groupId);
|
||||
} else if ("thread-group-exited".equals(miEvent)) { //$NON-NLS-1$
|
||||
event = new MIThreadGroupExitedEvent(procDmc, exec.getToken(), groupId);
|
||||
}
|
||||
|
||||
if (event != null) {
|
||||
fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected MIEvent<?> createEvent(String reason, MIExecAsyncOutput exec) {
|
||||
String threadId = null;
|
||||
|
||||
// For now, since GDB does not support thread-groups, fake an empty one
|
||||
String groupId = "";//null; //$NON-NLS-1$
|
||||
String groupId = null;
|
||||
|
||||
MIResult[] results = exec.getMIResults();
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
|
@ -215,7 +257,10 @@ public class MIRunControlEventProcessor
|
|||
|
||||
IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
|
||||
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$
|
||||
if (groupId == null) {
|
||||
groupId = procService.getExecutionGroupIdFromThread(threadId);
|
||||
}
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, groupId);
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, groupId);
|
||||
|
||||
IExecutionDMContext execDmc = processContainerDmc;
|
||||
|
@ -291,8 +336,9 @@ public class MIRunControlEventProcessor
|
|||
else { type = MIRunningEvent.CONTINUE; }
|
||||
|
||||
IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, ""); //$NON-NLS-1$
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, ""); //$NON-NLS-1$
|
||||
String groupId = procService.getExecutionGroupIdFromThread(null);
|
||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, groupId);
|
||||
IContainerDMContext processContainerDmc = procService.createExecutionGroupContext(procDmc, groupId);
|
||||
|
||||
fCommandControl.getSession().dispatchEvent(
|
||||
new MIRunningEvent(processContainerDmc, id, type), fCommandControl.getProperties());
|
||||
|
|
|
@ -12,23 +12,22 @@ package org.eclipse.dd.mi.service.command.commands;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIExecutionGroupDMContext;
|
||||
import org.eclipse.dd.mi.service.command.MIControlDMContext;
|
||||
import org.eclipse.dd.mi.service.command.output.MIListThreadGroupsInfo;
|
||||
import org.eclipse.dd.mi.service.command.output.MIOutput;
|
||||
|
||||
/**
|
||||
* -list-thread-groups [--available] [GROUP]
|
||||
* -list-thread-groups [--available | GROUP]
|
||||
*
|
||||
* When used without GROUP parameter, this will list top-level
|
||||
* thread groups that are been debugged. When used with the GROUP
|
||||
* thread groups that are being debugged. When used with the GROUP
|
||||
* parameter, the children of the specified group will be listed.
|
||||
* The children can be either threads, or other groups. At present,
|
||||
* GDB will not report both threads and groups as children at the
|
||||
* same time, but it may change in future.
|
||||
*
|
||||
* With the --available option, instead of reporting groups that are
|
||||
* been debugged, GDB will report all thread groups available on the
|
||||
* being debugged, GDB will report all thread groups available on the
|
||||
* target, not only the presently debugged ones. Using the --available
|
||||
* option together with explicit GROUP is not likely to work on all targets.
|
||||
*
|
||||
|
@ -45,11 +44,24 @@ import org.eclipse.dd.mi.service.command.output.MIOutput;
|
|||
*/
|
||||
public class MIListThreadGroups extends MICommand<MIListThreadGroupsInfo> {
|
||||
|
||||
public MIListThreadGroups(IContainerDMContext ctx) {
|
||||
// List all groups being debugged
|
||||
public MIListThreadGroups(MIControlDMContext ctx) {
|
||||
this(ctx, false);
|
||||
}
|
||||
|
||||
public MIListThreadGroups(IContainerDMContext ctx, boolean listAll) {
|
||||
// List all groups or threads being debugged which are children of the specified group
|
||||
public MIListThreadGroups(MIControlDMContext ctx, String groupId) {
|
||||
this(ctx, groupId, false);
|
||||
}
|
||||
|
||||
// List all groups available on the target
|
||||
public MIListThreadGroups(MIControlDMContext ctx, boolean listAll) {
|
||||
this(ctx, null, listAll);
|
||||
}
|
||||
|
||||
// There should be no reason to have both listAll and groupId specified,
|
||||
// so this constructor is private, and exists to avoid duplicating code.
|
||||
private MIListThreadGroups(MIControlDMContext ctx, String groupId, boolean listAll) {
|
||||
super(ctx, "-list-thread-groups"); //$NON-NLS-1$
|
||||
|
||||
final ArrayList<String> arguments = new ArrayList<String>();
|
||||
|
@ -57,11 +69,8 @@ public class MIListThreadGroups extends MICommand<MIListThreadGroupsInfo> {
|
|||
arguments.add("--available"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
// If the context is a thread-group, use the thread-group name
|
||||
// to list its children; if it is not, then we don't use any name to get
|
||||
// the list of all thread-groups
|
||||
if (ctx instanceof IMIExecutionGroupDMContext) {
|
||||
arguments.add(((IMIExecutionGroupDMContext)ctx).getGroupId());
|
||||
if (groupId != null) {
|
||||
arguments.add(groupId);
|
||||
}
|
||||
|
||||
if (!arguments.isEmpty()) {
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.mi.service.command.commands;
|
||||
|
||||
import org.eclipse.dd.mi.service.IMIExecutionGroupDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIProcessDMContext;
|
||||
import org.eclipse.dd.mi.service.command.MIControlDMContext;
|
||||
import org.eclipse.dd.mi.service.command.output.MIInfo;
|
||||
|
||||
/**
|
||||
|
@ -22,11 +21,7 @@ import org.eclipse.dd.mi.service.command.output.MIInfo;
|
|||
*/
|
||||
public class MITargetAttach extends MICommand<MIInfo> {
|
||||
|
||||
public MITargetAttach(IMIExecutionGroupDMContext ctx) {
|
||||
super(ctx, "-target-attach", new String[] {ctx.getGroupId()}); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public MITargetAttach(IMIProcessDMContext ctx) {
|
||||
super(ctx, "-target-attach", new String[] {"--pid " + ctx.getProcId()}); //$NON-NLS-1$//$NON-NLS-2$
|
||||
public MITargetAttach(MIControlDMContext ctx, String groupId) {
|
||||
super(ctx, "-target-attach", new String[] {groupId}); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.mi.service.command.commands;
|
||||
|
||||
import org.eclipse.dd.mi.service.IMIExecutionGroupDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIProcessDMContext;
|
||||
import org.eclipse.dd.mi.service.command.MIControlDMContext;
|
||||
import org.eclipse.dd.mi.service.command.output.MIInfo;
|
||||
|
||||
/**
|
||||
|
@ -21,12 +20,8 @@ import org.eclipse.dd.mi.service.command.output.MIInfo;
|
|||
* or THREAD_GROUP_ID
|
||||
*/
|
||||
public class MITargetDetach extends MICommand<MIInfo> {
|
||||
|
||||
public MITargetDetach(IMIExecutionGroupDMContext ctx) {
|
||||
super(ctx, "-target-detach", new String[] {ctx.getGroupId()}); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public MITargetDetach(IMIProcessDMContext ctx) {
|
||||
super(ctx, "-target-detach", new String[] {"--pid " + ctx.getProcId()}); //$NON-NLS-1$//$NON-NLS-2$
|
||||
public MITargetDetach(MIControlDMContext ctx, String groupId) {
|
||||
super(ctx, "-target-detach", new String[] {groupId}); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,13 +14,10 @@ package org.eclipse.dd.mi.service.command.events;
|
|||
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.mi.service.command.output.MIConst;
|
||||
import org.eclipse.dd.mi.service.command.output.MIResult;
|
||||
import org.eclipse.dd.mi.service.command.output.MIValue;
|
||||
|
||||
|
||||
/**
|
||||
* This can not be detected yet by gdb/mi.
|
||||
* This can only be detected by gdb/mi after GDB 6.8.
|
||||
*
|
||||
*/
|
||||
@Immutable
|
||||
|
@ -58,19 +55,4 @@ public class MIThreadCreatedEvent extends MIEvent<IContainerDMContext> {
|
|||
public String getStrId() {
|
||||
return fThreadId;
|
||||
}
|
||||
|
||||
public static MIThreadCreatedEvent parse(IContainerDMContext ctx, int token, MIResult[] results)
|
||||
{
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
String var = results[i].getVariable();
|
||||
MIValue val = results[i].getMIValue();
|
||||
if (var.equals("id")) { //$NON-NLS-1$
|
||||
if (val instanceof MIConst) {
|
||||
return new MIThreadCreatedEvent(ctx, token, ((MIConst) val).getString().trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,9 +14,6 @@ package org.eclipse.dd.mi.service.command.events;
|
|||
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.mi.service.command.output.MIConst;
|
||||
import org.eclipse.dd.mi.service.command.output.MIResult;
|
||||
import org.eclipse.dd.mi.service.command.output.MIValue;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -58,19 +55,4 @@ public class MIThreadExitEvent extends MIEvent<IContainerDMContext> {
|
|||
public String getStrId() {
|
||||
return fThreadId;
|
||||
}
|
||||
|
||||
public static MIThreadExitEvent parse(IContainerDMContext ctx, int token, MIResult[] results)
|
||||
{
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
String var = results[i].getVariable();
|
||||
MIValue val = results[i].getMIValue();
|
||||
if (var.equals("id")) { //$NON-NLS-1$
|
||||
if (val instanceof MIConst) {
|
||||
return new MIThreadExitEvent(ctx, token, ((MIConst) val).getString().trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*******************************************************************************
|
||||
* 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.command.events;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||
|
||||
|
||||
/**
|
||||
* This can only be detected by gdb/mi after GDB 6.8.
|
||||
*
|
||||
*/
|
||||
@Immutable
|
||||
public class MIThreadGroupCreatedEvent extends MIEvent<IProcessDMContext> {
|
||||
|
||||
final private String fGroupId;
|
||||
|
||||
public MIThreadGroupCreatedEvent(IProcessDMContext ctx, int token, String groupId) {
|
||||
super(ctx, token, null);
|
||||
fGroupId = groupId;
|
||||
}
|
||||
|
||||
public String getGroupId() { return fGroupId; }
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*******************************************************************************
|
||||
* 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.command.events;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
import org.eclipse.dd.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||
|
||||
|
||||
/**
|
||||
* This can only be detected by gdb/mi after GDB 6.8.
|
||||
*
|
||||
*/
|
||||
@Immutable
|
||||
public class MIThreadGroupExitedEvent extends MIEvent<IProcessDMContext> {
|
||||
|
||||
final private String fGroupId;
|
||||
|
||||
public MIThreadGroupExitedEvent(IProcessDMContext ctx, int token, String groupId) {
|
||||
super(ctx, token, null);
|
||||
fGroupId = groupId;
|
||||
}
|
||||
|
||||
public String getGroupId() { return fGroupId; }
|
||||
}
|
|
@ -11,75 +11,105 @@
|
|||
|
||||
package org.eclipse.dd.mi.service.command.output;
|
||||
|
||||
import org.eclipse.cdt.core.IProcessInfo;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* GDB/MI thread group parsing.
|
||||
*
|
||||
* ^done,groups=[{id="p133",type="process",pid="133"},{id="p162",type="process",pid="162"}]
|
||||
* or
|
||||
* ^done,threads=[{id="1",target-id="Thread 162.32942",details="JUnitProcess_PT (Ready) 1275938023 3473",frame={level="0",addr="0x00000000",func="??",args=[]}}]
|
||||
* The description field can be different depending on the target we are connected to.
|
||||
*
|
||||
* This output is from -list-thread-groups --available:
|
||||
* ^done,groups=[{id="160",description="name: JIM_InstallerProcess, type 555481, locked: N, system: N, state: Idle"},
|
||||
* {id="161",description="name: JIM_TcpSetupHandlerProcess, type 555505, locked: N, system: N, state: Idle"},
|
||||
* {id="162",description="name: JUnitProcess_PT, type 1094605, locked: N, system: N, state: Idle"}]
|
||||
*
|
||||
* This output is from -list-thread-groups:
|
||||
* ^done,groups=[{id="162",type="process",pid="162"}]
|
||||
*
|
||||
* This output is from -list-thread-groups GROUPID, in the case of a running thread or a stopped thread:
|
||||
* ^done,threads=[{id="1",target-id="Thread 162.32942",details="JUnitProcess_PT (Ready) 1030373359 44441",frame={level="0",addr="0x00000000",func="??",args=[]},state="stopped"}]
|
||||
* ^done,threads=[{id="1",target-id="Thread 162.32942",details="JUnitProcess_PT Idle 981333916 42692",state="running"}]
|
||||
*/
|
||||
public class MIListThreadGroupsInfo extends MIInfo {
|
||||
|
||||
public class ThreadGroupInfo implements IProcessInfo {
|
||||
int pid;
|
||||
String name;
|
||||
public interface IThreadGroupInfo {
|
||||
String getGroupId();
|
||||
String getPid();
|
||||
String getName();
|
||||
String getDesciption();
|
||||
}
|
||||
|
||||
@Immutable
|
||||
private static class ThreadGroupInfo implements IThreadGroupInfo {
|
||||
final String fGroupId;
|
||||
final String fDescription;
|
||||
final String fName;
|
||||
|
||||
public ThreadGroupInfo(String name, String pidStr) {
|
||||
try {
|
||||
this.pid = Integer.parseInt(pidStr);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
this.name = name;
|
||||
public ThreadGroupInfo(String id, String description) {
|
||||
fGroupId = id;
|
||||
fDescription = description;
|
||||
|
||||
fName = parseName(fDescription);
|
||||
}
|
||||
|
||||
public ThreadGroupInfo(String name, int pid) {
|
||||
this.pid = pid;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.IProcessInfo#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
private static String parseName(String desc) {
|
||||
String name = ""; //$NON-NLS-1$
|
||||
|
||||
// Find the string "name: " followed by the smallest set of characters that
|
||||
// is followed by a comma, or by the end of the line.
|
||||
Pattern pattern = Pattern.compile("name: (.*?)(, |$)", Pattern.MULTILINE); //$NON-NLS-1$
|
||||
Matcher matcher = pattern.matcher(desc);
|
||||
if (matcher.find()) {
|
||||
name = matcher.group(1);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.core.IProcessInfo#getPid()
|
||||
*/
|
||||
public int getPid() {
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
|
||||
public class ThreadId {
|
||||
String fId;
|
||||
|
||||
public ThreadId(String id) {
|
||||
fId = id;
|
||||
}
|
||||
public String getId() {
|
||||
return fId;
|
||||
}
|
||||
public String getGroupId() { return fGroupId; }
|
||||
public String getPid() { return fGroupId; }
|
||||
|
||||
public String getName() { return fName; }
|
||||
|
||||
public String getDesciption() { return fDescription; }
|
||||
}
|
||||
|
||||
IProcessInfo[] fProcessList;
|
||||
ThreadId[] fThreadList;
|
||||
public interface IThreadInfo {
|
||||
String getThreadId();
|
||||
String getOSId();
|
||||
String getState();
|
||||
}
|
||||
|
||||
@Immutable
|
||||
private static class ThreadInfo implements IThreadInfo {
|
||||
final String fThreadId;
|
||||
final String fOSId;
|
||||
final String fState;
|
||||
|
||||
public ThreadInfo(String id, String osId, String state) {
|
||||
fThreadId = id;
|
||||
fOSId = osId;
|
||||
fState = state;
|
||||
}
|
||||
|
||||
public String getThreadId() { return fThreadId; }
|
||||
public String getOSId() { return fOSId; }
|
||||
public String getState() { return fState; }
|
||||
}
|
||||
|
||||
IThreadGroupInfo[] fGroupList;
|
||||
IThreadInfo[] fThreadList;
|
||||
|
||||
public MIListThreadGroupsInfo(MIOutput out) {
|
||||
super(out);
|
||||
parse();
|
||||
}
|
||||
|
||||
public IProcessInfo[] getGroupList() {
|
||||
return fProcessList;
|
||||
}
|
||||
|
||||
public ThreadId[] getThreadList() {
|
||||
return fThreadList;
|
||||
}
|
||||
public IThreadGroupInfo[] getGroupList() { return fGroupList; }
|
||||
public IThreadInfo[] getThreadList() { return fThreadList; }
|
||||
|
||||
private void parse() {
|
||||
if (isDone()) {
|
||||
|
@ -104,20 +134,20 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (fProcessList == null) {
|
||||
fProcessList = new ThreadGroupInfo[0];
|
||||
if (fGroupList == null) {
|
||||
fGroupList = new IThreadGroupInfo[0];
|
||||
}
|
||||
if (fThreadList == null) {
|
||||
fThreadList = new ThreadId[0];
|
||||
fThreadList = new IThreadInfo[0];
|
||||
}
|
||||
}
|
||||
|
||||
private void parseGroups(MIList list) {
|
||||
MIValue[] values = list.getMIValues();
|
||||
fProcessList = new ThreadGroupInfo[values.length];
|
||||
fGroupList = new ThreadGroupInfo[values.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
MIResult[] results = ((MITuple)values[i]).getMIResults();
|
||||
String name = "", pid = "";//$NON-NLS-1$//$NON-NLS-2$
|
||||
String id = "", desc = "";//$NON-NLS-1$//$NON-NLS-2$
|
||||
|
||||
for (MIResult result : results) {
|
||||
String var = result.getVariable();
|
||||
|
@ -125,27 +155,27 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
|||
MIValue value = result.getMIValue();
|
||||
if (value instanceof MIConst) {
|
||||
String str = ((MIConst)value).getCString();
|
||||
name = str.trim();
|
||||
|
||||
id = str.trim();
|
||||
}
|
||||
} else if (var.equals("pid")) { //$NON-NLS-1$
|
||||
} else if (var.equals("description")) { //$NON-NLS-1$
|
||||
MIValue value = result.getMIValue();
|
||||
if (value instanceof MIConst) {
|
||||
String str = ((MIConst)value).getCString();
|
||||
pid = str.trim();
|
||||
desc = str.trim();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
fProcessList[i] = new ThreadGroupInfo(name, pid);
|
||||
fGroupList[i] = new ThreadGroupInfo(id, desc);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseThreads(MIList list) {
|
||||
MIValue[] values = list.getMIValues();
|
||||
fThreadList = new ThreadId[values.length];
|
||||
fThreadList = new ThreadInfo[values.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
MIResult[] results = ((MITuple)values[i]).getMIResults();
|
||||
String id = "", osId = "", state = "";//$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||
|
||||
for (MIResult result : results) {
|
||||
String var = result.getVariable();
|
||||
|
@ -153,11 +183,26 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
|||
MIValue value = result.getMIValue();
|
||||
if (value instanceof MIConst) {
|
||||
String str = ((MIConst)value).getCString();
|
||||
fThreadList[i] = new ThreadId(str.trim());
|
||||
break;
|
||||
id = str.trim();
|
||||
}
|
||||
} else if (var.equals("target-id")) { //$NON-NLS-1$
|
||||
MIValue value = result.getMIValue();
|
||||
if (value instanceof MIConst) {
|
||||
String str = ((MIConst)value).getCString();
|
||||
osId = str.trim();
|
||||
|
||||
}
|
||||
} else if (var.equals("state")) { //$NON-NLS-1$
|
||||
MIValue value = result.getMIValue();
|
||||
if (value instanceof MIConst) {
|
||||
String str = ((MIConst)value).getCString();
|
||||
state = str.trim();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
fThreadList[i] = new ThreadInfo(id, osId, state);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue