From eeb6b080ef2a6e203de13f4e917428d5ab17750b Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Mon, 11 Aug 2008 13:02:51 +0000 Subject: [PATCH] Bug 240507 Fix the cache for the GDBMultiProcesses service. Also clean up the use of thread-info --- .../service/GDBMultiProcesses.java | 166 ++++++++++++----- .../command/MIRunControlEventProcessor.java | 7 +- .../command/commands/MIThreadInfo.java | 8 +- .../service/command/output/IThreadFrame.java | 23 +++ .../service/command/output/IThreadInfo.java | 21 +++ .../output/MIListThreadGroupsInfo.java | 83 ++------- .../command/output/MIThreadInfoInfo.java | 176 +++++++----------- .../service/command/output/ThreadFrame.java | 46 +++++ .../mi/service/command/output/ThreadInfo.java | 48 +++++ 9 files changed, 342 insertions(+), 236 deletions(-) create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/IThreadFrame.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/IThreadInfo.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ThreadFrame.java create mode 100644 plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ThreadInfo.java diff --git a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBMultiProcesses.java b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBMultiProcesses.java index 44104943eda..c3fc13eaeb2 100644 --- a/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBMultiProcesses.java +++ b/plugins/org.eclipse.dd.gdb/src/org/eclipse/dd/gdb/internal/provisional/service/GDBMultiProcesses.java @@ -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 fProcessNames = new HashMap(); @@ -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,21 +445,21 @@ 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(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(); - } + fThreadCommandCache.execute(new MIThreadInfo(controlDmc, threadDmc.getId()), + new DataRequestMonitor(getExecutor(), rm) { + @Override + protected void handleSuccess() { + IThreadDMData threadData = new MIThreadDMData("", ""); //$NON-NLS-1$ //$NON-NLS-2$ + if (getData().getThreadList().length != 0) { + IThreadInfo thread = getData().getThreadList()[0]; + if (thread.getThreadId().equals(threadDmc.getId())) { + threadData = new MIThreadDMData("", thread.getOsId()); //$NON-NLS-1$ + } + } + + rm.setData(threadData); + rm.done(); + } }); } else { rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$ @@ -454,9 +468,19 @@ public class GDBMultiProcesses extends AbstractDsfService implements IMIProcesse } public void getDebuggingContext(IThreadDMContext dmc, DataRequestMonitor rm) { - rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, - NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$ - rm.done(); + 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(); } public void isDebuggerAttachSupported(IDMContext dmc, DataRequestMonitor rm) { @@ -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(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(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(getExecutor(), rm) { @Override @@ -655,31 +680,9 @@ 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) { @@ -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(); + } + } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java index 1f3c1b5b745..0f401a4fd38 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/MIRunControlEventProcessor.java @@ -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; diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java index b728da7a04a..7705343bdf4 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/commands/MIThreadInfo.java @@ -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 { - 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 diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/IThreadFrame.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/IThreadFrame.java new file mode 100644 index 00000000000..da42815dbab --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/IThreadFrame.java @@ -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(); +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/IThreadInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/IThreadInfo.java new file mode 100644 index 00000000000..7ac271b37c4 --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/IThreadInfo.java @@ -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(); +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIListThreadGroupsInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIListThreadGroupsInfo.java index 9d82582309b..1cb81445d4f 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIListThreadGroupsInfo.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIListThreadGroupsInfo.java @@ -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); - - } - } } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java index ef2b377eecf..62772c7cf81 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/MIThreadInfoInfo.java @@ -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 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 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(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(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; } diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ThreadFrame.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ThreadFrame.java new file mode 100644 index 00000000000..964b373fe9a --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ThreadFrame.java @@ -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; } +} diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ThreadInfo.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ThreadInfo.java new file mode 100644 index 00000000000..1d0d3ce018e --- /dev/null +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/command/output/ThreadInfo.java @@ -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; } + + + + +}