1
/*******************************************************************************
2
* Copyright (c) 2008, 2010 Ericsson and others.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* Ericsson - Initial API and implementation
10
* Wind River Systems - refactored to match pattern in package
11
* John Dallaway - GDB 7.x getOsId() pattern match too restrictive (Bug 325552)
12
*******************************************************************************/
13
package org.eclipse.cdt.dsf.mi.service.command.output;
15
import java.util.regex.Matcher;
16
import java.util.regex.Pattern;
18
import org.eclipse.cdt.dsf.concurrent.Immutable;
21
* GDB/MI Thread tuple parsing.
26
public class MIThread {
28
final private String fThreadId;
29
final private String fTargetId;
30
final private String fOsId;
31
final private String fParentId;
32
final private MIFrame fTopFrame;
33
final private String fDetails;
34
final private String fState;
35
final private String fCore;
37
private MIThread(String threadId, String targetId, String osId, String parentId,
38
MIFrame topFrame, String details, String state, String core) {
49
public String getThreadId() { return fThreadId; }
50
public String getTargetId() { return fTargetId; }
51
public String getOsId() { return fOsId; }
52
public String getParentId() { return fParentId; }
53
public MIFrame getTopFrame() { return fTopFrame; }
54
public String getDetails() { return fDetails; }
55
public String getState() { return fState; }
57
* Available since GDB 7.1
60
public String getCore() { return fCore; }
62
public static MIThread parse(MITuple tuple) {
63
MIResult[] results = tuple.getMIResults();
65
String threadId = null;
66
String targetId = null;
68
String parentId = null;
69
MIFrame topFrame = null;
71
String details = null;
74
for (int j = 0; j < results.length; j++) {
75
MIResult result = results[j];
76
String var = result.getVariable();
77
if (var.equals("id")) { //$NON-NLS-1$
78
MIValue val = results[j].getMIValue();
79
if (val instanceof MIConst) {
80
threadId = ((MIConst) val).getCString().trim();
83
else if (var.equals("target-id")) { //$NON-NLS-1$
84
MIValue val = results[j].getMIValue();
85
if (val instanceof MIConst) {
86
targetId = ((MIConst) val).getCString().trim();
87
osId = parseOsId(targetId);
88
parentId = parseParentId(targetId);
91
else if (var.equals("frame")) { //$NON-NLS-1$
92
MITuple val = (MITuple)results[j].getMIValue();
93
topFrame = new MIFrame(val);
95
else if (var.equals("state")) { //$NON-NLS-1$
96
MIValue val = results[j].getMIValue();
97
if (val instanceof MIConst) {
98
state = ((MIConst) val).getCString().trim();
101
else if (var.equals("details")) { //$NON-NLS-1$
102
MIValue val = results[j].getMIValue();
103
if (val instanceof MIConst) {
104
details = ((MIConst) val).getCString().trim();
107
else if (var.equals("core")) { //$NON-NLS-1$
108
MIValue val = results[j].getMIValue();
109
if (val instanceof MIConst) {
110
core = ((MIConst) val).getCString().trim();
115
return new MIThread(threadId, targetId, osId, parentId, topFrame, details, state, core);
118
// Note that windows gdbs returns lower case "thread" , so the matcher needs to be case-insensitive.
119
private static Pattern fgOsIdPattern1 = Pattern.compile("([Tt][Hh][Rr][Ee][Aa][Dd]\\s*)(0x[0-9a-fA-F]+|-?\\d+)(\\s*\\([Ll][Ww][Pp]\\s*)(\\d*)", 0); //$NON-NLS-1$
120
private static Pattern fgOsIdPattern2 = Pattern.compile("[Tt][Hh][Rr][Ee][Aa][Dd]\\s*\\d+\\.(\\d+)", 0); //$NON-NLS-1$
121
private static Pattern fgOsIdPattern3 = Pattern.compile("[Tt][Hh][Rr][Ee][Aa][Dd]\\s*(\\S+)", 0); //$NON-NLS-1$
123
static String parseOsId(String str) {
125
// "Thread 0xb7c8ab90 (LWP 7010)"
127
// "Thread 162.32942"
131
// PLEASE UPDATE MIThreadTests.java IF YOU TWEAK THIS CODE
133
Matcher matcher = fgOsIdPattern1.matcher(str);
134
if (matcher.find()) {
135
return matcher.group(4);
138
matcher = fgOsIdPattern2.matcher(str);
139
if (matcher.find()) {
140
return matcher.group(1);
143
matcher = fgOsIdPattern3.matcher(str);
144
if (matcher.find()) {
145
return matcher.group(1);
151
private static Pattern fgIdPattern = Pattern.compile("[Tt][Hh][Rr][Ee][Aa][Dd]\\s*(\\d+)\\.\\d+", 0); //$NON-NLS-1$
154
* This is used to parse the same ID fed to {@link #parseOsId(String)}. The
155
* difference is that we return the first portion when the ID is in format
156
* "Thread pppp.tttt". If the ID is not in that format, we return null.
158
static String parseParentId(String str) {
160
// "Thread 162.32942"
162
// PLEASE UPDATE MIThreadTests.java IF YOU TWEAK THIS CODE
164
Matcher matcher = fgIdPattern.matcher(str);
165
if (matcher.find()) {
166
return matcher.group(1);