1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 08:55:25 +02:00

Bug 318230: Add infrastructure to read the new core field from the

-list-thread-groups and -thread-info commands
This commit is contained in:
Marc Khouzam 2010-06-28 19:38:26 +00:00
parent ef6d28343d
commit f4953626d5
4 changed files with 250 additions and 15 deletions

View file

@ -17,7 +17,7 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
/**
* -list-thread-groups [--available | GROUP]
* -list-thread-groups [--available | GROUP] [ --recurse 1 ]
*
* When used without GROUP parameter, this will list top-level
* thread groups that are being debugged. When used with the GROUP
@ -37,9 +37,31 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
*
* where each thread group is like this:
*
* {id="xxx",type="process",pid="yyy",num_children="1"}
* {id="xxx",type="process",pid="yyy",num_children="1",cores=[1,2]}
*
* The id of a thread group should be considered an opaque string.
*
* As of GDB 7.1, the --recurse option has been added. If this option is
* present, then every reported thread group will also include its children,
* either as `group' or `threads' field.
*
* In general, any combination of option and parameters is permitted, with
* the following caveats:
* - When a single thread group is passed, the output will typically be the
* `threads' result. Because threads may not contain anything, the
* `recurse' option will be ignored.
* - When the `--available' option is passed, limited information may be
* available. In particular, the list of threads of a process might be
* inaccessible. Further, specifying specific thread groups might not give
* any performance advantage over listing all thread groups. The frontend
* should assume that `-list-thread-groups --available' is always an
* expensive operation and cache the results.
*
* As of GDB 7.1, the 'core' output field has been added.
* - cores This field is a list of integers, each identifying a core that one
* thread of the group is running on. This field may be absent if such
* information is not available.
*
* @since 1.1
*
*/

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Ericsson and others.
* Copyright (c) 2008, 2010 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
@ -11,6 +11,8 @@
package org.eclipse.cdt.dsf.mi.service.command.output;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -28,14 +30,126 @@ import org.eclipse.cdt.dsf.concurrent.Immutable;
* {id="166",type="process",description="name: JUnitProcess_PT, type 1094605, locked: N, system: N, state: Idle"}]
*
* {id="3602",type="process",description="/usr/sbin/dhcdbd --system",user="root"}
*
* -list-thread-groups:
* ^done,groups=[{id="162",type="process",pid="162"}]
*
* 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"}]
*
* As of GDB 7.1, a new 'core' output field has been added. This field is a list
* of integers, each identifying a core that one thread of the group is running on.
* This field may be absent if such information is not available.
*
* -list-thread-groups
* ^done,groups=[{id="12779",type="process",pid="12779",cores=["3"]}]
*
* -list-thread-groups 12779
* ^done,threads=[{id="10",
* target-id="Thread 0xb3d58ba0 (LWP 12876)",
* frame={level="0",addr="0xb7e21b88",func="clone",args=[],from="/lib/libc.so.6"},
* state="stopped",
* core="3"},
* {id="3",
* target-id="Thread 0xb755fba0 (LWP 12811)",
* frame={level="0",addr="0xffffe410",func="__kernel_vsyscall",args=[]},
* state="stopped",
* core="3"},
* {id="2",
* target-id="Thread 0xb7d60ba0 (LWP 12810)",
* frame={level="0",addr="0xffffe410",func="__kernel_vsyscall",args=[]},
* state="stopped",
* core="3"},
* {id="1",
* target-id="Thread 0xb7d616b0 (LWP 12779)",
* frame={level="0",addr="0x08048609",func="main",args=[],file="../src/NonStop.cpp",fullname="/local/runtime-TestDSF/NonStop/src/NonStop.cpp",line="44"},
* state="stopped",
* core="3"}]
*
* As of GDB 7.1, the --recurse option has been added and causes a different output
*
* -list-thread-groups --recurse 1
* ^done,groups=[{id="12779",
* type="process",
* pid="12779",
* cores=["3"],
* threads=[{id="10",
* target-id="Thread 0xb3d58ba0 (LWP 12876)",
* frame={level="0",addr="0xb7e21b88",func="clone",args=[],from="/lib/libc.so.6"},
* state="stopped",
* core="3"},
* {id="3",
* target-id="Thread 0xb755fba0 (LWP 12811)",
* frame={level="0",addr="0xffffe410",func="__kernel_vsyscall",args=[]},
* state="stopped",
* core="3"},
* {id="2",
* target-id="Thread 0xb7d60ba0 (LWP 12810)",
* frame={level="0",addr="0xffffe410",func="__kernel_vsyscall",args=[]},
* state="stopped",
* core="3"},
* {id="1",
* target-id="Thread 0xb7d616b0 (LWP 12779)",
* frame={level="0",addr="0x08048609",func="main",args=[],file="../src/NonStop.cpp",fullname="/local/runtime-TestDSF/NonStop/src/NonStop.cpp",line="44"},
* state="stopped",
* core="3"}
* ]
* }]
*
* Example of outputs by version on Linux
*
* GDB 7.0
*
* (when no inferior is running)
* -list-thread-groups
* ^done,groups=[]
*
* (with an inferior running)
* -list-thread-groups
* ^done,groups=[{id="19386",type="process",pid="19386"}]
*
* -list-thread-groups 19386
* ^done,threads=[{id="1",target-id="process 19386",frame={level="0",addr="0x08048618",func="main",args=[],file="a.cc",fullname="/local/lmckhou/testing/a.cc",line="9"},state="stopped"}]
*
* -list-thread-groups --available
* ^done,groups=[{id="19371",type="process",description="gdb.7.0 -i mi testing/a.out",user="lmckhou"},{id="19386",type="process",description="/local/lmckhou/testing/a.out",user="lmckhou"},{id="19413",type="process",description="sleep 5",user="lmckhou"}]
*
* GDB 7.1
*
* (when no inferior is running)
* -list-thread-groups
* ^done,groups=[{id="0",type="process",pid="0"}]
*
* (with an inferior running)
* -list-thread-groups
* ^done,groups=[{id="19424",type="process",pid="19424",cores=["3"]}]
*
* -list-thread-groups 19424
* ^done,threads=[{id="1",target-id="process 19424",frame={level="0",addr="0x08048618",func="main",args=[],file="a.cc",fullname="/local/lmckhou/testing/a.cc",line="9"},state="stopped",core="3"}]
*
* -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"}]
*
* GDB 7.2
*
* (when no inferior is running)
* -list-thread-groups
* ^done,groups=[{id="i1",type="process",executable="/local/lmckhou/testing/a.out"}]
*
* (with an inferior running)
* -list-thread-groups
* ^done,groups=[{id="i1",type="process",pid="19451",executable="/local/lmckhou/testing/a.out",cores=["2"]}]
*
* -list-thread-groups i1
* ^done,threads=[{id="1",target-id="process 19451",frame={level="0",addr="0x08048618",func="main",args=[],file="a.cc",fullname="/local/lmckhou/testing/a.cc",line="9"},state="stopped",core="2"}]
*
* -list-thread-groups --available
* ^done,groups=[{id="19445",type="process",description="gdb.7.2 -i mi testing/a.out",user="lmckhou"},{id="19451",type="process",description="/local/lmckhou/testing/a.out",user="lmckhou"},{id="19462",type="process",description="sleep 5",user="lmckhou"}]
*
* @since 1.1
*/
public class MIListThreadGroupsInfo extends MIInfo {
public interface IThreadGroupInfo {
@ -50,11 +164,23 @@ public class MIListThreadGroupsInfo extends MIInfo {
final String fGroupId;
final String fDescription;
final String fName;
final String fType;
final String fUser;
final String fPid;
final String[] fCores;
final String fExecutable;
public ThreadGroupInfo(String id, String description) {
public ThreadGroupInfo(String id, String description, String type, String pid,
String user, String[] cores, String exec) {
fGroupId = id;
fDescription = description;
fType = type;
fUser = user;
fPid = pid;
fCores = cores;
fExecutable = exec;
fName = parseName(fDescription);
}
@ -77,11 +203,22 @@ public class MIListThreadGroupsInfo extends MIInfo {
}
public String getGroupId() { return fGroupId; }
public String getPid() { return fGroupId; }
public String getPid() { return fPid; }
public String getName() { return fName; }
public String getDesciption() { return fDescription; }
// The following are not used yet, but it's good to keep
// them as a way to document what is available from GDB.
@SuppressWarnings("unused")
public String getType() { return fType; }
@SuppressWarnings("unused")
public String getUser() { return fUser; }
@SuppressWarnings("unused")
public String[] getCores() { return fCores; }
@SuppressWarnings("unused")
public String getExecutable() { return fExecutable; }
}
@ -129,7 +266,10 @@ public class MIListThreadGroupsInfo extends MIInfo {
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$
String id, desc, type, pid, exec, user;
id = desc = type = pid = exec = user = "";//$NON-NLS-1$
String[] cores = null;
for (MIResult result : results) {
String var = result.getVariable();
@ -144,11 +284,57 @@ public class MIListThreadGroupsInfo extends MIInfo {
if (value instanceof MIConst) {
String str = ((MIConst)value).getCString();
desc = str.trim();
}
} else if (var.equals("type")) { //$NON-NLS-1$
MIValue value = result.getMIValue();
if (value instanceof MIConst) {
String str = ((MIConst)value).getCString();
type = str.trim();
}
} else if (var.equals("pid")) { //$NON-NLS-1$
MIValue value = result.getMIValue();
if (value instanceof MIConst) {
String str = ((MIConst)value).getCString();
pid = str.trim();
}
} else if (var.equals("user")) { //$NON-NLS-1$
MIValue value = result.getMIValue();
if (value instanceof MIConst) {
String str = ((MIConst)value).getCString();
user = str.trim();
}
} else if (var.equals("cores")) { //$NON-NLS-1$
// Staring with GDB 7.1
MIValue value = result.getMIValue();
if (value instanceof MIList) {
cores = parseCores((MIList)value);
}
} else if (var.equals("executable")) { //$NON-NLS-1$
// Staring with GDB 7.2
MIValue value = result.getMIValue();
if (value instanceof MIConst) {
String str = ((MIConst)value).getCString();
exec = str.trim();
}
}
}
fGroupList[i] = new ThreadGroupInfo(id, desc);
// In the case of -list-thread-groups --available, we can use the id as the pid
if (pid.equals("")) { //$NON-NLS-1$
pid = id;
}
fGroupList[i] = new ThreadGroupInfo(id, desc, type, pid, user, cores, exec);
}
}
private String[] parseCores(MIList list) {
List<String> cores = new ArrayList<String>();
MIValue[] values = list.getMIValues();
for (int i = 0; i < values.length; i++) {
if (values[i] instanceof MIConst) {
cores.add(((MIConst)values[i]).getCString());
}
}
return cores.toArray(new String[cores.size()]);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Ericsson and others.
* Copyright (c) 2008, 2010 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
@ -28,12 +28,13 @@ public class MIThread {
final private String fTargetId;
final private String fOsId;
final private String fParentId;
final private MIFrame fTopFrame;
final private MIFrame fTopFrame;
final private String fDetails;
final private String fState;
final private String fCore;
private MIThread(String threadId, String targetId, String osId, String parentId,
MIFrame topFrame, String details, String state) {
MIFrame topFrame, String details, String state, String core) {
fThreadId = threadId;
fTargetId = targetId;
fOsId = osId;
@ -41,6 +42,7 @@ public class MIThread {
fTopFrame = topFrame;
fDetails = details;
fState = state;
fCore = core;
}
public String getThreadId() { return fThreadId; }
@ -50,6 +52,11 @@ public class MIThread {
public MIFrame getTopFrame() { return fTopFrame; }
public String getDetails() { return fDetails; }
public String getState() { return fState; }
/**
* Available since GDB 7.1
* @since 3.1
*/
public String getCore() { return fCore; }
public static MIThread parse(MITuple tuple) {
MIResult[] results = tuple.getMIResults();
@ -61,6 +68,7 @@ public class MIThread {
MIFrame topFrame = null;
String state = null;
String details = null;
String core = null;
for (int j = 0; j < results.length; j++) {
MIResult result = results[j];
@ -95,9 +103,15 @@ public class MIThread {
details = ((MIConst) val).getCString().trim();
}
}
else if (var.equals("core")) { //$NON-NLS-1$
MIValue val = results[j].getMIValue();
if (val instanceof MIConst) {
core = ((MIConst) val).getCString().trim();
}
}
}
return new MIThread(threadId, targetId, osId, parentId, topFrame, details, state);
return new MIThread(threadId, targetId, osId, parentId, topFrame, details, state, core);
}
private static Pattern fgOsIdPattern1 = Pattern.compile("(Thread\\s*)(0x[0-9a-fA-F]+|-?\\d+)(\\s*\\(LWP\\s*)(\\d*)", 0); //$NON-NLS-1$

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 Ericsson and others.
* Copyright (c) 2008, 2010 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
@ -69,6 +69,19 @@ package org.eclipse.cdt.dsf.mi.service.command.output;
* 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"}]
*
* With GDB 7.1, a new 'core' field is present to indicate which core the thread is on.
* The parsing of this new field is handled by {@link MIThread}
*
* -thread-info
* ^done,threads=[
* {id="1",target-id="process 1307",
* frame={level="0",addr="0x08048618",func="main",args=[],
* file="a.cc",fullname="/local/lmckhou/testing/a.cc",line="9"},
* state="stopped",
* core="2"}],
* current-thread-id="1"
*
* @since 1.1
*/
public class MIThreadInfoInfo extends MIInfo {