Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml16
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/ResumeCommand.java8
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepCommand.java12
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SuspendCommand.java10
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/TerminateCommand.java8
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java5
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java10
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java10
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFColumnPresentationExpression.java10
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPane.java132
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPaneFactory.java49
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java4
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java58
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java6
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java12
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java318
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java23
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFSourceRef.java2
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ExpressionsProxy.java4
-rw-r--r--plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IExpressions.java7
21 files changed, 612 insertions, 93 deletions
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.tm.tcf.debug.ui/META-INF/MANIFEST.MF
index 5b54cf108..026fddfa8 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/META-INF/MANIFEST.MF
@@ -12,6 +12,7 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.ui.console,
org.eclipse.ui.workbench.texteditor,
org.eclipse.text,
+ org.eclipse.jface.text,
org.eclipse.debug.core,
org.eclipse.debug.ui,
org.eclipse.tm.tcf.debug,
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml
index f027bda02..b3477b20d 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml
@@ -128,4 +128,20 @@
</specification>
</extension>
+ <extension point="org.eclipse.debug.ui.detailPaneFactories">
+ <detailFactories
+ class="org.eclipse.tm.internal.tcf.debug.ui.model.TCFDetailPaneFactory"
+ id="org.eclipse.tm.tcf.debug.DetailPaneFactory">
+ <enablement>
+ <with variable="selection">
+ <iterate>
+ <or>
+ <instanceof value="org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode"/>
+ </or>
+ </iterate>
+ </with>
+ </enablement>
+ </detailFactories>
+ </extension>
+
</plugin>
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/ResumeCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/ResumeCommand.java
index 645ffc54e..6118ae199 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/ResumeCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/ResumeCommand.java
@@ -46,10 +46,10 @@ public class ResumeCommand implements IResumeHandler {
if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
else node = model.getRootNode();
while (node != null && !node.isDisposed()) {
- if (!node.validateNode(this)) return;
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- ctx = ((TCFNodeExecContext)node).getRunContext();
+ if (!node.validateNode(this)) return;
+ ctx = ((TCFNodeExecContext)node).getRunContext().getData();
}
if (ctx == null) {
node = node.getParent();
@@ -82,10 +82,10 @@ public class ResumeCommand implements IResumeHandler {
if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
else node = model.getRootNode();
while (node != null && !node.isDisposed()) {
- if (!node.validateNode(this)) return;
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- ctx = ((TCFNodeExecContext)node).getRunContext();
+ if (!node.validateNode(this)) return;
+ ctx = ((TCFNodeExecContext)node).getRunContext().getData();
}
if (ctx == null) {
node = node.getParent();
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepCommand.java
index a9e8972f3..873c1a8e3 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepCommand.java
@@ -49,12 +49,12 @@ abstract class StepCommand implements IDebugCommandHandler {
if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
else node = model.getRootNode();
while (node != null && !node.isDisposed()) {
- if (!node.validateNode(this)) return;
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- ctx = ((TCFNodeExecContext)node).getRunContext();
+ if (!node.validateNode(this)) return;
+ ctx = ((TCFNodeExecContext)node).getRunContext().getData();
}
- if (!canExecute(ctx)) {
+ if (ctx == null || !canExecute(ctx)) {
node = node.getParent();
}
else {
@@ -80,12 +80,12 @@ abstract class StepCommand implements IDebugCommandHandler {
if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
else node = model.getRootNode();
while (node != null && !node.isDisposed()) {
- if (!node.validateNode(this)) return;
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- ctx = ((TCFNodeExecContext)node).getRunContext();
+ if (!node.validateNode(this)) return;
+ ctx = ((TCFNodeExecContext)node).getRunContext().getData();
}
- if (!canExecute(ctx)) {
+ if (ctx == null || !canExecute(ctx)) {
node = node.getParent();
}
else {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SuspendCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SuspendCommand.java
index fa69c4454..55fcb80a7 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SuspendCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SuspendCommand.java
@@ -46,10 +46,10 @@ public class SuspendCommand implements ISuspendHandler {
if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
else node = model.getRootNode();
while (node != null && !node.isDisposed()) {
- if (!node.validateNode(this)) return;
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- ctx = ((TCFNodeExecContext)node).getRunContext();
+ if (!node.validateNode(this)) return;
+ ctx = ((TCFNodeExecContext)node).getRunContext().getData();
}
if (ctx == null) {
node = node.getParent();
@@ -82,17 +82,17 @@ public class SuspendCommand implements ISuspendHandler {
if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
else node = model.getRootNode();
while (node != null && !node.isDisposed()) {
- if (!node.validateNode(this)) return;
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- ctx = ((TCFNodeExecContext)node).getRunContext();
+ if (!node.validateNode(this)) return;
+ ctx = ((TCFNodeExecContext)node).getRunContext().getData();
}
if (ctx == null) {
node = node.getParent();
}
else {
set.add(ctx);
- node = null;
+ break;
}
}
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/TerminateCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/TerminateCommand.java
index 2d2255743..a9aa268e0 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/TerminateCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/TerminateCommand.java
@@ -45,10 +45,10 @@ public class TerminateCommand implements ITerminateHandler {
TCFNode node = null;
if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
while (node != null && !node.isDisposed()) {
- if (!node.validateNode(this)) return;
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- ctx = ((TCFNodeExecContext)node).getRunContext();
+ if (!node.validateNode(this)) return;
+ ctx = ((TCFNodeExecContext)node).getRunContext().getData();
}
if (ctx != null && ctx.canTerminate()) {
res = true;
@@ -73,10 +73,10 @@ public class TerminateCommand implements ITerminateHandler {
TCFNode node = null;
if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
while (node != null && !node.isDisposed()) {
- if (!node.validateNode(this)) return;
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- ctx = ((TCFNodeExecContext)node).getRunContext();
+ if (!node.validateNode(this)) return;
+ ctx = ((TCFNodeExecContext)node).getRunContext().getData();
}
if (ctx != null && ctx.canTerminate()) {
set.add(ctx);
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java
index d3afa88f4..23dc827a9 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java
@@ -378,9 +378,10 @@ public class TCFAnnotationManager {
public void run() {
IRunControl.RunControlContext x = null;
TCFNode n = (TCFNode)adaptable;
- while (x == null && n != null) {
+ while (x == null && n != null && !n.isDisposed()) {
if (n instanceof TCFNodeExecContext) {
- x = ((TCFNodeExecContext)n).getRunContext();
+ if (!n.validateNode(this)) return;
+ x = ((TCFNodeExecContext)n).getRunContext().getData();
}
n = n.parent;
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java
index 09c4f191e..c1fa139b2 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java
@@ -1,3 +1,13 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
package org.eclipse.tm.internal.tcf.debug.ui.model;
import java.util.HashMap;
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java
index 4f7d7de54..8b69cc111 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java
@@ -1,3 +1,13 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
package org.eclipse.tm.internal.tcf.debug.ui.model;
import java.util.HashMap;
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFColumnPresentationExpression.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFColumnPresentationExpression.java
index 88c102a66..4e60082df 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFColumnPresentationExpression.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFColumnPresentationExpression.java
@@ -1,3 +1,13 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
package org.eclipse.tm.internal.tcf.debug.ui.model;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPane.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPane.java
new file mode 100644
index 000000000..adb883112
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPane.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.debug.ui.IDetailPane;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.ui.IWorkbenchPartSite;
+
+/**
+ * This detail pane uses a source viewer to display detailed information about the current
+ * selection.
+ */
+public class TCFDetailPane implements IDetailPane {
+
+ public static final String ID = "org.eclipse.tm.tcf.debug.DetailPaneFactory";
+ public static final String NAME = "TCF Detail Pane";
+ public static final String DESC = "TCF Detail Pane";
+
+ private SourceViewer source_viewer;
+ private Display display;
+ private int generation;
+ @SuppressWarnings("unused")
+ private IWorkbenchPartSite part_site;
+ private final Document document = new Document();
+
+ public Control createControl(Composite parent) {
+ assert source_viewer == null;
+ source_viewer = new SourceViewer(parent, null, SWT.V_SCROLL | SWT.H_SCROLL);
+ source_viewer.setDocument(document);
+ source_viewer.setEditable(false);
+ Control control = source_viewer.getControl();
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ control.setLayoutData(gd);
+ display = control.getDisplay();
+ return control;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void display(IStructuredSelection selection) {
+ if (source_viewer == null) return;
+ generation++;
+ final int g = generation;
+ final ArrayList<TCFNode> nodes = new ArrayList<TCFNode>();
+ if (selection != null) {
+ Iterator iterator = selection.iterator();
+ while (iterator.hasNext()) {
+ Object next = iterator.next();
+ if (next instanceof TCFNode) nodes.add((TCFNode)next);
+ }
+ }
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ if (g != generation) return;
+ final String s = getDetailText(nodes, this);
+ if (s == null) return;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (g != generation) return;
+ document.set(s);
+ }
+ });
+ }
+ });
+ }
+
+ private String getDetailText(ArrayList<TCFNode> nodes, Runnable done) {
+ if (!TCFNode.validateNodes(nodes, done)) return null;
+ StringBuffer bf = new StringBuffer();
+ for (TCFNode n : nodes) {
+ if (n instanceof TCFNodeExpression) {
+ String s = ((TCFNodeExpression)n).getDetailText(done);
+ if (s == null) return null;
+ bf.append(s);
+ }
+ else {
+ bf.append(n.toString());
+ bf.append('\n');
+ }
+ }
+ return bf.toString();
+ }
+
+ public void dispose() {
+ if (source_viewer == null) return;
+ generation++;
+ if (source_viewer.getControl() != null) {
+ source_viewer.getControl().dispose();
+ }
+ source_viewer = null;
+ }
+
+ public String getDescription() {
+ return DESC;
+ }
+
+ public String getID() {
+ return ID;
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ public void init(IWorkbenchPartSite part_site) {
+ this.part_site = part_site;
+ }
+
+ public boolean setFocus() {
+ if (source_viewer == null) return false;
+ source_viewer.getTextWidget().setFocus();
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPaneFactory.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPaneFactory.java
new file mode 100644
index 000000000..46d971560
--- /dev/null
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPaneFactory.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.debug.ui.IDetailPane;
+import org.eclipse.debug.ui.IDetailPaneFactory;
+import org.eclipse.jface.viewers.IStructuredSelection;
+
+/**
+ * The TCF detail pane factory is contributed to the <code>org.eclipse.debug.ui.detailPaneFactories</code>
+ * extension. For any selection that contains TCFNode the factory can produce a <code>IDetailPane</code> object.
+ */
+public class TCFDetailPaneFactory implements IDetailPaneFactory {
+
+ public IDetailPane createDetailPane(String paneID) {
+ assert paneID.equals(TCFDetailPane.ID);
+ return new TCFDetailPane();
+ }
+
+ public String getDefaultDetailPane(IStructuredSelection selection) {
+ return TCFDetailPane.ID;
+ }
+
+ public String getDetailPaneDescription(String paneID) {
+ return TCFDetailPane.NAME;
+ }
+
+ public String getDetailPaneName(String paneID) {
+ return TCFDetailPane.DESC;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Set getDetailPaneTypes(IStructuredSelection selection) {
+ HashSet<String> set = new HashSet<String>();
+ set.add(TCFDetailPane.ID);
+ return set;
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java
index 788cc8caf..1680e0f3e 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java
@@ -171,7 +171,7 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
error("Context is disposed");
}
else if (exec_ctx.validateNode(this)) {
- IMemory.MemoryContext mem = exec_ctx.getMemoryContext();
+ IMemory.MemoryContext mem = exec_ctx.getMemoryContext().getData();
if (mem == null) {
error("Context does not provide memory access");
}
@@ -249,7 +249,7 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
error("Context is disposed");
}
else if (exec_ctx.validateNode(this)) {
- final IMemory.MemoryContext mem = exec_ctx.getMemoryContext();
+ final IMemory.MemoryContext mem = exec_ctx.getMemoryContext().getData();
if (mem == null) {
error("Context does not provide memory access");
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
index 3fc77e0a7..e5d3b27d2 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
@@ -76,11 +76,13 @@ import org.eclipse.tm.internal.tcf.debug.ui.commands.StepReturnCommand;
import org.eclipse.tm.internal.tcf.debug.ui.commands.SuspendCommand;
import org.eclipse.tm.internal.tcf.debug.ui.commands.TerminateCommand;
import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.IMemory;
import org.eclipse.tm.tcf.services.IProcesses;
import org.eclipse.tm.tcf.services.IRegisters;
import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.services.ISymbols;
import org.eclipse.tm.tcf.util.TCFDataCache;
import org.eclipse.tm.tcf.util.TCFTask;
import org.eclipse.ui.IEditorInput;
@@ -119,6 +121,12 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
private static final Map<ILaunchConfiguration,IEditorInput> editor_not_found =
new HashMap<ILaunchConfiguration,IEditorInput>();
+ private final Map<String,Map<String,TCFDataCache<ISymbols.Symbol>>> symbols =
+ new HashMap<String,Map<String,TCFDataCache<ISymbols.Symbol>>>();
+
+ private final Map<String,Map<String,TCFDataCache<String[]>>> symbol_children =
+ new HashMap<String,Map<String,TCFDataCache<String[]>>>();
+
private TCFNodeLaunch launch_node;
private boolean disposed;
@@ -151,6 +159,10 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onContextChanged(contexts[i]);
}
+ Map<String,TCFDataCache<ISymbols.Symbol>> m = symbols.remove(contexts[i].getID());
+ if (m != null) {
+ for (TCFDataCache<ISymbols.Symbol> s : m.values()) s.cancel();
+ }
}
fireModelChanged();
}
@@ -568,6 +580,52 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
assert Protocol.isDispatchThread();
return id2node.get(id);
}
+
+ public TCFDataCache<ISymbols.Symbol> getSymbolInfoCache(String mem_id, final String sym_id) {
+ Map<String,TCFDataCache<ISymbols.Symbol>> m = symbols.get(mem_id);
+ if (m == null) symbols.put(mem_id, m = new HashMap<String,TCFDataCache<ISymbols.Symbol>>());
+ TCFDataCache<ISymbols.Symbol> s = m.get(sym_id);
+ if (s == null) m.put(sym_id, s = new TCFDataCache<ISymbols.Symbol>(launch.getChannel()) {
+ @Override
+ protected boolean startDataRetrieval() {
+ ISymbols syms = getLaunch().getService(ISymbols.class);
+ if (sym_id == null || syms == null) {
+ set(null, null, null);
+ return true;
+ }
+ command = syms.getContext(sym_id, new ISymbols.DoneGetContext() {
+ public void doneGetContext(IToken token, Exception error, ISymbols.Symbol sym) {
+ set(token, error, sym);
+ }
+ });
+ return false;
+ }
+ });
+ return s;
+ }
+
+ public TCFDataCache<String[]> getSymbolChildrenCache(String mem_id, final String sym_id) {
+ Map<String,TCFDataCache<String[]>> m = symbol_children.get(mem_id);
+ if (m == null) symbol_children.put(mem_id, m = new HashMap<String,TCFDataCache<String[]>>());
+ TCFDataCache<String[]> s = m.get(sym_id);
+ if (s == null) m.put(sym_id, s = new TCFDataCache<String[]>(launch.getChannel()) {
+ @Override
+ protected boolean startDataRetrieval() {
+ ISymbols syms = getLaunch().getService(ISymbols.class);
+ if (sym_id == null || syms == null) {
+ set(null, null, null);
+ return true;
+ }
+ command = syms.getChildren(sym_id, new ISymbols.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception error, String[] ids) {
+ set(token, error, ids);
+ }
+ });
+ return false;
+ }
+ });
+ return s;
+ }
public void update(IChildrenCountUpdate[] updates) {
for (int i = 0; i < updates.length; i++) {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java
index cc81311c5..f97cb55ee 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java
@@ -154,7 +154,7 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
/**
* Return address of this node.
* For executable contexts and stack frames address is current PC.
- * @return
+ * @return BigInteger - remote memory address that is associated with this node
*/
public BigInteger getAddress() {
return null;
@@ -332,7 +332,7 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
public abstract boolean validateNode(Runnable done);
/**
- * Subclasses can use this method to validate a collection of nodes.
+ * Clients can use this method to validate a collection of nodes.
* Validation of multiple nodes is expensive and should be avoided
* when possible.
*
@@ -342,7 +342,7 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
* @param nodes
* @return true if all nodes are already valid, false if validation is started.
*/
- protected boolean validateNodes(Collection<TCFNode> nodes, Runnable done) {
+ public static boolean validateNodes(Collection<TCFNode> nodes, Runnable done) {
TCFNode pending = null;
for (TCFNode n : nodes) {
if (!n.validateNode(null)) pending = n;
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java
index efc8f95be..1266fa0ba 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java
@@ -153,16 +153,12 @@ public class TCFNodeExecContext extends TCFNode {
return line_info_cache;
}
- public IRunControl.RunControlContext getRunContext() {
- assert Protocol.isDispatchThread();
- if (!run_context.isValid()) return null;
- return run_context.getData();
+ public TCFDataCache<IRunControl.RunControlContext> getRunContext() {
+ return run_context;
}
- public IMemory.MemoryContext getMemoryContext() {
- assert Protocol.isDispatchThread();
- if (!mem_context.isValid()) return null;
- return mem_context.getData();
+ public TCFDataCache<IMemory.MemoryContext> getMemoryContext() {
+ return mem_context;
}
public boolean isRunning() {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java
index 89308f55f..23a469442 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java
@@ -1,5 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
package org.eclipse.tm.internal.tcf.debug.ui.model;
+import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
@@ -14,10 +25,12 @@ import org.eclipse.tm.internal.tcf.debug.ui.Activator;
import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
import org.eclipse.tm.tcf.protocol.IChannel;
import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.IExpressions;
import org.eclipse.tm.tcf.services.ISymbols;
import org.eclipse.tm.tcf.util.TCFDataCache;
+// TODO: elements of long arrays need to be shown in groups
public class TCFNodeExpression extends TCFNode {
private final String script;
@@ -192,19 +205,24 @@ public class TCFNodeExpression extends TCFNode {
value.wait(this);
return false;
}
- String id = null;
- if (value.getData() != null) id = value.getData().getTypeID();
- ISymbols syms = model.getLaunch().getService(ISymbols.class);
- if (id == null || syms == null) {
+ IExpressions.Value v = value.getData();
+ if (v == null) {
set(null, null, null);
return true;
}
- command = syms.getContext(id, new ISymbols.DoneGetContext() {
- public void doneGetContext(IToken token, Exception error, ISymbols.Symbol sym) {
- set(token, error, sym);
- }
- });
- return false;
+ String ctx_id = v.getExeContextID();
+ String type_id = v.getTypeID();
+ if (ctx_id == null || type_id == null) {
+ set(null, null, null);
+ return true;
+ }
+ TCFDataCache<ISymbols.Symbol> s = model.getSymbolInfoCache(ctx_id, type_id);
+ if (!s.validate()) {
+ s.wait(this);
+ return false;
+ }
+ set(null, s.getError(), s.getData());
+ return true;
}
};
children = new TCFChildrenSubExpressions(this);
@@ -267,71 +285,82 @@ public class TCFNodeExpression extends TCFNode {
return type;
}
- private BigInteger toBigInteger(byte[] data, boolean big_endian, boolean sign_extension) {
+ private BigInteger toBigInteger(byte[] data, int offs, int size, boolean big_endian, boolean sign_extension) {
byte[] temp = null;
if (sign_extension) {
- temp = new byte[data.length];
+ temp = new byte[size];
}
else {
- temp = new byte[data.length + 1];
+ temp = new byte[size + 1];
temp[0] = 0; // Extra byte to avoid sign extension by BigInteger
}
if (big_endian) {
- System.arraycopy(data, 0, temp, sign_extension ? 0 : 1, data.length);
+ System.arraycopy(data, offs, temp, sign_extension ? 0 : 1, size);
}
else {
- for (int i = 0; i < data.length; i++) {
- temp[temp.length - i - 1] = data[i];
+ for (int i = 0; i < size; i++) {
+ temp[temp.length - i - 1] = data[i + offs];
}
}
return new BigInteger(temp);
}
- private void setLabel(ILabelUpdate result, String name, int col, int radix) {
+ private String toNumberString(int radix, ISymbols.Symbol t, byte[] data, int offs, int size, boolean big_endian) {
String s = null;
- IExpressions.Value val = value.getData();
- if (val != null) {
- byte[] data = val.getValue();
- if (data == null) s = "n/a";
- if (s == null && data.length == 0) s = "";
- if (s == null && radix == 10 && data.length <= 16) {
- ISymbols.Symbol t = type.getData();
- if (t != null) {
- switch (t.getTypeClass()) {
- case integer:
- s = toBigInteger(data, val.isBigEndian(), true).toString();
+ if (data == null) s = "N/A";
+ if (s == null && size == 0) s = "";
+ if (s == null && radix == 10 && size <= 16) {
+ if (t != null) {
+ switch (t.getTypeClass()) {
+ case integer:
+ s = toBigInteger(data, offs, size, big_endian, true).toString();
+ break;
+ case real:
+ switch (t.getSize()) {
+ case 4:
+ s = Float.toString(Float.intBitsToFloat(toBigInteger(
+ data, offs, size, big_endian, true).intValue()));
break;
- case real:
- switch (t.getSize()) {
- case 4:
- s = Float.toString(Float.intBitsToFloat(toBigInteger(
- data, val.isBigEndian(), true).intValue()));
- break;
- case 8:
- s = Double.toString(Double.longBitsToDouble(toBigInteger(
- data, val.isBigEndian(), true).longValue()));
- break;
- }
+ case 8:
+ s = Double.toString(Double.longBitsToDouble(toBigInteger(
+ data, offs, size, big_endian, true).longValue()));
break;
}
- }
- }
- if (s == null && data.length <= 16) {
- s = toBigInteger(data, val.isBigEndian(), false).toString(radix);
- switch (radix) {
- case 8:
- if (!s.startsWith("0")) s = "0" + s;
- break;
- case 16:
- int l = data.length * 2 - s.length();
- if (l < 0) l = 0;
- if (l > 16) l = 16;
- s = "0000000000000000".substring(0, l) + s;
break;
}
}
}
+ if (s == null && size <= 16) {
+ s = toBigInteger(data, offs, size, big_endian, false).toString(radix);
+ switch (radix) {
+ case 8:
+ if (!s.startsWith("0")) s = "0" + s;
+ break;
+ case 16:
+ int l = size * 2 - s.length();
+ if (l < 0) l = 0;
+ if (l > 16) l = 16;
+ s = "0000000000000000".substring(0, l) + s;
+ break;
+ }
+ }
+ if (s == null) s = "N/A";
+ return s;
+ }
+
+ private String toNumberString(int radix) {
+ String s = null;
+ IExpressions.Value val = value.getData();
+ if (val != null) {
+ byte[] data = val.getValue();
+ s = toNumberString(radix, type.getData(), data, 0, data.length, val.isBigEndian());
+ }
if (s == null) s = "...";
+ return s;
+ }
+
+ private void setLabel(ILabelUpdate result, String name, int col, int radix) {
+ String s = toNumberString(radix);
if (name == null) {
result.setLabel(s, col);
}
@@ -371,7 +400,7 @@ public class TCFNodeExpression extends TCFNode {
}
}
}
- if (s == null) s = "";
+ if (s == null) s = "N/A";
result.setLabel(s, col);
}
@@ -386,12 +415,21 @@ public class TCFNodeExpression extends TCFNode {
Throwable error = expression.getError();
if (error == null) error = value.getError();
if (error == null) error = type.getError();
+ String[] cols = result.getColumnIds();
if (error != null) {
- result.setForeground(new RGB(255, 0, 0), 0);
- result.setLabel(name + ": " + error.getMessage(), 0);
+ if (cols == null || cols.length <= 1) {
+ result.setForeground(new RGB(255, 0, 0), 0);
+ result.setLabel(name + ": N/A", 0);
+ }
+ else {
+ result.setLabel(name, 0);
+ for (int i = 1; i < cols.length; i++) {
+ result.setForeground(new RGB(255, 0, 0), i);
+ result.setLabel("N/A", i);
+ }
+ }
}
else {
- String[] cols = result.getColumnIds();
if (cols == null) {
setLabel(result, name, 0, 16);
}
@@ -414,6 +452,174 @@ public class TCFNodeExpression extends TCFNode {
}
}
}
+
+ private void appendErrorText(StringBuffer bf, Throwable error) {
+ if (error == null) return;
+ bf.append("Exception: ");
+ for (;;) {
+ String s = error.getLocalizedMessage();
+ if (s == null || s.length() == 0) s = error.getClass().getName();
+ bf.append(s);
+ if (!s.endsWith("\n")) bf.append('\n');
+ Throwable cause = error.getCause();
+ if (cause == null) return;
+ bf.append("Caused by: ");
+ error = cause;
+ }
+ }
+
+ private boolean appendArrayValueText(StringBuffer bf, int level, ISymbols.Symbol t,
+ byte[] data, int offs, int size, boolean big_endian, Runnable done) {
+ TCFDataCache<ISymbols.Symbol> c = model.getSymbolInfoCache(t.getExeContextID(), t.getBaseTypeID());
+ if (!c.validate()) {
+ c.wait(done);
+ return false;
+ }
+ ISymbols.Symbol b = c.getData();
+ int length = t.getLength();
+ if (level == 0) {
+ if (size == length) {
+ try {
+ bf.append('"');
+ String s = new String(data, offs, size, "ASCII");
+ int l = s.length();
+ String end_q = "\"";
+ if (l > 300) {
+ l = 300;
+ end_q = "...";
+ }
+ for (int i = 0; i < l; i++) {
+ char ch = s.charAt(i);
+ if (ch < ' ') ch = ' ';
+ bf.append(ch);
+ }
+ bf.append(end_q);
+ }
+ catch (UnsupportedEncodingException e) {
+ Protocol.log("ASCII", e);
+ }
+ bf.append('\n');
+ }
+ }
+ if (b == null) return true;
+ int elem_size = size / length;
+ bf.append('[');
+ for (int n = 0; n < length; n++) {
+ if (n >= 100) {
+ bf.append("...");
+ break;
+ }
+ if (n > 0) bf.append(", ");
+ if (!appendValueText(bf, level + 1, b, data, offs + n * elem_size, elem_size, big_endian, done)) return false;
+ }
+ bf.append(']');
+ if (level == 0) bf.append('\n');
+ return true;
+ }
+
+ private boolean appendCompositeValueText(StringBuffer bf, int level, ISymbols.Symbol t,
+ byte[] data, int offs, int size, boolean big_endian, Runnable done) {
+ TCFDataCache<String[]> c = model.getSymbolChildrenCache(t.getExeContextID(), t.getID());
+ if (!c.validate()) {
+ c.wait(done);
+ return false;
+ }
+ String[] ids = c.getData();
+ if (ids == null) return true;
+ bf.append('{');
+ for (String id : ids) {
+ if (id != ids[0]) bf.append(", ");
+ TCFDataCache<ISymbols.Symbol> s = model.getSymbolInfoCache(t.getExeContextID(), id);
+ if (!s.validate()) {
+ s.wait(done);
+ return false;
+ }
+ ISymbols.Symbol f = s.getData();
+ if (!appendValueText(bf, level + 1, f, data, offs + f.getOffset(), f.getSize(), big_endian, done)) return false;
+ }
+ bf.append('}');
+ return true;
+ }
+
+ private boolean appendValueText(StringBuffer bf, int level, ISymbols.Symbol t,
+ byte[] data, int offs, int size, boolean big_endian, Runnable done) {
+ if (data == null) return true;
+ switch (t.getTypeClass()) {
+ case enumeration:
+ case integer:
+ case cardinal:
+ case real:
+ if (level == 0) {
+ bf.append("Dec: ");
+ bf.append(toNumberString(10, t, data, offs, size, big_endian));
+ bf.append("\n");
+ bf.append("Oct: ");
+ bf.append(toNumberString(8, t, data, offs, size, big_endian));
+ bf.append("\n");
+ bf.append("Hex: ");
+ bf.append(toNumberString(16, t, data, offs, size, big_endian));
+ bf.append("\n");
+ }
+ else if (t.getTypeClass() == ISymbols.TypeClass.cardinal) {
+ bf.append("0x");
+ bf.append(toNumberString(16, t, data, offs, size, big_endian));
+ }
+ else {
+ bf.append(toNumberString(10, t, data, offs, size, big_endian));
+ }
+ break;
+ case pointer:
+ case function:
+ if (level == 0) {
+ bf.append("Oct: ");
+ bf.append(toNumberString(8, t, data, offs, size, big_endian));
+ bf.append("\n");
+ bf.append("Hex: ");
+ bf.append(toNumberString(16, t, data, offs, size, big_endian));
+ bf.append("\n");
+ }
+ else {
+ bf.append("0x");
+ bf.append(toNumberString(16, t, data, offs, size, big_endian));
+ }
+ break;
+ case array:
+ if (!appendArrayValueText(bf, level, t, data, offs, size, big_endian, done)) return false;
+ break;
+ case composite:
+ if (!appendCompositeValueText(bf, level, t, data, offs, size, big_endian, done)) return false;
+ break;
+ default:
+ bf.append('?');
+ break;
+ }
+ return true;
+ }
+
+ String getDetailText(Runnable done) {
+ StringBuffer bf = new StringBuffer();
+ appendErrorText(bf, expression.getError());
+ appendErrorText(bf, value.getError());
+ appendErrorText(bf, type.getError());
+ if (bf.length() == 0) {
+ IExpressions.Value v = value.getData();
+ if (v != null) {
+ byte[] data = v.getValue();
+ boolean big_endian = v.isBigEndian();
+ ISymbols.Symbol t = type.getData();
+ if (t != null) {
+ if (!appendValueText(bf, 0, t, data, 0, data.length, big_endian, done)) return null;
+ }
+ else {
+ bf.append("Hex: ");
+ bf.append(toNumberString(16, t, data, 0, data.length, big_endian));
+ bf.append("\n");
+ bf.append("Value type is not available\n");
+ }
+ }
+ }
+ return bf.toString();
+ }
@Override
protected void getData(IChildrenCountUpdate result) {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java
index ce272c8c2..1534bf51d 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java
@@ -82,23 +82,41 @@ public class TCFNodeStackFrame extends TCFNode {
set(null, null, null);
return true;
}
+ IMemory.MemoryContext mem_ctx = null;
+ TCFNode p = parent;
+ while (p != null) {
+ if (p instanceof TCFNodeExecContext) {
+ TCFDataCache<IMemory.MemoryContext> cache = ((TCFNodeExecContext)p).getMemoryContext();
+ if (!cache.validate()) {
+ cache.wait(this);
+ return false;
+ }
+ mem_ctx = cache.getData();
+ if (mem_ctx != null) break;
+ }
+ p = p.parent;
+ }
TCFSourceRef l = line_info_cache.get(n);
if (l != null) {
+ l.context = mem_ctx;
set(null, null, l);
return true;
}
ILineNumbers ln = model.getLaunch().getService(ILineNumbers.class);
if (ln == null) {
l = new TCFSourceRef();
+ l.context = mem_ctx;
l.address = n;
set(null, null, l);
return true;
}
final BigInteger n0 = n;
final BigInteger n1 = n0.add(BigInteger.valueOf(1));
+ final IMemory.MemoryContext ctx = mem_ctx;
command = ln.mapToSource(parent.id, n0, n1, new ILineNumbers.DoneMapToSource() {
public void doneMapToSource(IToken token, Exception error, CodeArea[] areas) {
TCFSourceRef l = new TCFSourceRef();
+ l.context = ctx;
l.address = n0;
if (error == null && areas != null && areas.length > 0) {
for (ILineNumbers.CodeArea area : areas) {
@@ -289,7 +307,7 @@ public class TCFNodeStackFrame extends TCFNode {
result.setLabel("...", 0);
}
else {
- String label = makeHexAddrString(l.address);
+ String label = makeHexAddrString(l.context, l.address);
if (l.area != null && l.area.file != null) {
label += ": " + l.area.file + ", line " + l.area.start_line;
}
@@ -299,12 +317,11 @@ public class TCFNodeStackFrame extends TCFNode {
}
}
- private String makeHexAddrString(Number n) {
+ private String makeHexAddrString(IMemory.MemoryContext m, Number n) {
BigInteger i = null;
if (n instanceof BigInteger) i = (BigInteger)n;
else i = new BigInteger(n.toString());
String s = i.toString(16);
- IMemory.MemoryContext m = ((TCFNodeExecContext)parent).getMemoryContext();
int sz = (m != null ? m.getAddressSize() : 4) * 2;
int l = sz - s.length();
if (l < 0) l = 0;
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFSourceRef.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFSourceRef.java
index 00405ed49..049edcd7c 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFSourceRef.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFSourceRef.java
@@ -13,11 +13,13 @@ package org.eclipse.tm.internal.tcf.debug.model;
import java.math.BigInteger;
import org.eclipse.tm.tcf.services.ILineNumbers;
+import org.eclipse.tm.tcf.services.IMemory;
/**
* Objects of this class represent a mapping between an address and source code area.
*/
public class TCFSourceRef {
+ public IMemory.MemoryContext context;
public BigInteger address;
public ILineNumbers.CodeArea area;
public Throwable error;
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ExpressionsProxy.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ExpressionsProxy.java
index 5d1a2f98c..7634707e9 100644
--- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ExpressionsProxy.java
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/internal/tcf/services/remote/ExpressionsProxy.java
@@ -99,6 +99,10 @@ public class ExpressionsProxy implements IExpressions {
return (String)props.get(VAL_TYPE);
}
+ public String getExeContextID() {
+ return (String)props.get(VAL_EXE_ID);
+ }
+
public byte[] getValue() {
return value;
}
diff --git a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IExpressions.java b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IExpressions.java
index dfa5f1064..0c355e3d2 100644
--- a/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IExpressions.java
+++ b/plugins/org.eclipse.tm.tcf/src/org/eclipse/tm/tcf/services/IExpressions.java
@@ -126,6 +126,12 @@ public interface IExpressions extends IService {
String getTypeID();
/**
+ * Get execution context ID (thread or process) that owns type symbol for this value.
+ * @return execution context ID.
+ */
+ String getExeContextID();
+
+ /**
* Check endianess of the values.
* Big endian means decreasing numeric significance with increasing byte number.
* @return true if big endian.
@@ -151,6 +157,7 @@ public interface IExpressions extends IService {
static final String
VAL_CLASS = "Class",
VAL_TYPE = "Type",
+ VAL_EXE_ID = "ExeID",
VAL_BIG_ENDIAN = "BigEndian";
/**

Back to the top