Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Khouzam2011-07-29 19:43:34 +0000
committerMarc Khouzam2011-07-29 19:43:34 +0000
commitd2c51aec89dfaf71d8f4f0ff41c162861f8dc9af (patch)
treeb4a7c5a76ce4e9fa2852b1b1cd699546398af172
parent2810a4ed7628831e18cfee1d0263a581b0e848ba (diff)
downloadorg.eclipse.cdt-d2c51aec89dfaf71d8f4f0ff41c162861f8dc9af.tar.gz
org.eclipse.cdt-d2c51aec89dfaf71d8f4f0ff41c162861f8dc9af.tar.xz
org.eclipse.cdt-d2c51aec89dfaf71d8f4f0ff41c162861f8dc9af.zip
Bug 353423: Need a way to refresh the thread list and state in the run control service
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0_NS.java30
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_2_NS.java68
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java5
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIListThreadGroups.java35
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIListThreadGroupsInfo.java41
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIThread.java5
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIThreadInfoInfo.java9
7 files changed, 166 insertions, 27 deletions
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0_NS.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0_NS.java
index 40b96c68b6c..611d5a5388f 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0_NS.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_0_NS.java
@@ -222,20 +222,22 @@ public class GDBRunControl_7_0_NS extends AbstractDsfService implements IMIRunCo
}
public StateChangeReason getReason() {
- switch(getMIEvent().getType()) {
- case MIRunningEvent.CONTINUE:
- return StateChangeReason.USER_REQUEST;
- case MIRunningEvent.NEXT:
- case MIRunningEvent.NEXTI:
- return StateChangeReason.STEP;
- case MIRunningEvent.STEP:
- case MIRunningEvent.STEPI:
- return StateChangeReason.STEP;
- case MIRunningEvent.FINISH:
- return StateChangeReason.STEP;
- case MIRunningEvent.UNTIL:
- case MIRunningEvent.RETURN:
- break;
+ if (getMIEvent() != null) {
+ switch(getMIEvent().getType()) {
+ case MIRunningEvent.CONTINUE:
+ return StateChangeReason.USER_REQUEST;
+ case MIRunningEvent.NEXT:
+ case MIRunningEvent.NEXTI:
+ return StateChangeReason.STEP;
+ case MIRunningEvent.STEP:
+ case MIRunningEvent.STEPI:
+ return StateChangeReason.STEP;
+ case MIRunningEvent.FINISH:
+ return StateChangeReason.STEP;
+ case MIRunningEvent.UNTIL:
+ case MIRunningEvent.RETURN:
+ break;
+ }
}
return StateChangeReason.UNKNOWN;
}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_2_NS.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_2_NS.java
index 1b668fef050..a33a9221e10 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_2_NS.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRunControl_7_2_NS.java
@@ -17,6 +17,9 @@ import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
+import org.eclipse.cdt.dsf.datamodel.IDMContext;
+import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
+import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IRunControl2;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
@@ -27,6 +30,10 @@ import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIRunControl;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
+import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo;
+import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo.IThreadGroupInfo;
+import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo.IThreadGroupInfo2;
+import org.eclipse.cdt.dsf.mi.service.command.output.MIThread;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
@@ -41,6 +48,7 @@ public class GDBRunControl_7_2_NS extends GDBRunControl_7_0_NS
private ICommandControlService fConnection;
private CommandFactory fCommandFactory;
+ private IGDBProcesses fProcService;
///////////////////////////////////////////////////////////////////////////
// Initialization and shutdown
@@ -70,6 +78,7 @@ public class GDBRunControl_7_2_NS extends GDBRunControl_7_0_NS
new Hashtable<String,String>());
fConnection = getServicesTracker().getService(ICommandControlService.class);
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
+ fProcService = getServicesTracker().getService(IGDBProcesses.class);
getSession().addServiceEventListener(this, null);
rm.done();
}
@@ -169,4 +178,63 @@ public class GDBRunControl_7_2_NS extends GDBRunControl_7_0_NS
private void doResumeContainer(IMIContainerDMContext context, final RequestMonitor rm) {
fConnection.queueCommand(fCommandFactory.createMIExecContinue(context), new DataRequestMonitor<MIInfo>(getExecutor(), rm));
}
+
+
+ /**
+ * @since 4.1
+ */
+ protected void refreshThreads() {
+ fConnection.queueCommand(
+ fCommandFactory.createMIListThreadGroups(fConnection.getContext(), false, true),
+ new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), null) {
+ @Override
+ protected void handleSuccess() {
+ IThreadGroupInfo[] groups = getData().getGroupList();
+ for (IThreadGroupInfo group : groups) {
+ if (group instanceof IThreadGroupInfo2) {
+ MIThread[] threadList = ((IThreadGroupInfo2)group).getThreads();
+ for (MIThread thread : threadList) {
+ String threadId = thread.getThreadId();
+ IMIContainerDMContext containerDmc =
+ fProcService.createContainerContextFromThreadId(fConnection.getContext(), threadId);
+ IProcessDMContext processDmc = DMContexts.getAncestorOfType(containerDmc, IProcessDMContext.class);
+ IThreadDMContext threadDmc =
+ fProcService.createThreadContext(processDmc, threadId);
+ IMIExecutionDMContext execDmc = fProcService.createExecutionContext(containerDmc, threadDmc, threadId);
+
+ MIThreadRunState threadState = fThreadRunStates.get(execDmc);
+ if (threadState != null) {
+ // We may not know this thread. This can happen when dealing with a remote
+ // where thread events are not reported immediately.
+ // However, the -list-thread-groups command we just sent will make
+ // GDB send those events. Therefore, we can just ignore threads we don't
+ // know about, and wait for those events.
+ if (MIThread.MI_THREAD_STATE_RUNNING.equals(thread.getState())) {
+ if (threadState.fSuspended == true) {
+ // We missed a resumed event! Send it now.
+ IResumedDMEvent resumedEvent = new ResumedEvent(execDmc, null);
+ fConnection.getSession().dispatchEvent(resumedEvent, getProperties());
+ }
+ } else if (MIThread.MI_THREAD_STATE_STOPPED.equals(thread.getState())) {
+ if (threadState.fSuspended == false) {
+ // We missed a suspend event! Send it now.
+ ISuspendedDMEvent suspendedEvent = new SuspendedEvent(execDmc, null);
+ fConnection.getSession().dispatchEvent(suspendedEvent, getProperties());
+ }
+ } else {
+ assert false : "Invalid thread state: " + thread.getState(); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public void flushCache(IDMContext context) {
+ super.flushCache(context);
+ refreshThreads();
+ }
}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java
index 0f11dfe4c6b..cc7d731c265 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/CommandFactory.java
@@ -677,6 +677,11 @@ public class CommandFactory {
return new MIListThreadGroups(ctx, listAll);
}
+ /** @since 4.1 */
+ public ICommand<MIListThreadGroupsInfo> createMIListThreadGroups(ICommandControlDMContext ctx, boolean listAll, boolean recurse) {
+ return new MIListThreadGroups(ctx, listAll, recurse);
+ }
+
/** @since 4.0 */
public ICommand<MIInfo> createMIRemoveInferior(ICommandControlDMContext ctx, String groupId) {
return new MIRemoveInferior(ctx, groupId);
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIListThreadGroups.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIListThreadGroups.java
index d08be578832..3a4aa19587b 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIListThreadGroups.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIListThreadGroups.java
@@ -67,24 +67,42 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
*/
public class MIListThreadGroups extends MICommand<MIListThreadGroupsInfo> {
- // List all groups being debugged
+ /**
+ * List all groups (processes) being debugged.
+ */
public MIListThreadGroups(ICommandControlDMContext ctx) {
this(ctx, false);
}
- // List all groups or threads being debugged which are children of the specified group
+ /**
+ * If the parameter groupId is null, list all groups (processes) being debugged.
+ * If the parameter groupId is a valid group, list all threads
+ * which are children of the specified group
+ */
public MIListThreadGroups(ICommandControlDMContext ctx, String groupId) {
- this(ctx, groupId, false);
+ this(ctx, groupId, false, false);
}
- // List all groups available on the target
+ /**
+ * If the parameter listAll is true, list all processes running on the
+ * target (not just the debugged ones).
+ * If the parameter listAll is false, list only the processes being debugged.
+ */
public MIListThreadGroups(ICommandControlDMContext ctx, boolean listAll) {
- this(ctx, null, listAll);
+ this(ctx, null, listAll, false);
}
+ /**
+ * If the parameter recurse is true, list all threads of all processes.
+ * @since 4.1
+ */
+ public MIListThreadGroups(ICommandControlDMContext ctx, boolean listAll, boolean recurse) {
+ this(ctx, null, listAll, recurse);
+ }
+
// There should be no reason to have both listAll and groupId specified,
// so this constructor is private, and exists to avoid duplicating code.
- private MIListThreadGroups(ICommandControlDMContext ctx, String groupId, boolean listAll) {
+ private MIListThreadGroups(ICommandControlDMContext ctx, String groupId, boolean listAll, boolean recurse) {
super(ctx, "-list-thread-groups"); //$NON-NLS-1$
assert !((groupId != null) && listAll); // see comment above
@@ -94,6 +112,11 @@ public class MIListThreadGroups extends MICommand<MIListThreadGroupsInfo> {
arguments.add("--available"); //$NON-NLS-1$
}
+ if (recurse) {
+ arguments.add("--recurse"); //$NON-NLS-1$
+ arguments.add("1"); //$NON-NLS-1$
+ }
+
if (groupId != null) {
assert groupId.trim().length() > 0;
arguments.add(groupId);
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIListThreadGroupsInfo.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIListThreadGroupsInfo.java
index 1385333e21f..d8269b22f7d 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIListThreadGroupsInfo.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIListThreadGroupsInfo.java
@@ -131,6 +131,21 @@ import org.eclipse.cdt.dsf.concurrent.Immutable;
* -list-thread-groups --available
* ^done,groups=[{id="19418",type="process",description="gdb.7.1 -i mi testing/a.out",user="lmckhou"},{id="19424",type="process",description="/local/lmckhou/testing/a.out",user="lmckhou"},{id="19438",type="process",description="sleep 5",user="lmckhou"}]
*
+ * -list-thread-groups --recurse 1
+ * ^done,groups=[{id="i2",type="process",pid="11805",executable="/home/lmckhou/Consumer",cores=["0","1"],
+ * threads=[{id="6",target-id="Thread 0xb6516b70 (LWP 11811)",state="running",core="1"},
+ * {id="5",target-id="Thread 0xb6d17b70 (LWP 11810)",state="running",core="1"},
+ * {id="4",target-id="Thread 0xb7518b70 (LWP 11809)",
+ * frame={level="0",addr="0x0804850d",func="main",args=[],file="Consumer.cc",fullname="/home/lmckhou/Consumer.cc",line="5"},
+ * state="stopped",core="0"},
+ * {id="3",target-id="Thread 0xb7d19b70 (LWP 11808)",state="running",core="1"},
+ * {id="2",target-id="Thread 0xb7d1bb30 (LWP 11805)",state="running",core="0"}]},
+ * {id="i1",type="process",pid="11793",executable="/home/lmckhProducer",cores=["0","1"],
+ * threads=[{id="10",target-id="Thread 0xb6516b70 (LWP 11815)",state="running",core="0"},
+ * {id="8",target-id="Thread 0xb7518b70 (LWP 11813)",state="running",core="0"},
+ * {id="7",target-id="Thread 0xb7d19b70 (LWP 11812)",state="running",core="1"},
+ * {id="1",target-id="Thread 0xb7d1bb30 (LWP 11793)",state="running",core="1"}]}]
+ *
* GDB 7.2
*
* (when no inferior is running)
@@ -171,8 +186,15 @@ public class MIListThreadGroupsInfo extends MIInfo {
String getExecutable();
}
+ /**
+ * @since 4.1
+ */
+ public interface IThreadGroupInfo2 extends IThreadGroupInfo {
+ MIThread[] getThreads();
+ }
+
@Immutable
- private static class ThreadGroupInfo implements IThreadGroupInfo {
+ private static class ThreadGroupInfo implements IThreadGroupInfo2 {
final String fGroupId;
final String fDescription;
final String fName;
@@ -181,9 +203,10 @@ public class MIListThreadGroupsInfo extends MIInfo {
final String fPid;
final String[] fCores;
final String fExecutable;
+ final MIThread[] fThreadList;
public ThreadGroupInfo(String id, String description, String type, String pid,
- String user, String[] cores, String exec) {
+ String user, String[] cores, String exec, MIThread[] threads) {
fGroupId = id;
fDescription = description;
fType = type;
@@ -194,6 +217,8 @@ public class MIListThreadGroupsInfo extends MIInfo {
fExecutable = exec;
fName = parseName(fDescription);
+
+ fThreadList = threads;
}
private static String parseName(String desc) {
@@ -225,6 +250,8 @@ public class MIListThreadGroupsInfo extends MIInfo {
public String getType() { return fType; }
public String getExecutable() { return fExecutable; }
+
+ public MIThread[] getThreads() { return fThreadList; }
}
@@ -274,6 +301,7 @@ public class MIListThreadGroupsInfo extends MIInfo {
MIResult[] results = ((MITuple)values[i]).getMIResults();
String id, desc, type, pid, exec, user;
id = desc = type = pid = exec = user = "";//$NON-NLS-1$
+ MIThread[] threads = null;
String[] cores = null;
@@ -322,6 +350,13 @@ public class MIListThreadGroupsInfo extends MIInfo {
String str = ((MIConst)value).getCString();
exec = str.trim();
}
+ } else if (var.equals("threads")) { //$NON-NLS-1$
+ // Staring with GDB 7.1
+ // Re-use the MIThreadInfoInfo parsing
+ MIValue value = result.getMIValue();
+ if (value instanceof MIList) {
+ threads = MIThreadInfoInfo.parseThreads(((MIList)value));
+ }
}
}
// In the case of -list-thread-groups --available, the pid field is not present, but the
@@ -332,7 +367,7 @@ public class MIListThreadGroupsInfo extends MIInfo {
if (pid.equals("") && !desc.equals("")) { //$NON-NLS-1$ //$NON-NLS-2$
pid = id;
}
- fGroupList[i] = new ThreadGroupInfo(id, desc, type, pid, user, cores, exec);
+ fGroupList[i] = new ThreadGroupInfo(id, desc, type, pid, user, cores, exec, threads);
}
}
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIThread.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIThread.java
index 679ee148d95..f718950a327 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIThread.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIThread.java
@@ -25,6 +25,11 @@ import org.eclipse.cdt.dsf.concurrent.Immutable;
@Immutable
public class MIThread {
+ /** @since 4.1 */
+ public final static String MI_THREAD_STATE_RUNNING = "running"; //$NON-NLS-1$
+ /** @since 4.1 */
+ public final static String MI_THREAD_STATE_STOPPED = "stopped"; //$NON-NLS-1$
+
final private String fThreadId;
final private String fTargetId;
final private String fOsId;
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIThreadInfoInfo.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIThreadInfoInfo.java
index 9163acd275e..788291998b3 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIThreadInfoInfo.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIThreadInfoInfo.java
@@ -115,7 +115,7 @@ public class MIThreadInfoInfo extends MIInfo {
if (var.equals("threads")) { //$NON-NLS-1$
MIValue val = results[i].getMIValue();
if (val instanceof MIList) {
- parseThreads((MIList) val);
+ fThreadList = parseThreads((MIList) val);
}
}
else if (var.equals("current-thread-id")) { //$NON-NLS-1$
@@ -136,13 +136,14 @@ public class MIThreadInfoInfo extends MIInfo {
// 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) {
+ static MIThread[] parseThreads(MIList list) {
MIValue[] values = list.getMIValues();
- fThreadList = new MIThread[values.length];
+ MIThread[] threadList = new MIThread[values.length];
for (int i = 0; i < values.length; i++) {
- fThreadList[i] = MIThread.parse((MITuple) values[i]);
+ threadList[i] = MIThread.parse((MITuple) values[i]);
}
+ return threadList;
}
}

Back to the top