diff options
author | aleherbau | 2011-05-05 07:19:36 +0000 |
---|---|---|
committer | aleherbau | 2011-05-05 07:19:36 +0000 |
commit | 837458856781c52e4b635897c787180c15b58ce6 (patch) | |
tree | 15e213d24e07ad0e2309a13e5f9dd92689147c67 | |
parent | dd1b024f2acacb34a65d888f7ebda661f263563b (diff) | |
download | org.eclipse.tcf-837458856781c52e4b635897c787180c15b58ce6.tar.gz org.eclipse.tcf-837458856781c52e4b635897c787180c15b58ce6.tar.xz org.eclipse.tcf-837458856781c52e4b635897c787180c15b58ce6.zip |
TCF Debugger: Add Watchpoint in Editor and Variables/Expressions view
9 files changed, 267 insertions, 32 deletions
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/icons/obj16/funbrkp_obj.gif b/plugins/org.eclipse.tm.tcf.cdt.ui/icons/obj16/funbrkp_obj.gif Binary files differdeleted file mode 100644 index 7bb768925..000000000 --- a/plugins/org.eclipse.tm.tcf.cdt.ui/icons/obj16/funbrkp_obj.gif +++ /dev/null diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.properties b/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.properties index e606504da..a2e03adb8 100644 --- a/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.properties +++ b/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.properties @@ -29,3 +29,13 @@ launchDelegate.remoteApplication.name=TCF Remote Process launchDelegate.remoteApplication.description=Start new application on a remote system under control of a remote TCF agent. launchDelegate.attach.name=TCF Attach to Process launchDelegate.attach.description=Attach to a running local or remote program. + +action.addWatchpoint.label=Add Watchpoint (C/C++)... + +command.addFunctionBreakpoint.name=Add Function Breakpoint (C/C++) +command.addFunctionBreakpoint.desc=Allows to add a new function breakpoint on an arbitrary symbol +command.addWatchpoint.name=Add Watchpoint (C/C++) +command.addWatchpoint.desc=Allows to add a new watchpoint on an arbitrary symbol + +item.addFunctionBreakpoint.name=Add Function Breakpoint (C/C++)... +item.addWatchpoint.name=Add Watchpoint... diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.xml b/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.xml index 8025f0fa0..62a22b176 100644 --- a/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.xml +++ b/plugins/org.eclipse.tm.tcf.cdt.ui/plugin.xml @@ -28,30 +28,15 @@ <factory adaptableType="org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode" class="org.eclipse.tm.internal.tcf.cdt.ui.TCFNodeAdapterFactory"> - <adapter - type="org.eclipse.cdt.debug.core.model.ISteppingModeTarget"> - </adapter> - <adapter - type="org.eclipse.debug.core.model.ISuspendResume"> - </adapter> - <adapter - type="org.eclipse.cdt.ui.text.c.hover.ICEditorTextHover"> - </adapter> - <adapter - type="org.eclipse.cdt.debug.core.model.IReverseToggleHandler"> - </adapter> - <adapter - type="org.eclipse.cdt.debug.core.model.IReverseStepIntoHandler"> - </adapter> - <adapter - type="org.eclipse.cdt.debug.core.model.IReverseStepOverHandler"> - </adapter> - <adapter - type="org.eclipse.cdt.debug.core.model.IReverseResumeHandler"> - </adapter> - <adapter - type="org.eclipse.cdt.debug.core.model.IUncallHandler"> - </adapter> + <adapter type="org.eclipse.cdt.debug.core.model.ISteppingModeTarget"/> + <adapter type="org.eclipse.debug.core.model.ISuspendResume"/> + <adapter type="org.eclipse.cdt.ui.text.c.hover.ICEditorTextHover"/> + <adapter type="org.eclipse.cdt.debug.core.model.IReverseToggleHandler"/> + <adapter type="org.eclipse.cdt.debug.core.model.IReverseStepIntoHandler"/> + <adapter type="org.eclipse.cdt.debug.core.model.IReverseStepOverHandler"/> + <adapter type="org.eclipse.cdt.debug.core.model.IReverseResumeHandler"/> + <adapter type="org.eclipse.cdt.debug.core.model.IUncallHandler"/> + <adapter type="org.eclipse.cdt.debug.internal.core.ICWatchpointTarget"/> </factory> </extension> @@ -288,16 +273,25 @@ plugin="org.eclipse.tm.tcf.cdt.core"> </statusHandler> </extension> + <extension point="org.eclipse.ui.commands"> <command categoryId="org.eclipse.debug.ui.category.run" defaultHandler="org.eclipse.tm.internal.tcf.cdt.ui.commands.AddFunctionBreakointHandler" - description="Allows to add a new function breakpoint on an arbitrary symbol" + description="%command.addFunctionBreakpoint.desc" id="org.eclipse.tm.tcf.cdt.ui.add_function_breakpoint" - name="Add Function Breakpoint"> + name="%command.addFunctionBreakpoint.name"> + </command> + <command + categoryId="org.eclipse.debug.ui.category.run" + defaultHandler="org.eclipse.tm.internal.tcf.cdt.ui.commands.AddWatchpointHandler" + description="%command.addWatchpoint.desc" + id="org.eclipse.tm.tcf.cdt.ui.add_watchpoint" + name="%command.addWatchpoint.name"> </command> </extension> + <extension point="org.eclipse.ui.menus"> <menuContribution @@ -305,12 +299,44 @@ locationURI="menu:org.eclipse.debug.ui.BreakpointView?after=additions"> <command commandId="org.eclipse.tm.tcf.cdt.ui.add_function_breakpoint" - icon="icons/obj16/funbrkp_obj.gif" + icon="platform:/plugin/org.eclipse.cdt.debug.ui/icons/obj16/funbrkp_obj.gif" id="org.eclipse.tm.tcf.cdt.ui.add_function_breakpoint" - label="Add Function Breakpoint (C/C++)..." + label="%item.addFunctionBreakpoint.name" + style="push"> + </command> + </menuContribution> + <menuContribution + allPopups="false" + locationURI="popup:#CEditorContext?after=group.debug"> + <command + commandId="org.eclipse.tm.tcf.cdt.ui.add_watchpoint" + icon="platform:/plugin/org.eclipse.cdt.debug.ui/icons/elcl16/watchpoint_co.gif" + id="org.eclipse.tm.tcf.cdt.ui.add_watchpoint.editor" + label="%item.addWatchpoint.name" style="push"> + <visibleWhen checkEnabled="false"> + <with variable="activeContexts"> + <iterate ifEmpty="false" operator="or"> + <equals value="org.eclipse.tm.tcf.debug.ui.debugging"/> + </iterate> + </with> + </visibleWhen> </command> </menuContribution> </extension> + <extension point="org.eclipse.ui.popupMenus"> + <objectContribution + objectClass="org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExpression" + id="org.eclipse.tcf.cdt.ui.WatchpointActions"> + <action + class="org.eclipse.cdt.debug.internal.ui.actions.AddWatchpointOnVariableActionDelegate" + enablesFor="1" + icon="platform:/plugin/org.eclipse.cdt.debug.ui/icons/elcl16/watchpoint_co.gif" + id="org.eclipse.tcf.cdt.ui.actions.AddWatchpointOnVariable" + label="%action.addWatchpoint.label" + menubarPath="additions"/> + </objectContribution> + </extension> + </plugin> diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/TCFNodeAdapterFactory.java b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/TCFNodeAdapterFactory.java index e89edb5e7..d5fcb0ad4 100644 --- a/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/TCFNodeAdapterFactory.java +++ b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/TCFNodeAdapterFactory.java @@ -1,5 +1,5 @@ /*******************************************************************************
- * Copyright (c) 2010 Wind River Systems, Inc. and others.
+ * Copyright (c) 2010, 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
@@ -16,9 +16,11 @@ import org.eclipse.cdt.debug.core.model.IReverseStepOverHandler; import org.eclipse.cdt.debug.core.model.IReverseToggleHandler;
import org.eclipse.cdt.debug.core.model.ISteppingModeTarget;
import org.eclipse.cdt.debug.core.model.IUncallHandler;
+import org.eclipse.cdt.debug.internal.core.ICWatchpointTarget;
import org.eclipse.cdt.ui.text.c.hover.ICEditorTextHover;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.debug.core.model.ISuspendResume;
+import org.eclipse.tm.internal.tcf.cdt.ui.breakpoints.TCFWatchpointTarget;
import org.eclipse.tm.internal.tcf.cdt.ui.commands.TCFReverseResumeCommand;
import org.eclipse.tm.internal.tcf.cdt.ui.commands.TCFReverseStepIntoCommand;
import org.eclipse.tm.internal.tcf.cdt.ui.commands.TCFReverseStepOverCommand;
@@ -28,10 +30,11 @@ import org.eclipse.tm.internal.tcf.cdt.ui.hover.TCFDebugTextHover; import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExpression;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
import org.eclipse.tm.tcf.util.TCFTask;
-@SuppressWarnings("rawtypes")
+@SuppressWarnings({ "rawtypes", "restriction" })
public class TCFNodeAdapterFactory implements IAdapterFactory {
private static final Class<?>[] CLASSES = {
@@ -42,7 +45,8 @@ public class TCFNodeAdapterFactory implements IAdapterFactory { IReverseStepIntoHandler.class,
IReverseStepOverHandler.class,
IReverseResumeHandler.class,
- IUncallHandler.class
+ IUncallHandler.class,
+ ICWatchpointTarget.class
};
public Object getAdapter(Object adaptableObject, Class adapterType) {
@@ -109,6 +113,10 @@ public class TCFNodeAdapterFactory implements IAdapterFactory { model.setAdapter(adapterType, handler = new TCFReverseResumeCommand(model));
}
return handler;
+ } else if (ICWatchpointTarget.class == adapterType) {
+ if (node instanceof TCFNodeExpression) {
+ return new TCFWatchpointTarget((TCFNodeExpression) node);
+ }
}
}
return null;
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/breakpoints/TCFWatchpointTarget.java b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/breakpoints/TCFWatchpointTarget.java new file mode 100644 index 000000000..d93ff0a78 --- /dev/null +++ b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/breakpoints/TCFWatchpointTarget.java @@ -0,0 +1,59 @@ +/*******************************************************************************
+ * Copyright (c) 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.cdt.ui.breakpoints;
+
+import org.eclipse.cdt.debug.internal.core.ICWatchpointTarget;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExpression;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ISymbols;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
+
+/**
+ * TCF "Add Watchpoint" target implementation.
+ */
+@SuppressWarnings("restriction")
+public class TCFWatchpointTarget implements ICWatchpointTarget {
+
+ private final TCFNodeExpression fNode;
+
+ public TCFWatchpointTarget(TCFNodeExpression node) {
+ fNode = node;
+ }
+
+ public void canSetWatchpoint(CanCreateWatchpointRequest request) {
+ request.setCanCreate(true);
+ request.done();
+ }
+
+ public String getExpression() {
+ final TCFDataCache<String> expressionText = fNode.getExpressionText();
+ String expr = new TCFTask<String>(fNode.getChannel()) {
+ public void run() {
+ if (!expressionText.validate(this)) return;
+ done(expressionText.getData());
+ }
+ }.getE();
+ return expr != null ? expr : "";
+ }
+
+ public void getSize(final GetSizeRequest request) {
+ final TCFDataCache<ISymbols.Symbol> expressionType = fNode.getType();
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ if (!expressionType.validate(this)) return;
+ ISymbols.Symbol type = expressionType.getData();
+ request.setSize(type != null ? type.getSize() : 1);
+ request.done();
+ }
+ });
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/commands/AddWatchpointHandler.java b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/commands/AddWatchpointHandler.java new file mode 100644 index 000000000..a53eb572b --- /dev/null +++ b/plugins/org.eclipse.tm.tcf.cdt.ui/src/org/eclipse/tm/internal/tcf/cdt/ui/commands/AddWatchpointHandler.java @@ -0,0 +1,55 @@ +/*******************************************************************************
+ * Copyright (c) 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tm.internal.tcf.cdt.ui.commands;
+
+import java.math.BigInteger;
+
+import org.eclipse.cdt.debug.core.CDIDebugModel;
+import org.eclipse.cdt.debug.internal.ui.actions.AddWatchpointDialog;
+import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+@SuppressWarnings("restriction")
+public class AddWatchpointHandler extends AbstractHandler {
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ String expr = null;
+ if (selection instanceof ITextSelection) {
+ expr = ((ITextSelection) selection).getText();
+ }
+ AddWatchpointDialog dlg = new AddWatchpointDialog(HandlerUtil.getActiveShell(event), null);
+ dlg.setExpression(expr);
+ if (dlg.open() == Window.OK) {
+ addWatchpoint(dlg.getWriteAccess(), dlg.getReadAccess(), dlg.getExpression(), dlg.getMemorySpace(), dlg.getRange());
+ }
+ return null;
+ }
+
+ private void addWatchpoint(boolean write, boolean read, String expression, String memorySpace, BigInteger range) {
+ IResource resource = ResourcesPlugin.getWorkspace().getRoot();
+ try {
+ CDIDebugModel.createWatchpoint("", resource, write, read, expression, memorySpace, range, true, 0, "", true); //$NON-NLS-1$
+ }
+ catch(CoreException ce) {
+ CDebugUIPlugin.errorDialog("Cannot add watchpoint.", ce);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml index 1d9366791..364af2165 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml +++ b/plugins/org.eclipse.tm.tcf.debug.ui/plugin.xml @@ -298,4 +298,10 @@ </renderingBindings> </extension> + <extension point="org.eclipse.debug.ui.debugModelContextBindings"> + <modelContextBinding + contextId="org.eclipse.tm.tcf.debug.ui.debugging" + debugModelId="org.eclipse.tm.tcf.debug"/> + </extension> + </plugin> 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 33aa7e324..331245c47 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 @@ -60,6 +60,7 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT private final TCFData<ISymbols.Symbol> type; private final TCFData<String> type_name; private final TCFData<String> string; + private final TCFData<String> expression_text; private final TCFChildrenSubExpressions children; private int sort_pos; private IExpressions.Value prev_value; @@ -419,6 +420,62 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT return true; } }; + expression_text = new TCFData<String>(channel) { + @Override + protected boolean startDataRetrieval() { + TCFDataCache<ISymbols.Symbol> field = model.getSymbolInfoCache(field_id); + TCFDataCache<?> pending = null; + if (field != null && !field.validate()) pending = field; + if (!var_expression.validate()) pending = var_expression; + if (!text.validate()) pending = text; + if (pending != null) { + pending.wait(this); + return false; + } + String parentName = ""; + if (parent instanceof TCFNodeExpression) { + TCFDataCache<String> parentText = ((TCFNodeExpression) parent).getExpressionText(); + if (!parentText.validate(this)) return false; + if (parentText.getData() != null) { + parentName = parenthesize(parentText.getData()); + } + } + String name = null; + if (index >= 0) { + if (index == 0 && deref) { + name = "*" + parentName; + } + else { + name = parentName + "[" + index + "]"; + } + } + if (name == null && field != null && field.getData() != null) { + name = parentName + (deref ? "->" : ".") + field.getData().getName(); + } + if (name == null && var_expression.getData() != null) { + TCFDataCache<ISymbols.Symbol> var = model.getSymbolInfoCache(var_expression.getData().getSymbolID()); + if (var != null) { + if (!var.validate(this)) return false; + if (var.getData() != null) name = var.getData().getName(); + } + } + if (name == null && text.getData() != null) name = text.getData(); + if (name != null) { + String cast = model.getCastToType(id); + if (cast != null) name = "(" + cast + ")(" + name + ")"; + } + set(null, null, name); + return true; + } + + private String parenthesize(String expr) { + // surround with parentheses if not a simple identifier + if (!expr.matches("\\w*")) { + return '(' + expr + ')'; + } + return expr; + } + }; children = new TCFChildrenSubExpressions(this, 0, 0, 0); } @@ -1336,4 +1393,8 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT } return super.getAdapter(adapter); } + + public TCFDataCache<String> getExpressionText() { + return expression_text; + } } diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java index d0a65394d..941b58813 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFBreakpointsModel.java @@ -432,7 +432,17 @@ public class TCFBreakpointsModel implements IBreakpointListener, IBreakpointMana if (readAccess) accessMode |= IBreakpoints.ACCESSMODE_READ; if (writeAccess) accessMode |= IBreakpoints.ACCESSMODE_WRITE; m.put(IBreakpoints.PROP_ACCESSMODE, Integer.valueOf(accessMode)); - m.put(IBreakpoints.PROP_LOCATION, "&(" + expr + ')'); + Object range = p.get("org.eclipse.cdt.debug.core.range"); + if (range != null) { + int size = Integer.parseInt(range.toString()); + if (size > 0) { + m.put(IBreakpoints.PROP_SIZE, size); + } + } + if (!Character.isDigit(expr.charAt(0))) { + expr = "&(" + expr + ')'; + } + m.put(IBreakpoints.PROP_LOCATION, expr); } } else if ("org.eclipse.cdt.debug.core.cFunctionBreakpointMarker".equals(type)) { |