Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2011-06-30 20:54:27 +0000
committereutarass2011-06-30 20:54:27 +0000
commit5b11c386f9cfa5dccf566cfc2229a29da07ba4b9 (patch)
tree1f46b2bcbdc9b211aa5e8fb8fc57d71eec1d8cb9 /plugins
parentc1034860084e94449896dc6097edcc64e1438fc3 (diff)
downloadorg.eclipse.tcf-5b11c386f9cfa5dccf566cfc2229a29da07ba4b9.tar.gz
org.eclipse.tcf-5b11c386f9cfa5dccf566cfc2229a29da07ba4b9.tar.xz
org.eclipse.tcf-5b11c386f9cfa5dccf566cfc2229a29da07ba4b9.zip
TCF Debugger: implemented editor markers that show breakpoints status for current selection in the Debug view.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/plugin.properties1
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml19
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java3
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java3
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFAnnotationManager.java452
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java52
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java5
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java2
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsStatus.java27
9 files changed, 380 insertions, 184 deletions
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.properties b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.properties
index 5e5f22e79..a246bf272 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.properties
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.properties
@@ -15,6 +15,7 @@ preferencePage.name = Target Communication
debugCurrentInstructionPointer = Debug Current Instruction Pointer
debugCallStack = Debug Call Stack
+debugBreakpointInstance = Breakpoint
DebuggerActionSet.label = TCF Debugger
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml
index 08c01f973..571483967 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml
@@ -146,6 +146,9 @@
<type
name="org.eclipse.tm.tcf.debug.stack_frame">
</type>
+ <type
+ name="org.eclipse.tm.tcf.debug.breakpoint_instance">
+ </type>
</extension>
<extension point="org.eclipse.ui.editors.markerAnnotationSpecification">
@@ -181,6 +184,22 @@
verticalRulerPreferenceKey="secondaryIPVerticalRuler"
verticalRulerPreferenceValue="true">
</specification>
+ <specification
+ annotationImageProvider="org.eclipse.tm.internal.tcf.debug.ui.model.TCFAnnotationImageProvider"
+ annotationType="org.eclipse.tm.tcf.debug.breakpoint_instance"
+ colorPreferenceKey="breakpointInstanceColor"
+ colorPreferenceValue="100,200,204"
+ highlightPreferenceKey="breakpointInstanceHighlight"
+ highlightPreferenceValue="false"
+ label="%debugBreakpointInstance"
+ overviewRulerPreferenceKey="breakpointInstanceRuler"
+ overviewRulerPreferenceValue="true"
+ presentationLayer="5"
+ textPreferenceKey="breakpointInstanceIndication"
+ textPreferenceValue="false"
+ verticalRulerPreferenceKey="breakpointInstanceVerticalRuler"
+ verticalRulerPreferenceValue="true">
+ </specification>
</extension>
<extension point="org.eclipse.debug.ui.detailPaneFactories">
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java
index 9f3becfcf..ae58135e7 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java
@@ -40,9 +40,6 @@ public class Activator extends AbstractUIPlugin {
if (model_manager == null) {
model_manager = new TCFModelManager();
}
- if (annotation_manager == null) {
- annotation_manager = new TCFAnnotationManager();
- }
}
});
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java
index 9ea786aee..42ac06899 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/ImageCache.java
@@ -63,7 +63,8 @@ public class ImageCache {
IMG_BREAKPOINT_DISABLED = "icons/full/obj16/brkpd_obj.gif",
IMG_BREAKPOINT_INSTALLED = "icons/ovr16/installed_ovr.gif",
IMG_BREAKPOINT_CONDITIONAL = "icons/ovr16/conditional_ovr.gif",
- IMG_BREAKPOINT_WARNING = "icons/ovr16/warning_ovr.gif";
+ IMG_BREAKPOINT_WARNING = "icons/ovr16/warning_ovr.gif",
+ IMG_BREAKPOINT_ERROR = "icons/ovr16/error_ovr.gif";
private static final Map<String,ImageDescriptor> desc_cache = new HashMap<String,ImageDescriptor>();
private static final Map<ImageDescriptor,Image> image_cache = new HashMap<ImageDescriptor,Image>();
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 1bd5d35d6..3e81bb7dd 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2010 Wind River Systems, Inc. and others.
+ * Copyright (c) 2008, 2011 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
@@ -10,36 +10,56 @@
*******************************************************************************/
package org.eclipse.tm.internal.tcf.debug.ui.model;
+import java.math.BigInteger;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
-import java.util.Set;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.ISourceLocator;
+import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
-import org.eclipse.debug.ui.IDebugView;
+import org.eclipse.debug.ui.ISourcePresentation;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFSourceLookupDirector;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFSourceLookupParticipant;
import org.eclipse.tm.internal.tcf.debug.model.ITCFBreakpointListener;
import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpoint;
import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpointsStatus;
import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
+import org.eclipse.tm.internal.tcf.debug.model.TCFSourceRef;
+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.Protocol;
import org.eclipse.tm.tcf.services.IBreakpoints;
+import org.eclipse.tm.tcf.services.ILineNumbers;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWindowListener;
-import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
@@ -50,18 +70,19 @@ public class TCFAnnotationManager {
class TCFAnnotation extends Annotation {
- final TCFModel model;
- final String exe_id;
- final ITextEditor editor;
+ final ILineNumbers.CodeArea area;
final Image image;
- final Position position;
+ final String text;
+ final int hash_code;
- TCFAnnotation(TCFModel model, String exe_id, ITextEditor editor, Image image, Position position) {
- this.model = model;
- this.exe_id = exe_id;
- this.editor = editor;
+ IAnnotationModel model;
+
+ TCFAnnotation(ILineNumbers.CodeArea area, Image image, String text) {
+ this.area = area;
this.image = image;
- this.position = position;
+ this.text = text;
+ hash_code = area.hashCode() + image.hashCode() + text.hashCode();
+ setText(text);
}
protected Image getImage() {
@@ -70,17 +91,30 @@ public class TCFAnnotationManager {
void dispose() {
assert Thread.currentThread() == display.getThread();
- IDocumentProvider doc_provider = editor.getDocumentProvider();
- IEditorInput editor_input = editor.getEditorInput();
- if (doc_provider != null) {
- IAnnotationModel ann_model = doc_provider.getAnnotationModel(editor_input);
- if (ann_model != null) ann_model.removeAnnotation(this);
+ if (model != null) {
+ model.removeAnnotation(this);
+ model = null;
}
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof TCFAnnotation)) return false;
+ TCFAnnotation a = (TCFAnnotation)o;
+ if (!area.equals(a.area)) return false;
+ if (!image.equals(a.image)) return false;
+ if (!text.equals(a.text)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return hash_code;
+ }
}
private class WorkbenchWindowInfo {
- final ArrayList<TCFAnnotation> annotations = new ArrayList<TCFAnnotation>();
+ final LinkedList<TCFAnnotation> annotations = new LinkedList<TCFAnnotation>();
void dispose() {
for (TCFAnnotation a : annotations) a.dispose();
@@ -92,6 +126,9 @@ public class TCFAnnotationManager {
private final HashMap<IWorkbenchWindow,WorkbenchWindowInfo> windows =
new HashMap<IWorkbenchWindow,WorkbenchWindowInfo>();
+ private final HashSet<IWorkbenchWindow> dirty_windows = new HashSet<IWorkbenchWindow>();
+ private final HashSet<TCFLaunch> dirty_launches = new HashSet<TCFLaunch>();
+
private final TCFLaunch.LaunchListener launch_listener = new TCFLaunch.LaunchListener() {
public void onCreated(TCFLaunch launch) {
@@ -99,26 +136,17 @@ public class TCFAnnotationManager {
public void onConnected(final TCFLaunch launch) {
updateActiveLaunch();
+ updateAnnotations(null, launch);
TCFBreakpointsStatus bps = launch.getBreakpointsStatus();
if (bps == null) return;
bps.addListener(new ITCFBreakpointListener() {
public void breakpointStatusChanged(String id) {
- displayExec(new Runnable() {
- public void run() {
- if (active_launch != launch) return;
- refreshBreakpointView();
- }
- });
+ updateAnnotations(null, launch);
}
public void breakpointRemoved(String id) {
- displayExec(new Runnable() {
- public void run() {
- if (active_launch != launch) return;
- refreshBreakpointView();
- }
- });
+ updateAnnotations(null, launch);
}
public void breakpointChanged(String id) {
@@ -128,22 +156,8 @@ public class TCFAnnotationManager {
public void onDisconnected(final TCFLaunch launch) {
assert Protocol.isDispatchThread();
- synchronized (Device.class) {
- displayExec(new Runnable() {
- public void run() {
- for (WorkbenchWindowInfo info : windows.values()) {
- for (Iterator<TCFAnnotation> i = info.annotations.iterator(); i.hasNext();) {
- TCFAnnotation a = i.next();
- if (a.model.getLaunch() == launch) {
- i.remove();
- a.dispose();
- }
- }
- }
- }
- });
- }
updateActiveLaunch();
+ updateAnnotations(null, launch);
}
public void onProcessOutput(TCFLaunch launch, String process_id, int stream_id, byte[] data) {
@@ -158,6 +172,7 @@ public class TCFAnnotationManager {
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
updateActiveLaunch();
+ updateAnnotations(part.getSite().getWorkbenchWindow(), (TCFLaunch)null);
}
};
@@ -185,12 +200,13 @@ public class TCFAnnotationManager {
IDebugUIConstants.ID_DEBUG_VIEW, selection_listener);
windows.put(window, new WorkbenchWindowInfo());
updateActiveLaunch();
+ updateAnnotations(window, (TCFLaunch)null);
}
};
private final Display display = Display.getDefault();
- private int refresh_breakpoint_view_cnt = 0;
private int update_active_launch_cnt = 0;
+ private int update_unnotations_cnt = 0;
private boolean started;
private boolean disposed;
@@ -253,35 +269,12 @@ public class TCFAnnotationManager {
if (adaptable != null) {
ILaunch x = (ILaunch)adaptable.getAdapter(ILaunch.class);
if (x instanceof TCFLaunch) {
- final TCFLaunch l = (TCFLaunch)x;
- final boolean[] b = new boolean[1];
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- IChannel channel = l.getChannel();
- b[0] = channel != null && channel.getState() == IChannel.STATE_OPEN;
- }
- });
- if (b[0]) launch = l;
+ TCFLaunch l = (TCFLaunch)x;
+ IChannel channel = l.getChannel();
+ if (channel != null && channel.getState() == IChannel.STATE_OPEN) launch = l;
}
}
- if (active_launch != launch) {
- active_launch = launch;
- refreshBreakpointView();
- }
- }
- });
- }
-
- private void refreshBreakpointView() {
- assert !disposed;
- final int cnt = ++refresh_breakpoint_view_cnt;
- displayExec(new Runnable() {
- public void run() {
- if (cnt != refresh_breakpoint_view_cnt) return;
- for (IWorkbenchWindow window : windows.keySet()) {
- IDebugView view = (IDebugView)window.getActivePage().findView(IDebugUIConstants.ID_BREAKPOINT_VIEW);
- if (view != null) view.getViewer().refresh();
- }
+ active_launch = launch;
}
});
}
@@ -290,7 +283,7 @@ public class TCFAnnotationManager {
assert Protocol.isDispatchThread();
if (disposed) return null;
final TCFLaunch launch = active_launch;
- if (launch != null && launch.getBreakpointsStatus() != null) {
+ if (launch != null) {
TCFBreakpointsStatus bs = launch.getBreakpointsStatus();
if (bs != null) {
Map<String,Object> map = bs.getStatus(breakpoint);
@@ -307,74 +300,273 @@ public class TCFAnnotationManager {
return null;
}
- void addStackFrameAnnotation(TCFModel model, String exe_id, boolean top_frame,
- IWorkbenchPage page, ITextEditor editor, IRegion region) {
- if (disposed) return;
- assert Thread.currentThread() == display.getThread();
- TCFAnnotation annotation = null;
- IAnnotationModel ann_model = null;
+ @SuppressWarnings("unchecked")
+ private Object[] toObjectArray(Object o) {
+ if (o == null) return null;
+ Collection<Object> c = (Collection<Object>)o;
+ return (Object[])c.toArray(new Object[c.size()]);
+ }
- if (editor != null && region != null) {
- IDocumentProvider doc_provider = editor.getDocumentProvider();
- IEditorInput editor_input = editor.getEditorInput();
- ann_model = doc_provider.getAnnotationModel(editor_input);
- if (ann_model != null) {
- String type;
- String text;
- Image image;
- if (top_frame) {
- type = "org.eclipse.tm.tcf.debug.top_frame"; //$NON-NLS-1$
- text = "Debug Current Instruction Pointer"; //$NON-NLS-1$
- image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER_TOP);
- }
- else {
- type = "org.eclipse.tm.tcf.debug.stack_frame"; //$NON-NLS-1$
- text = "Debug Stack Frame"; //$NON-NLS-1$
- image = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER);
- }
- annotation = new TCFAnnotation(model, exe_id, editor, image,
- new Position(region.getOffset(), region.getLength()));
- annotation.setType(type);
- annotation.setText(text);
+ @SuppressWarnings("unchecked")
+ private Map<String,Object> toObjectMap(Object o) {
+ return (Map<String,Object>)o;
+ }
+
+ private BigInteger toBigInteger(Number n) {
+ if (n == null) return null;
+ if (n instanceof BigInteger) return (BigInteger)n;
+ return new BigInteger(n.toString());
+ }
+
+ private void addBreakpointErrorAnnotation(List<TCFAnnotation> set, TCFLaunch launch, String id, String error) {
+ Map<String,Object> props = launch.getBreakpointsStatus().getProperties(id);
+ if (props != null) {
+ String file = (String)props.get(IBreakpoints.PROP_FILE);
+ Number line = (Number)props.get(IBreakpoints.PROP_LINE);
+ if (file != null && line != null) {
+ ILineNumbers.CodeArea area = new ILineNumbers.CodeArea(null, file,
+ line.intValue(), 0, line.intValue() + 1, 0,
+ null, null, 0, false, false, false, false);
+ TCFAnnotation a = new TCFAnnotation(area,
+ ImageCache.getImage(ImageCache.IMG_BREAKPOINT_ERROR),
+ "Cannot plant breakpoint: " + error);
+ a.setType("org.eclipse.tm.tcf.debug.breakpoint_instance"); //$NON-NLS-1$
+ set.add(a);
}
}
+ }
- if (page != null) {
- WorkbenchWindowInfo info = windows.get(page.getWorkbenchWindow());
- if (info != null) {
- if (annotation != null && info.annotations.size() == 1) {
- for (TCFAnnotation a : info.annotations) {
- if (a.model != annotation.model) continue;
- if (a.editor != annotation.editor) continue;
- if (a.image != annotation.image) continue;
- if (!a.exe_id.equals(annotation.exe_id)) continue;
- if (!a.position.equals(annotation.position)) continue;
- if (!a.getType().equals(annotation.getType())) continue;
- if (!a.getText().equals(annotation.getText())) continue;
+ private void updateAnnotations(IWorkbenchWindow window, final TCFNode node) {
+ if (disposed) return;
+ assert Thread.currentThread() == display.getThread();
+ final WorkbenchWindowInfo win_info = windows.get(window);
+ if (win_info == null) return;
+ List<TCFAnnotation> set = null;
+ if (node != null) {
+ set = new TCFTask<List<TCFAnnotation>>(node.getChannel()) {
+ public void run() {
+ if (node.isDisposed()) {
+ done(null);
return;
}
+ TCFNodeExecContext thread = null;
+ TCFNodeExecContext memory = null;
+ TCFNodeStackFrame frame = null;
+ String bp_group = null;
+ if (node instanceof TCFNodeStackFrame) {
+ thread = (TCFNodeExecContext)node.getParent();
+ frame = (TCFNodeStackFrame)node;
+ }
+ else if (node instanceof TCFNodeExecContext) {
+ thread = (TCFNodeExecContext)node;
+ TCFChildrenStackTrace trace = thread.getStackTrace();
+ if (!trace.validate(this)) return;
+ frame = trace.getTopFrame();
+ }
+ if (thread != null) {
+ TCFDataCache<IRunControl.RunControlContext> rc_ctx_cache = thread.getRunContext();
+ if (!rc_ctx_cache.validate(this)) return;
+ IRunControl.RunControlContext rc_ctx_data = rc_ctx_cache.getData();
+ if (rc_ctx_data != null) bp_group = rc_ctx_data.getBPGroup();
+ TCFDataCache<TCFNodeExecContext> mem_cache = thread.getMemoryNode();
+ if (!mem_cache.validate(this)) return;
+ memory = mem_cache.getData();
+ }
+ List<TCFAnnotation> set = new ArrayList<TCFAnnotation>();
+ if (memory != null) {
+ TCFLaunch launch = node.getModel().getLaunch();
+ TCFBreakpointsStatus bs = launch.getBreakpointsStatus();
+ if (bs != null) {
+ for (String id : bs.getStatusIDs()) {
+ Map<String,Object> map = bs.getStatus(id);
+ if (map == null) continue;
+ String error = (String)map.get(IBreakpoints.STATUS_ERROR);
+ if (error != null) addBreakpointErrorAnnotation(set, launch, id, error);
+ Object[] arr = toObjectArray(map.get(IBreakpoints.STATUS_INSTANCES));
+ if (arr == null) continue;
+ for (Object o : arr) {
+ Map<String,Object> m = toObjectMap(o);
+ String ctx_id = (String)m.get(IBreakpoints.INSTANCE_CONTEXT);
+ if (ctx_id == null) continue;
+ if (!ctx_id.equals(node.getID()) && !ctx_id.equals(bp_group)) continue;
+ error = (String)m.get(IBreakpoints.INSTANCE_ERROR);
+ BigInteger addr = toBigInteger((Number)m.get(IBreakpoints.INSTANCE_ADDRESS));
+ if (addr != null) {
+ ILineNumbers.CodeArea area = null;
+ TCFDataCache<TCFSourceRef> line_cache = memory.getLineInfo(addr);
+ if (line_cache != null) {
+ if (!line_cache.validate(this)) return;
+ TCFSourceRef line_data = line_cache.getData();
+ if (line_data != null && line_data.area != null) area = line_data.area;
+ }
+ if (area == null) {
+ Map<String,Object> props = launch.getBreakpointsStatus().getProperties(id);
+ if (props != null) {
+ String file = (String)props.get(IBreakpoints.PROP_FILE);
+ Number line = (Number)props.get(IBreakpoints.PROP_LINE);
+ if (file != null && line != null) {
+ area = new ILineNumbers.CodeArea(null, file,
+ line.intValue(), 0, line.intValue() + 1, 0,
+ null, null, 0, false, false, false, false);
+ }
+ }
+ }
+ if (area != null) {
+ if (error != null) {
+ TCFAnnotation a = new TCFAnnotation(area,
+ ImageCache.getImage(ImageCache.IMG_BREAKPOINT_ERROR),
+ "Cannot plant breakpoint at 0x" + addr.toString(16) + ": " + error);
+ a.setType("org.eclipse.tm.tcf.debug.breakpoint_instance"); //$NON-NLS-1$
+ set.add(a);
+ error = null;
+ }
+ else {
+ TCFAnnotation a = new TCFAnnotation(area,
+ ImageCache.getImage(ImageCache.IMG_BREAKPOINT_INSTALLED),
+ "Breakpoint planted at 0x" + addr.toString(16));
+ a.setType("org.eclipse.tm.tcf.debug.breakpoint_instance"); //$NON-NLS-1$
+ set.add(a);
+ }
+ }
+ }
+ if (error != null) addBreakpointErrorAnnotation(set, launch, id, error);
+ }
+ }
+ }
+ }
+ if (frame != null && frame.getFrameNo() >= 0) {
+ TCFDataCache<TCFSourceRef> line_cache = frame.getLineInfo();
+ if (!line_cache.validate(this)) return;
+ TCFSourceRef line_data = line_cache.getData();
+ if (line_data != null && line_data.area != null) {
+ TCFAnnotation a = null;
+ if (frame.getFrameNo() == 0) {
+ a = new TCFAnnotation(line_data.area,
+ DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER_TOP),
+ "Current Instruction Pointer");
+ a.setType("org.eclipse.tm.tcf.debug.top_frame"); //$NON-NLS-1$
+ }
+ else {
+ a = new TCFAnnotation(line_data.area,
+ DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER),
+ "Stack Frame");
+ a.setType("org.eclipse.tm.tcf.debug.stack_frame"); //$NON-NLS-1$
+ }
+ set.add(a);
+ }
+ }
+ done(set);
}
- for (TCFAnnotation a : info.annotations) a.dispose();
- info.annotations.clear();
- if (annotation != null) {
- ann_model.addAnnotation(annotation, annotation.position);
- info.annotations.add(annotation);
+ }.getE();
+ }
+ Iterator<TCFAnnotation> i = win_info.annotations.iterator();
+ while (i.hasNext()) {
+ TCFAnnotation a = i.next();
+ if (set != null && set.remove(a)) continue;
+ a.dispose();
+ i.remove();
+ }
+ if (set == null || set.size() == 0) return;
+ Map<IEditorInput,ITextEditor> editors = new HashMap<IEditorInput,ITextEditor>();
+ for (IEditorReference ref : window.getActivePage().getEditorReferences()) {
+ IEditorPart part = ref.getEditor(false);
+ if (!(part instanceof ITextEditor)) continue;
+ ITextEditor editor = (ITextEditor)part;
+ editors.put(editor.getEditorInput(), editor);
+ }
+ ISourceLocator locator = node.getModel().getLaunch().getSourceLocator();
+ ISourcePresentation presentation = TCFModelPresentation.getDefault();
+ for (TCFAnnotation a : set) {
+ Object source_element = null;
+ if (locator instanceof TCFSourceLookupDirector) {
+ source_element = ((TCFSourceLookupDirector)locator).getSourceElement(a.area);
+ }
+ else if (locator instanceof ISourceLookupDirector) {
+ // support for foreign (CDT) source locator
+ String filename = TCFSourceLookupParticipant.toFileName(a.area);
+ if (filename != null) {
+ source_element = ((ISourceLookupDirector)locator).getSourceElement(filename);
+ if (source_element == null && !filename.equals(a.area.file)) {
+ // retry with relative path
+ source_element = ((ISourceLookupDirector)locator).getSourceElement(a.area.file);
+ }
}
}
+ if (source_element == null) continue;
+ IEditorInput editor_input = presentation.getEditorInput(source_element);
+ ITextEditor editor = editors.get(editor_input);
+ if (editor == null) continue;
+ IDocumentProvider doc_provider = editor.getDocumentProvider();
+ IAnnotationModel ann_model = doc_provider.getAnnotationModel(editor_input);
+ if (ann_model == null) continue;
+ IRegion region = null;
+ try {
+ doc_provider.connect(editor_input);
+ }
+ catch (CoreException e) {
+ }
+ try {
+ IDocument document = doc_provider.getDocument(editor_input);
+ if (document != null) region = document.getLineInformation(a.area.start_line - 1);
+ }
+ catch (BadLocationException e) {
+ }
+ finally {
+ doc_provider.disconnect(editor_input);
+ }
+ if (region == null) continue;
+ ann_model.addAnnotation(a, new Position(region.getOffset(), region.getLength()));
+ a.model = ann_model;
+ win_info.annotations.add(a);
}
}
- void removeStackFrameAnnotation(TCFModel model, Set<String> ids) {
- if (disposed) return;
- assert Thread.currentThread() == display.getThread();
- for (WorkbenchWindowInfo info : windows.values()) {
- for (Iterator<TCFAnnotation> i = info.annotations.iterator(); i.hasNext();) {
- TCFAnnotation a = i.next();
- if (a.model == model && ids.contains(a.exe_id)) {
- i.remove();
- a.dispose();
+ private void updateAnnotations() {
+ final int cnt = ++update_unnotations_cnt;
+ displayExec(new Runnable() {
+ public void run() {
+ TCFNode node = null;
+ if (cnt != update_unnotations_cnt) return;
+ for (IWorkbenchWindow window : windows.keySet()) {
+ if (dirty_windows.contains(null) || dirty_windows.contains(window)) {
+ try {
+ ISelection active_context = DebugUITools.getDebugContextManager()
+ .getContextService(window).getActiveContext();
+ if (active_context instanceof IStructuredSelection) {
+ IStructuredSelection selection = (IStructuredSelection)active_context;
+ if (!selection.isEmpty()) {
+ Object first_element = selection.getFirstElement();
+ if (first_element instanceof IAdaptable) {
+ node = (TCFNode)((IAdaptable)first_element).getAdapter(TCFNode.class);
+ }
+ }
+ }
+ if (dirty_launches.contains(null) || node != null && dirty_launches.contains(node.getModel().getLaunch())) {
+ updateAnnotations(window, node);
+ }
+ }
+ catch (Throwable x) {
+ if (node != null && node.isDisposed()) return;
+ Activator.log("Cannot update editor annotations", x);
+ }
+ }
+ }
+ for (TCFLaunch launch : dirty_launches) {
+ if (launch != null) launch.removePendingClient(TCFAnnotationManager.this);
}
+ dirty_windows.clear();
+ dirty_launches.clear();
}
- }
+ });
+ }
+
+ void updateAnnotations(final IWorkbenchWindow window, final TCFLaunch launch) {
+ displayExec(new Runnable() {
+ public void run() {
+ dirty_windows.add(window);
+ dirty_launches.add(launch);
+ updateAnnotations();
+ }
+ });
}
}
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 3cfeffdf2..c2af3b391 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
@@ -275,22 +275,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
private final IModelSelectionPolicy selection_policy;
- private final HashSet<String> removed_annotations = new HashSet<String>();
- private boolean removed_annotations_posted;
- private final Runnable removed_annotations_runnable = new Runnable() {
- public void run() {
- HashSet<String> set = null;
- synchronized (removed_annotations) {
- assert removed_annotations_posted;
- removed_annotations_posted = false;
- if (removed_annotations.size() == 0) return;
- set = new HashSet<String>(removed_annotations);
- removed_annotations.clear();
- }
- annotation_manager.removeStackFrameAnnotation(TCFModel.this, set);
- }
- };
-
private IChannel channel;
private TCFNodeLaunch launch_node;
private boolean disposed;
@@ -345,7 +329,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
((TCFNodeExecContext)node).onContainerResumed();
}
}
- for (String id : context_ids) removeAnnotation(id);
+ annotation_manager.updateAnnotations(null, launch);
}
public void containerSuspended(String context, String pc, String reason,
@@ -415,7 +399,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onContextResumed();
}
- removeAnnotation(id);
+ annotation_manager.updateAnnotations(null, launch);
}
public void contextSuspended(String id, String pc, String reason, Map<String,Object> params) {
@@ -520,7 +504,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
public void onContextActionStart(TCFAction action) {
final String id = action.getContextID();
active_actions.put(id, action);
- removeAnnotation(id);
+ annotation_manager.updateAnnotations(null, launch);
}
public void onContextActionResult(String id, String reason) {
@@ -801,7 +785,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
launch_node.onAnyContextAddedOrRemoved();
// Close debug session if the last context is removed:
onContextOrProcessRemoved();
- for (String id : context_ids) removeAnnotation(id);
+ annotation_manager.updateAnnotations(null, launch);
}
private void onContextOrProcessRemoved() {
@@ -1240,12 +1224,8 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
}
if (source_element != null) {
ISourcePresentation presentation = TCFModelPresentation.getDefault();
- if (presentation != null) {
- editor_input = presentation.getEditorInput(source_element);
- }
- if (editor_input != null) {
- editor_id = presentation.getEditorId(editor_input, source_element);
- }
+ editor_input = presentation.getEditorInput(source_element);
+ if (editor_input != null) editor_id = presentation.getEditorId(editor_input, source_element);
line = area.start_line;
}
}
@@ -1289,8 +1269,8 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
region = getLineInformation(text_editor, line);
if (region != null) text_editor.selectAndReveal(region.getOffset(), 0);
}
- annotation_manager.addStackFrameAnnotation(TCFModel.this,
- exe_id, top_frame, page, text_editor, region);
+ if (wait_for_pc_update_after_step) launch.addPendingClient(annotation_manager);
+ annotation_manager.updateAnnotations(page.getWorkbenchWindow(), launch);
}
finally {
if (cnt == display_source_generation) launch.removePendingClient(TCFModel.this);
@@ -1299,17 +1279,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
});
}
- /* Remove editor annotations for given executable context ID */
- private void removeAnnotation(String id) {
- synchronized (removed_annotations) {
- removed_annotations.add(id);
- if (!removed_annotations_posted) {
- display.asyncExec(removed_annotations_runnable);
- removed_annotations_posted = true;
- }
- }
- }
-
/*
* Refresh Launch View.
* Normally the view is updated by sending deltas through model proxy.
@@ -1426,7 +1395,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
/*
* Returns the line information for the given line in the given editor
*/
- private IRegion getLineInformation(ITextEditor editor, int lineNumber) {
+ private IRegion getLineInformation(ITextEditor editor, int line) {
IDocumentProvider provider = editor.getDocumentProvider();
IEditorInput input = editor.getEditorInput();
try {
@@ -1437,8 +1406,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
}
try {
IDocument document = provider.getDocument(input);
- if (document != null)
- return document.getLineInformation(lineNumber - 1);
+ if (document != null) return document.getLineInformation(line - 1);
}
catch (BadLocationException e) {
}
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 f2b51b29d..c0cd8c27a 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
@@ -168,6 +168,11 @@ public class TCFNodeStackFrame extends TCFNode {
};
}
+ /**
+ * Get frame position in the parent's stack trace.
+ * Top frame position is 0.
+ * @return frame position or -1 if the frame is not part of the trace.
+ */
public int getFrameNo() {
assert Protocol.isDispatchThread();
return frame_no;
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java
index b6125ae5e..3e3d289c1 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/launch/TCFSourceLookupParticipant.java
@@ -125,7 +125,7 @@ public class TCFSourceLookupParticipant extends AbstractSourceLookupParticipant
int j = name.lastIndexOf('\\');
if (i > j) base = name.substring(i + 1);
if (j > i) base = name.substring(j + 1);
- res = super.findSourceElements(base);
+ if (!base.equals(name)) res = super.findSourceElements(base);
}
}
ArrayList<Object> list = new ArrayList<Object>();
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsStatus.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsStatus.java
index a41b1d9fe..bf73c1938 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsStatus.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsStatus.java
@@ -26,6 +26,7 @@ import org.eclipse.tm.tcf.services.IBreakpoints;
public class TCFBreakpointsStatus {
private final IBreakpoints service;
+ private final Map<String,Map<String,Object>> breakpoints = new HashMap<String,Map<String,Object>>();
private final Map<String,Map<String,Object>> status = new HashMap<String,Map<String,Object>>();
private final Set<ITCFBreakpointListener> listeners = new HashSet<ITCFBreakpointListener>();
@@ -53,6 +54,7 @@ public class TCFBreakpointsStatus {
public void contextAdded(Map<String,Object>[] bps) {
for (Map<String,Object> bp : bps) {
String id = (String)bp.get(IBreakpoints.PROP_ID);
+ breakpoints.put(id, bp);
if (status.get(id) != null) continue;
status.put(id, new HashMap<String,Object>());
for (Iterator<ITCFBreakpointListener> i = listeners.iterator(); i.hasNext();) {
@@ -64,6 +66,7 @@ public class TCFBreakpointsStatus {
public void contextChanged(Map<String,Object>[] bps) {
for (Map<String,Object> bp : bps) {
String id = (String)bp.get(IBreakpoints.PROP_ID);
+ breakpoints.put(id, bp);
if (!status.containsKey(id)) continue;
for (Iterator<ITCFBreakpointListener> i = listeners.iterator(); i.hasNext();) {
i.next().breakpointChanged(id);
@@ -73,6 +76,7 @@ public class TCFBreakpointsStatus {
public void contextRemoved(String[] ids) {
for (String id : ids) {
+ breakpoints.remove(id);
if (!status.containsKey(id)) continue;
for (Iterator<ITCFBreakpointListener> i = listeners.iterator(); i.hasNext();) {
i.next().breakpointRemoved(id);
@@ -89,13 +93,16 @@ public class TCFBreakpointsStatus {
public void doneGetIDs(IToken token, Exception error, String[] ids) {
if (error != null) return;
for (final String id : ids) {
- // fake properties - only ID is required for contextAdded
- Map<String, Object> bpProps = new HashMap<String, Object>();
- bpProps.put(IBreakpoints.PROP_ID, id);
- listener.contextAdded((Map<String, Object>[]) new Map[] { bpProps });
- service.getStatus(id, new IBreakpoints.DoneGetStatus() {
- public void doneGetStatus(IToken token, Exception error, Map<String, Object> status) {
- if (error == null) listener.breakpointStatusChanged(id, status);
+ service.getProperties(id, new IBreakpoints.DoneGetProperties() {
+ public void doneGetProperties(IToken token, Exception error, Map<String, Object> props) {
+ if (error == null) {
+ listener.contextAdded((Map<String, Object>[]) new Map[] { props });
+ service.getStatus(id, new IBreakpoints.DoneGetStatus() {
+ public void doneGetStatus(IToken token, Exception error, Map<String, Object> status) {
+ if (error == null) listener.breakpointStatusChanged(id, status);
+ }
+ });
+ }
}
});
}
@@ -115,6 +122,12 @@ public class TCFBreakpointsStatus {
return status.get(id);
}
+ public Map<String,Object> getProperties(String id) {
+ assert id != null;
+ assert Protocol.isDispatchThread();
+ return breakpoints.get(id);
+ }
+
public Map<String,Object> getStatus(IBreakpoint bp) {
try {
String id = TCFBreakpointsModel.getBreakpointsModel().getBreakpointID(bp);

Back to the top