mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 240507 Fix the cache for the GDBMultiProcesses service. Also clean up the use of thread-info
This commit is contained in:
parent
1fbfd51fac
commit
eeb6b080ef
9 changed files with 342 additions and 236 deletions
|
@ -25,18 +25,20 @@ 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.IContainerResumedDMEvent;
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
|
||||
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.internal.MIPlugin;
|
||||
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIExecutionGroupDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIProcessDMContext;
|
||||
|
@ -45,12 +47,16 @@ 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.commands.MIThreadInfo;
|
||||
import org.eclipse.dd.mi.service.command.events.IMIDMEvent;
|
||||
import org.eclipse.dd.mi.service.command.events.MIThreadCreatedEvent;
|
||||
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.IThreadInfo;
|
||||
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.MIThreadInfoInfo;
|
||||
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;
|
||||
|
||||
|
||||
|
@ -305,7 +311,12 @@ public class GDBMultiProcesses extends AbstractDsfService implements IMIProcesse
|
|||
}
|
||||
|
||||
private GDBControl fCommandControl;
|
||||
private CommandCache fCommandCache;
|
||||
|
||||
// A cache for commands about the threadGroups
|
||||
private CommandCache fContainerCommandCache;
|
||||
|
||||
//A cache for commands about the threads
|
||||
private CommandCache fThreadCommandCache;
|
||||
|
||||
// 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>();
|
||||
|
@ -345,8 +356,11 @@ public class GDBMultiProcesses extends AbstractDsfService implements IMIProcesse
|
|||
private void doInitialize(RequestMonitor requestMonitor) {
|
||||
|
||||
fCommandControl = getServicesTracker().getService(GDBControl.class);
|
||||
fCommandCache = new CommandCache(getSession(), fCommandControl);
|
||||
fCommandCache.setContextAvailable(fCommandControl.getControlDMContext(), true);
|
||||
fContainerCommandCache = new CommandCache(getSession(), fCommandControl);
|
||||
fContainerCommandCache.setContextAvailable(fCommandControl.getControlDMContext(), true);
|
||||
fThreadCommandCache = new CommandCache(getSession(), fCommandControl);
|
||||
fThreadCommandCache.setContextAvailable(fCommandControl.getControlDMContext(), true);
|
||||
|
||||
getSession().addServiceEventListener(this, null);
|
||||
|
||||
// Register this service.
|
||||
|
@ -431,18 +445,18 @@ public class GDBMultiProcesses extends AbstractDsfService implements IMIProcesse
|
|||
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) {
|
||||
fThreadCommandCache.execute(new MIThreadInfo(controlDmc, threadDmc.getId()),
|
||||
new DataRequestMonitor<MIThreadInfoInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
IThreadDMData threadData = new MIThreadDMData("", ""); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
for (IThreadInfo thread : getData().getThreadList()) {
|
||||
if (getData().getThreadList().length != 0) {
|
||||
IThreadInfo thread = getData().getThreadList()[0];
|
||||
if (thread.getThreadId().equals(threadDmc.getId())) {
|
||||
threadData = new MIThreadDMData("", thread.getOSId()); //$NON-NLS-1$
|
||||
break;
|
||||
threadData = new MIThreadDMData("", thread.getOsId()); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
rm.setData(threadData);
|
||||
rm.done();
|
||||
}
|
||||
|
@ -454,8 +468,18 @@ public class GDBMultiProcesses extends AbstractDsfService implements IMIProcesse
|
|||
}
|
||||
|
||||
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$
|
||||
if (dmc instanceof MIProcessDMC) {
|
||||
MIProcessDMC procDmc = (MIProcessDMC)dmc;
|
||||
rm.setData(createExecutionGroupContext(procDmc, procDmc.getProcId()));
|
||||
} else if (dmc instanceof MIThreadDMC) {
|
||||
MIThreadDMC threadDmc = (MIThreadDMC)dmc;
|
||||
IMIProcessDMContext procDmc = DMContexts.getAncestorOfType(dmc, IMIProcessDMContext.class);
|
||||
IMIExecutionGroupDMContext groupDmc = createExecutionGroupContext(procDmc, procDmc.getProcId());
|
||||
rm.setData(createExecutionContext(groupDmc, threadDmc, threadDmc.getId()));
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, MIPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid thread context.", null)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
rm.done();
|
||||
}
|
||||
|
||||
|
@ -538,17 +562,17 @@ public class GDBMultiProcesses extends AbstractDsfService implements IMIProcesse
|
|||
final MIControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, MIControlDMContext.class);
|
||||
final IMIExecutionGroupDMContext groupDmc = DMContexts.getAncestorOfType(dmc, IMIExecutionGroupDMContext.class);
|
||||
if (groupDmc != null) {
|
||||
fCommandCache.execute(
|
||||
fThreadCommandCache.execute(
|
||||
new MIListThreadGroups(controlDmc, groupDmc.getGroupId()),
|
||||
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(makeExecutionDMCs(groupDmc, getData().getThreadList()));
|
||||
rm.setData(makeExecutionDMCs(groupDmc, getData().getThreadInfo().getThreadList()));
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
fCommandCache.execute(
|
||||
fContainerCommandCache.execute(
|
||||
new MIListThreadGroups(controlDmc),
|
||||
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
|
@ -603,7 +627,8 @@ public class GDBMultiProcesses extends AbstractDsfService implements IMIProcesse
|
|||
final MIControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, MIControlDMContext.class);
|
||||
|
||||
if (controlDmc != null) {
|
||||
fCommandCache.execute(
|
||||
// Don't cache this command since the list can change at any time.
|
||||
fCommandControl.queueCommand(
|
||||
new MIListThreadGroups(controlDmc, true),
|
||||
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
|
@ -655,32 +680,10 @@ public class GDBMultiProcesses extends AbstractDsfService implements IMIProcesse
|
|||
|
||||
public String getExecutionGroupIdFromThread(String threadId) {
|
||||
String groupId = fGroupIdMap.get(threadId);
|
||||
if (groupId == null) return "162"; //$NON-NLS-1$
|
||||
if (groupId == null) return ""; //$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();
|
||||
|
@ -695,4 +698,67 @@ public class GDBMultiProcesses extends AbstractDsfService implements IMIProcesse
|
|||
getSession().dispatchEvent(new ExecutionGroupExitedDMEvent(groupDmc), getProperties());
|
||||
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(IResumedDMEvent e) {
|
||||
if (e instanceof IContainerResumedDMEvent) {
|
||||
// This will happen in all-stop mode
|
||||
fContainerCommandCache.setContextAvailable(e.getDMContext(), false);
|
||||
fThreadCommandCache.setContextAvailable(e.getDMContext(), false);
|
||||
} else {
|
||||
// This will happen in non-stop mode
|
||||
// Keep target available for Container commands
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(ISuspendedDMEvent e) {
|
||||
if (e instanceof IContainerSuspendedDMEvent) {
|
||||
// This will happen in all-stop mode
|
||||
fContainerCommandCache.setContextAvailable(e.getDMContext(), true);
|
||||
fThreadCommandCache.setContextAvailable(e.getDMContext(), true);
|
||||
} else {
|
||||
// This will happen in non-stop mode
|
||||
}
|
||||
}
|
||||
|
||||
// Event handler when a thread or threadGroup starts
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(IStartedDMEvent e) {
|
||||
if (e instanceof ExecutionGroupStartedDMEvent) {
|
||||
fContainerCommandCache.reset();
|
||||
} else {
|
||||
// HACK figure out the thread and the group ids
|
||||
// I had to HACK GDB for this
|
||||
if (e instanceof IMIDMEvent) {
|
||||
String threadId = ((MIThreadCreatedEvent)((IMIDMEvent)e).getMIEvent()).getStrId();
|
||||
IContainerDMContext ctx = ((MIThreadCreatedEvent)((IMIDMEvent)e).getMIEvent()).getDMContext();
|
||||
if (ctx instanceof IMIExecutionGroupDMContext) {
|
||||
String groupId = ((IMIExecutionGroupDMContext)ctx).getGroupId();
|
||||
fGroupIdMap.put(threadId, groupId);
|
||||
}
|
||||
}
|
||||
// END HACK
|
||||
fThreadCommandCache.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Event handler when a thread or a threadGroup exits
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched(IExitedDMEvent e) {
|
||||
if (e instanceof ExecutionGroupExitedDMEvent) {
|
||||
fContainerCommandCache.reset();
|
||||
} else {
|
||||
// HACK figure out the thread and the group ids
|
||||
// I had to HACK GDB for this
|
||||
if (e instanceof IMIDMEvent) {
|
||||
String threadId = ((MIThreadCreatedEvent)((IMIDMEvent)e).getMIEvent()).getStrId();
|
||||
fGroupIdMap.remove(threadId);
|
||||
}
|
||||
// END HACK
|
||||
|
||||
fThreadCommandCache.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,12 +195,7 @@ public class MIRunControlEventProcessor
|
|||
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$
|
||||
} else if ("thread-group-created".equals(miEvent) || "thread-group-exited".equals(miEvent)) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
String groupId = null;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
package org.eclipse.dd.mi.service.command.commands;
|
||||
|
||||
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.dd.mi.service.command.MIControlDMContext;
|
||||
import org.eclipse.dd.mi.service.command.output.MIOutput;
|
||||
import org.eclipse.dd.mi.service.command.output.MIThreadInfoInfo;
|
||||
|
||||
|
@ -26,12 +26,12 @@ import org.eclipse.dd.mi.service.command.output.MIThreadInfoInfo;
|
|||
*/
|
||||
public class MIThreadInfo extends MICommand<MIThreadInfoInfo> {
|
||||
|
||||
public MIThreadInfo(IContainerDMContext dmc) {
|
||||
public MIThreadInfo(MIControlDMContext dmc) {
|
||||
super(dmc, "-thread-info"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public MIThreadInfo(IContainerDMContext dmc, int threadId) {
|
||||
super(dmc, "-thread-info", new String[]{ Integer.toString(threadId) }); //$NON-NLS-1$
|
||||
public MIThreadInfo(MIControlDMContext dmc, String threadId) {
|
||||
super(dmc, "-thread-info", new String[]{ threadId }); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* 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.output;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
public interface IThreadFrame {
|
||||
int getStackLevel();
|
||||
BigInteger getAddress();
|
||||
String getFucntion();
|
||||
Object[] getArgs();
|
||||
String getFileName();
|
||||
String getFullName();
|
||||
int getLineNumber();
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*******************************************************************************
|
||||
* 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.output;
|
||||
|
||||
|
||||
public interface IThreadInfo {
|
||||
String getThreadId();
|
||||
String getTargetId();
|
||||
String getOsId();
|
||||
IThreadFrame getTopFrame();
|
||||
String getDetails();
|
||||
String getState();
|
||||
}
|
|
@ -21,15 +21,15 @@ import org.eclipse.dd.dsf.concurrent.Immutable;
|
|||
*
|
||||
* The description field can be different depending on the target we are connected to.
|
||||
*
|
||||
* This output is from -list-thread-groups --available:
|
||||
* -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:
|
||||
* -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:
|
||||
* 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"}]
|
||||
*/
|
||||
|
@ -77,31 +77,9 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
|||
public String getDesciption() { return fDescription; }
|
||||
}
|
||||
|
||||
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;
|
||||
private IThreadGroupInfo[] fGroupList;
|
||||
private MIThreadInfoInfo fThreadInfo;
|
||||
|
||||
public MIListThreadGroupsInfo(MIOutput out) {
|
||||
super(out);
|
||||
|
@ -109,7 +87,7 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
|||
}
|
||||
|
||||
public IThreadGroupInfo[] getGroupList() { return fGroupList; }
|
||||
public IThreadInfo[] getThreadList() { return fThreadList; }
|
||||
public MIThreadInfoInfo getThreadInfo() { return fThreadInfo; }
|
||||
|
||||
private void parse() {
|
||||
if (isDone()) {
|
||||
|
@ -125,26 +103,23 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
|||
parseGroups((MIList)val);
|
||||
}
|
||||
} else if (var.equals("threads")) { //$NON-NLS-1$
|
||||
MIValue val = results[i].getMIValue();
|
||||
if (val instanceof MIList) {
|
||||
parseThreads((MIList)val);
|
||||
// Re-use the MIThreadInfoInfo parsing
|
||||
fThreadInfo = new MIThreadInfoInfo(out);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fGroupList == null) {
|
||||
fGroupList = new IThreadGroupInfo[0];
|
||||
}
|
||||
if (fThreadList == null) {
|
||||
fThreadList = new IThreadInfo[0];
|
||||
if (fThreadInfo == null) {
|
||||
fThreadInfo = new MIThreadInfoInfo(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseGroups(MIList list) {
|
||||
MIValue[] values = list.getMIValues();
|
||||
fGroupList = new ThreadGroupInfo[values.length];
|
||||
fGroupList = new IThreadGroupInfo[values.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
MIResult[] results = ((MITuple)values[i]).getMIResults();
|
||||
String id = "", desc = "";//$NON-NLS-1$//$NON-NLS-2$
|
||||
|
@ -169,40 +144,4 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
|||
fGroupList[i] = new ThreadGroupInfo(id, desc);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseThreads(MIList list) {
|
||||
MIValue[] values = list.getMIValues();
|
||||
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();
|
||||
if (var.equals("id")) { //$NON-NLS-1$
|
||||
MIValue value = result.getMIValue();
|
||||
if (value instanceof MIConst) {
|
||||
String str = ((MIConst)value).getCString();
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,10 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.mi.service.command.output;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* GDB/MI thread list parsing.
|
||||
*
|
||||
|
@ -28,14 +24,14 @@ import org.eclipse.dd.dsf.concurrent.Immutable;
|
|||
* {id="2",target-id="Thread 0xb7c8ab90 (LWP 7010)",
|
||||
* frame={level="0",addr="0x08048bba",func="my_func",args=[{name="arg",value="0xbff056f5"}],
|
||||
* file="my_test.cc",fullname="/home/francois/GDB/my_test.cc",line="26"},
|
||||
* running="0"},
|
||||
* state="stopped"},
|
||||
* {id="1",target-id="Thread 0xb7c8b8d0 (LWP 7007)",
|
||||
* frame={level="0",addr="0x08048a77",func="timer",args=[{name="duration",value="0xbff056f5 \"10\""}],
|
||||
* file="my_test.cc",fullname="/home/francois/GDB/my_test.cc",line="39"},
|
||||
* running="0"}
|
||||
* state="stopped"}
|
||||
* ],current-thread-id="2"
|
||||
*
|
||||
|
||||
*
|
||||
* Example 2:
|
||||
*
|
||||
* -thread-info 2
|
||||
|
@ -43,7 +39,7 @@ import org.eclipse.dd.dsf.concurrent.Immutable;
|
|||
* {id="2",target-id="Thread 0xb7c8ab90 (LWP 7010)",
|
||||
* frame={level="0",addr="0x08048bba",func="my_func",args=[{name="arg",value="0xbff056f5"}],
|
||||
* file="my_test.cc",fullname="/home/francois/GDB/my_test.cc",line="26"},
|
||||
* running="0"}
|
||||
* state="stopped"}
|
||||
* ]
|
||||
*
|
||||
*
|
||||
|
@ -51,92 +47,45 @@ import org.eclipse.dd.dsf.concurrent.Immutable;
|
|||
*
|
||||
* -thread-info
|
||||
* ^done,threads=[
|
||||
* {id="2",target-id="Thread 0xb7c8eb90 (LWP 7807)",running="1"},
|
||||
* {id="2",target-id="Thread 0xb7d6d6b0 (LWP 14494)",state="running"},
|
||||
* {id="1",target-id="Thread 0xb7c8b8d0 (LWP 7007)",
|
||||
* frame={level="0",addr="0x08048a77",func="timer",args=[{name="duration",value="0xbff056f5 \"10\""}],
|
||||
* file="my_test.cc",fullname="/home/francois/GDB/my_test.cc",line="39"},
|
||||
* running="0"}
|
||||
* state="stopped"}
|
||||
* ],current-thread-id="1"
|
||||
*
|
||||
*
|
||||
* Example 4 (non-stop):
|
||||
*
|
||||
* -thread-info 1
|
||||
* ^done,threads=[{id="1",target-id="Thread 0xb7d6d6b0 (LWP 14494)",state="running"}]
|
||||
*
|
||||
*
|
||||
* Example 5 (Dicos):
|
||||
*
|
||||
* -thread-info 1
|
||||
* ^done,threads=[
|
||||
* {id="1",target-id="Thread 162.32942",details="JUnitProcess_PT (Ready) 175417582794 8572423",
|
||||
* frame={level="0",addr="0x1559a318",func="mainExpressionTestApp",args=[],
|
||||
* file="/local/home/lmckhou/TSP/TADE/example/JUnitProcess_OU/src/ExpressionTestApp.cc",
|
||||
* fullname="/local/home/lmckhou/TSP/TADE/example/JUnitProcess_OU/src/ExpressionTestApp.cc",line="279"},
|
||||
* state="stopped"}]
|
||||
*/
|
||||
public class MIThreadInfoInfo extends MIInfo {
|
||||
|
||||
@Immutable
|
||||
public class ThreadInfo {
|
||||
|
||||
final private String fGdbId;
|
||||
final private String fTargetId;
|
||||
final private String fOsId;
|
||||
final private ThreadFrame fTopFrame;
|
||||
final private boolean fIsRunning;
|
||||
|
||||
public ThreadInfo(String gdbId, String targetId, String osId, ThreadFrame topFrame, boolean isRunning) {
|
||||
fGdbId = gdbId;
|
||||
fTargetId = targetId;
|
||||
fOsId = osId;
|
||||
fTopFrame = topFrame;
|
||||
fIsRunning = isRunning;
|
||||
}
|
||||
|
||||
public String getGdbId() { return fGdbId; }
|
||||
public String getTargetId() { return fTargetId; }
|
||||
public String getOsId() { return fOsId; }
|
||||
public ThreadFrame getTopFrame() { return fTopFrame; }
|
||||
public boolean isRunning() { return fIsRunning; }
|
||||
}
|
||||
|
||||
@Immutable
|
||||
public class ThreadFrame {
|
||||
final private int fStackLevel;
|
||||
final private BigInteger fAddress;
|
||||
final private String fFunction;
|
||||
final private ThreadFrameFunctionArgs[] fArgs;
|
||||
final private String fFileName;
|
||||
final private String fFullName;
|
||||
final private int fLineNumber;
|
||||
|
||||
public ThreadFrame(int stackLevel, BigInteger address, String function,
|
||||
ThreadFrameFunctionArgs[] args, String file, String fullName, int line)
|
||||
{
|
||||
fStackLevel = stackLevel;
|
||||
fAddress = address;
|
||||
fFunction = function;
|
||||
fArgs = args;
|
||||
fFileName = file;
|
||||
fFullName = fullName;
|
||||
fLineNumber = line;
|
||||
}
|
||||
|
||||
public int getStackLevel() { return fStackLevel; }
|
||||
public BigInteger getAddress() { return fAddress; }
|
||||
public String getFucntion() { return fFunction; }
|
||||
public ThreadFrameFunctionArgs[] getArgs() { return fArgs; }
|
||||
public String getFileName() { return fFileName; }
|
||||
public String getFullName() { return fFullName; }
|
||||
public int getLineNumber() { return fLineNumber; }
|
||||
}
|
||||
|
||||
@Immutable
|
||||
public class ThreadFrameFunctionArgs {
|
||||
}
|
||||
|
||||
private int fCurrentThread = -1;
|
||||
private List<ThreadInfo> fThreadInfoList = null;
|
||||
private int[] fThreadList = null;
|
||||
private String fCurrentThread = null;
|
||||
private IThreadInfo[] fThreadList = null;
|
||||
|
||||
public MIThreadInfoInfo(MIOutput out) {
|
||||
super(out);
|
||||
parse();
|
||||
}
|
||||
|
||||
public int getCurrentThread() {
|
||||
public String getCurrentThread() {
|
||||
return fCurrentThread;
|
||||
}
|
||||
|
||||
public List<ThreadInfo> getThreadInfoList() {
|
||||
return fThreadInfoList;
|
||||
}
|
||||
|
||||
public int[] getThreadList() {
|
||||
public IThreadInfo[] getThreadList() {
|
||||
return fThreadList;
|
||||
}
|
||||
|
||||
|
@ -159,40 +108,36 @@ public class MIThreadInfoInfo extends MIInfo {
|
|||
else if (var.equals("current-thread-id")) { //$NON-NLS-1$
|
||||
MIValue value = results[i].getMIValue();
|
||||
if (value instanceof MIConst) {
|
||||
String str = ((MIConst) value).getCString();
|
||||
try {
|
||||
fCurrentThread = Integer.parseInt(str.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
fCurrentThread = -1;
|
||||
fCurrentThread = ((MIConst) value).getCString().trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fThreadInfoList == null) {
|
||||
fThreadInfoList = new Vector<ThreadInfo>(0);
|
||||
fThreadList = new int[0];
|
||||
if (fThreadList == null) {
|
||||
fThreadList = new IThreadInfo[0];
|
||||
}
|
||||
}
|
||||
|
||||
// General formats:
|
||||
// id="n",target-id="Thread 0xb7c8ab90 (LWP 7010)",frame={...},running="0"
|
||||
// id="n",target-id="Thread 0xb7c8eb90 (LWP 7807)",running="1"
|
||||
// id="n",target-id="Thread 0xb7c8ab90 (LWP 7010)",frame={...},state="stopped"
|
||||
// id="n",target-id="Thread 0xb7c8eb90 (LWP 7807)",state="running"
|
||||
// id="n",target-id="Thread 162.32942",details="...",frame={...},state="stopped"
|
||||
private void parseThreads(MIList list) {
|
||||
MIValue[] values = list.getMIValues();
|
||||
fThreadInfoList = new Vector<ThreadInfo>(values.length);
|
||||
fThreadList = new int[values.length];
|
||||
fThreadList = new IThreadInfo[values.length];
|
||||
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
MITuple value = (MITuple) values[i];
|
||||
MIResult[] results = value.getMIResults();
|
||||
|
||||
String gdbId = null;
|
||||
String threadId = null;
|
||||
String targetId = null;
|
||||
String osId = null;
|
||||
String parentId = null;
|
||||
ThreadFrame topFrame = null;
|
||||
boolean isRunning = false;
|
||||
String state = null;
|
||||
String details = null;
|
||||
|
||||
for (int j = 0; j < results.length; j++) {
|
||||
MIResult result = results[j];
|
||||
|
@ -200,45 +145,68 @@ public class MIThreadInfoInfo extends MIInfo {
|
|||
if (var.equals("id")) { //$NON-NLS-1$
|
||||
MIValue val = results[j].getMIValue();
|
||||
if (val instanceof MIConst) {
|
||||
gdbId = ((MIConst) val).getCString();
|
||||
threadId = ((MIConst) val).getCString().trim();
|
||||
}
|
||||
}
|
||||
else if (var.equals("target-id")) { //$NON-NLS-1$
|
||||
MIValue val = results[j].getMIValue();
|
||||
if (val instanceof MIConst) {
|
||||
targetId = ((MIConst) val).getCString();
|
||||
targetId = ((MIConst) val).getCString().trim();
|
||||
osId = parseOsId(targetId);
|
||||
parentId = parseParentId(targetId);
|
||||
}
|
||||
}
|
||||
else if (var.equals("frame")) { //$NON-NLS-1$
|
||||
MIValue val = results[j].getMIValue();
|
||||
topFrame = parseFrame(val);
|
||||
}
|
||||
else if (var.equals("running")) { //$NON-NLS-1$
|
||||
else if (var.equals("state")) { //$NON-NLS-1$
|
||||
MIValue val = results[j].getMIValue();
|
||||
if (val instanceof MIConst) {
|
||||
String v = ((MIConst) val).getCString();
|
||||
isRunning = v.equals("1"); //$NON-NLS-1$
|
||||
state = ((MIConst) val).getCString().trim();
|
||||
}
|
||||
}
|
||||
else if (var.equals("details")) { //$NON-NLS-1$
|
||||
MIValue val = results[j].getMIValue();
|
||||
if (val instanceof MIConst) {
|
||||
details = ((MIConst) val).getCString().trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fThreadInfoList.add(new ThreadInfo(gdbId, targetId, osId, topFrame, isRunning));
|
||||
try {
|
||||
fThreadList[i] = Integer.parseInt(gdbId);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
fThreadList[i] = new ThreadInfo(threadId, targetId, osId, parentId, topFrame, details, state);
|
||||
}
|
||||
}
|
||||
|
||||
// General format:
|
||||
// "Thread 0xb7c8ab90 (LWP 7010)"
|
||||
// "Thread 162.32942"
|
||||
private String parseOsId(String str) {
|
||||
Pattern pattern = Pattern.compile("(Thread\\s*)(0x[0-9a-fA-F]+|-?\\d+)(\\s*\\(LWP\\s*)(\\d*)", 0); //$NON-NLS-1$
|
||||
Matcher matcher = pattern.matcher(str);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(4);
|
||||
}
|
||||
|
||||
pattern = Pattern.compile("Thread\\s*\\d+\\.(\\d+)", 0); //$NON-NLS-1$
|
||||
matcher = pattern.matcher(str);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// General format:
|
||||
// "Thread 0xb7c8ab90 (LWP 7010)"
|
||||
// "Thread 162.32942"
|
||||
private String parseParentId(String str) {
|
||||
Pattern pattern = Pattern.compile("Thread\\s*(\\d+)\\.\\d+", 0); //$NON-NLS-1$
|
||||
Matcher matcher = pattern.matcher(str);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*******************************************************************************
|
||||
* 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.output;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
public class ThreadFrame implements IThreadFrame {
|
||||
final private int fStackLevel;
|
||||
final private BigInteger fAddress;
|
||||
final private String fFunction;
|
||||
final private Object[] fArgs;
|
||||
final private String fFileName;
|
||||
final private String fFullName;
|
||||
final private int fLineNumber;
|
||||
|
||||
public ThreadFrame(int stackLevel, BigInteger address, String function,
|
||||
Object[] args, String file, String fullName, int line)
|
||||
{
|
||||
fStackLevel = stackLevel;
|
||||
fAddress = address;
|
||||
fFunction = function;
|
||||
fArgs = args;
|
||||
fFileName = file;
|
||||
fFullName = fullName;
|
||||
fLineNumber = line;
|
||||
}
|
||||
|
||||
public int getStackLevel() { return fStackLevel; }
|
||||
public BigInteger getAddress() { return fAddress; }
|
||||
public String getFucntion() { return fFunction; }
|
||||
public Object[] getArgs() { return fArgs; }
|
||||
public String getFileName() { return fFileName; }
|
||||
public String getFullName() { return fFullName; }
|
||||
public int getLineNumber() { return fLineNumber; }
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*******************************************************************************
|
||||
* 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.output;
|
||||
|
||||
import org.eclipse.dd.dsf.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
public class ThreadInfo implements IThreadInfo {
|
||||
|
||||
final private String fThreadId;
|
||||
final private String fTargetId;
|
||||
final private String fOsId;
|
||||
final private String fParentId;
|
||||
final private IThreadFrame fTopFrame;
|
||||
final private String fDetails;
|
||||
final private String fState;
|
||||
|
||||
public ThreadInfo(String threadId, String targetId, String osId, String parentId,
|
||||
IThreadFrame topFrame, String details, String state) {
|
||||
fThreadId = threadId;
|
||||
fTargetId = targetId;
|
||||
fOsId = osId;
|
||||
fParentId = parentId;
|
||||
fTopFrame = topFrame;
|
||||
fDetails = details;
|
||||
fState = state;
|
||||
}
|
||||
|
||||
public String getThreadId() { return fThreadId; }
|
||||
public String getTargetId() { return fTargetId; }
|
||||
public String getOsId() { return fOsId; }
|
||||
public String getParentId() { return fParentId; }
|
||||
public IThreadFrame getTopFrame() { return fTopFrame; }
|
||||
public String getDetails() { return fDetails; }
|
||||
public String getState() { return fState; }
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue