1
0
Fork 0
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:
Marc Khouzam 2008-08-11 13:02:51 +00:00
parent 1fbfd51fac
commit eeb6b080ef
9 changed files with 342 additions and 236 deletions

View file

@ -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();
}
}
}

View file

@ -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;

View file

@ -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

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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);
}
}
}

View file

@ -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;
}

View file

@ -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; }
}

View file

@ -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; }
}