diff options
Diffstat (limited to 'plugins')
7 files changed, 200 insertions, 50 deletions
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 9d397607a..d3b9339d9 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 @@ -52,7 +52,7 @@ public class TCFChildrenExpressions extends TCFChildren { for (final IExpression e : node.model.getExpressionManager().getExpressions()) { String text = e.getExpressionText(); TCFNodeExpression n = findScript(text); - if (n == null) add(n = new TCFNodeExpression(node, text, null, null, -1, false)); + if (n == null) add(n = new TCFNodeExpression(node, text, null, null, null, -1, false)); n.setSortPosition(cnt++); if (e instanceof IWatchExpression) n.setEnabled(((IWatchExpression)e).isEnabled()); data.put(n.id, n); diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenHoverExpressions.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenHoverExpressions.java index 45abb553b..705044bd2 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenHoverExpressions.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenHoverExpressions.java @@ -58,7 +58,7 @@ class TCFChildrenHoverExpressions extends TCFChildren { if (expression_script != null) { TCFNodeExpression expression_node = findScript(expression_script); if (expression_node == null) { - add(expression_node = new TCFNodeExpression(node, expression_script, null, null, -1, false)); + add(expression_node = new TCFNodeExpression(node, expression_script, null, null, null, -1, false)); } data.put(expression_node.id, expression_node); } diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java index 16b0ba6b2..2320cd4b3 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java @@ -65,7 +65,7 @@ public class TCFChildrenLocalVariables extends TCFChildren { data = new HashMap<String,TCFNode>(); for (String id : contexts) { TCFNodeExpression n = (TCFNodeExpression)node.model.getNode(id); - if (n == null) n = new TCFNodeExpression(node, null, null, id, -1, false); + if (n == null) n = new TCFNodeExpression(node, null, null, id, null, -1, false); assert n.id.equals(id); assert n.parent == node; n.setSortPosition(cnt++); diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLogExpressions.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLogExpressions.java index 711e97c37..90286a53e 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLogExpressions.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLogExpressions.java @@ -57,7 +57,7 @@ public class TCFChildrenLogExpressions extends TCFChildren { for (String script : scripts) { TCFNodeExpression expression_node = findScript(script); if (expression_node == null) { - add(expression_node = new TCFNodeExpression(node, script, null, null, -1, false)); + add(expression_node = new TCFNodeExpression(node, script, null, null, null, -1, false)); } data.put(expression_node.id, expression_node); } 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 3b97f1ad9..b6c729562 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 @@ -106,7 +106,7 @@ public class TCFChildrenSubExpressions extends TCFChildren { } else { TCFNodeExpression n = findField(id, deref); - if (n == null) add(n = new TCFNodeExpression(node, null, id, null, -1, deref)); + if (n == null) add(n = new TCFNodeExpression(node, null, id, null, null, -1, deref)); n.setSortPosition(map.size()); map.put(n.id, n); } @@ -116,6 +116,27 @@ public class TCFChildrenSubExpressions extends TCFChildren { pending.wait(this); return false; } + + private TCFNodeExpression findReg(String reg_id) { + assert reg_id != null; + for (TCFNode n : getNodes()) { + TCFNodeExpression e = (TCFNodeExpression)n; + if (reg_id.equals(e.getRegisterID())) return e; + } + return null; + } + + private boolean findRegs(TCFNodeRegister reg_node, Map<String,TCFNode> map) { + TCFChildren reg_children = reg_node.getChildren(); + if (!reg_children.validate(this)) return false; + for (TCFNode subnode : reg_children.toArray()) { + TCFNodeExpression n = findReg(subnode.id); + if (n == null) add(n = new TCFNodeExpression(node, null, null, null, subnode.id, -1, false)); + n.setSortPosition(map.size()); + map.put(n.id, n); + } + return true; + } private TCFNodeExpression findIndex(int index, boolean deref) { assert index >= 0; @@ -139,15 +160,25 @@ public class TCFChildrenSubExpressions extends TCFChildren { protected boolean startDataRetrieval() { assert !isDisposed(); TCFNode exp = node; - while (exp != null) { - if (exp instanceof TCFNodeExpression) break; - exp = exp.parent; - } + while (!(exp instanceof TCFNodeExpression)) exp = exp.parent; TCFDataCache<ISymbols.Symbol> type_cache = ((TCFNodeExpression)exp).getType(); if (!type_cache.validate(this)) return false; ISymbols.Symbol type_data = type_cache.getData(); if (type_data == null) { - set(null, null, new HashMap<String,TCFNode>()); + HashMap<String,TCFNode> data = new HashMap<String,TCFNode>(); + TCFDataCache<IExpressions.Value> val_cache = ((TCFNodeExpression)exp).getValue(); + if (!val_cache.validate(this)) return false; + IExpressions.Value val_data = val_cache.getData(); + if (val_data != null) { + String reg_id = val_data.getRegisterID(); + if (reg_id != null) { + if (!node.model.createNode(reg_id, this)) return false; + if (isValid()) return true; + TCFNodeRegister reg_node = (TCFNodeRegister)node.model.getNode(reg_id); + if (!findRegs(reg_node, data)) return false; + } + } + set(null, null, data); return true; } ISymbols.TypeClass type_class = type_data.getTypeClass(); @@ -164,7 +195,7 @@ public class TCFChildrenSubExpressions extends TCFChildren { if (size <= 100) { for (int i = offs; i < offs + size; i++) { TCFNodeExpression n = findIndex(i, false); - if (n == null) n = new TCFNodeExpression(node, null, null, null, i, false); + if (n == null) n = new TCFNodeExpression(node, null, null, null, null, i, false); n.setSortPosition(i); data.put(n.id, n); } @@ -182,10 +213,10 @@ public class TCFChildrenSubExpressions extends TCFChildren { } } else if (type_class == ISymbols.TypeClass.pointer) { - TCFDataCache<IExpressions.Value> value = ((TCFNodeExpression)exp).getValue(); - if (!value.validate(this)) return false; - IExpressions.Value v = value.getData(); - if (v != null && !isNull(v.getValue())) { + TCFDataCache<IExpressions.Value> val_cache = ((TCFNodeExpression)exp).getValue(); + if (!val_cache.validate(this)) return false; + IExpressions.Value val_data = val_cache.getData(); + if (val_data != null && !isNull(val_data.getValue())) { TCFDataCache<ISymbols.Symbol> base_type_cache = node.model.getSymbolInfoCache(type_data.getBaseTypeID()); if (base_type_cache != null) { if (!base_type_cache.validate(this)) return false; @@ -196,7 +227,7 @@ public class TCFChildrenSubExpressions extends TCFChildren { } else { TCFNodeExpression n = findIndex(0, true); - if (n == null) n = new TCFNodeExpression(node, null, null, null, 0, true); + if (n == null) n = new TCFNodeExpression(node, null, null, null, null, 0, true); n.setSortPosition(0); data.put(n.id, n); } 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 380a8a7a4..58a10ca0f 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 @@ -102,6 +102,7 @@ import org.eclipse.tm.internal.tcf.debug.ui.preferences.TCFPreferences; import org.eclipse.tm.tcf.core.Command; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IErrorReport; +import org.eclipse.tm.tcf.protocol.IService; import org.eclipse.tm.tcf.protocol.IToken; import org.eclipse.tm.tcf.protocol.Protocol; import org.eclipse.tm.tcf.services.IDisassembly; @@ -111,7 +112,7 @@ import org.eclipse.tm.tcf.services.IMemoryMap; 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.IRunControl.RunControlContext; +import org.eclipse.tm.tcf.services.IStackTrace; import org.eclipse.tm.tcf.services.ISymbols; import org.eclipse.tm.tcf.util.TCFDataCache; import org.eclipse.tm.tcf.util.TCFTask; @@ -1056,59 +1057,147 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider, /** * Asynchronously create model node for given ID. - * Only nodes for IDs recognized by Run Control service can be created this way. - * If 'cache' is valid after the method returns, the node cannot be created, and - * the cache will contain an error report. - * @param id - Run Control service context ID. + * If 'cache' is valid after the method returns, the node cannot be created, + * and the cache will contain an error report. + * @param id - context ID. * @param cache - data cache object that need the node for validation. * @return - true if all done, false if 'cache' is waiting for remote data. */ public boolean createNode(String id, final TCFDataCache<?> cache) { TCFNode parent = getNode(id); if (parent != null) return true; - LinkedList<IRunControl.RunControlContext> path = null; + LinkedList<Object> path = null; for (;;) { Object obj = context_map.get(id); - if (obj == null) { - final String command_id = id; - IRunControl rc = channel.getRemoteService(IRunControl.class); - if (rc == null) { - cache.set(null, new Exception("Target does not provide Run Control service"), null); - return true; - } - cache.start(rc.getContext(command_id, new IRunControl.DoneGetContext() { - public void doneGetContext(IToken token, Exception error, RunControlContext context) { - if (error == null && context == null) { - error = new Exception("Invalid context ID"); - } - context_map.put(command_id, error != null ? error : context); - cache.done(token); - } - })); + if (obj == null) obj = new CreateNodeRunnable(id); + if (obj instanceof CreateNodeRunnable) { + ((CreateNodeRunnable)obj).wait(cache); return false; } if (obj instanceof Throwable) { cache.set(null, (Throwable)obj, null); return true; } - IRunControl.RunControlContext ctx = (IRunControl.RunControlContext)obj; - if (path == null) path = new LinkedList<IRunControl.RunControlContext>(); - path.add(ctx); - String parent_id = ctx.getParentID(); + if (path == null) path = new LinkedList<Object>(); + path.add(obj); + String parent_id = null; + if (obj instanceof IRunControl.RunControlContext) { + parent_id = ((IRunControl.RunControlContext)obj).getParentID(); + } + else if (obj instanceof IStackTrace.StackTraceContext) { + parent_id = ((IStackTrace.StackTraceContext)obj).getParentID(); + } + else { + parent_id = ((IRegisters.RegistersContext)obj).getParentID(); + } parent = parent_id == null ? launch_node : getNode(parent_id); if (parent != null) break; id = parent_id; } while (path.size() > 0) { - IRunControl.RunControlContext ctx = path.removeLast(); - TCFNodeExecContext n = new TCFNodeExecContext(parent, ctx.getID()); - if (parent instanceof TCFNodeLaunch) ((TCFNodeLaunch)parent).getChildren().add(n); - else ((TCFNodeExecContext)parent).getChildren().add(n); - n.setRunContext(ctx); - parent = n; + Object obj = path.removeLast(); + if (obj instanceof IRunControl.RunControlContext) { + IRunControl.RunControlContext ctx = (IRunControl.RunControlContext)obj; + TCFNodeExecContext n = new TCFNodeExecContext(parent, ctx.getID()); + if (parent instanceof TCFNodeLaunch) ((TCFNodeLaunch)parent).getChildren().add(n); + else ((TCFNodeExecContext)parent).getChildren().add(n); + n.setRunContext(ctx); + parent = n; + } + else if (obj instanceof IStackTrace.StackTraceContext) { + IStackTrace.StackTraceContext ctx = (IStackTrace.StackTraceContext)obj; + TCFNodeStackFrame n = new TCFNodeStackFrame((TCFNodeExecContext)parent, ctx.getID(), false); + ((TCFNodeExecContext)parent).getStackTrace().add(n); + parent = n; + } + else if (obj instanceof IRegisters.RegistersContext) { + IRegisters.RegistersContext ctx = (IRegisters.RegistersContext)obj; + TCFNodeRegister n = new TCFNodeRegister(parent, ctx.getID()); + if (parent instanceof TCFNodeRegister) ((TCFNodeRegister)parent).getChildren().add(n); + else if (parent instanceof TCFNodeStackFrame) ((TCFNodeStackFrame)parent).getRegisters().add(n); + else ((TCFNodeExecContext)parent).getRegisters().add(n); + parent = n; + } + else { + assert false; + } } return true; } + + private class CreateNodeRunnable implements Runnable { + + final String id; + final ArrayList<Runnable> waiting_list = new ArrayList<Runnable>(); + final ArrayList<IService> service_list = new ArrayList<IService>(); + + CreateNodeRunnable(String id) { + this.id = id; + assert context_map.get(id) == null; + String[] arr = { IRunControl.NAME, IStackTrace.NAME, IRegisters.NAME }; + for (String nm : arr) { + IService s = channel.getRemoteService(nm); + if (s != null) service_list.add(s); + } + context_map.put(id, this); + Protocol.invokeLater(this); + } + + void wait(Runnable r) { + assert context_map.get(id) == this; + waiting_list.add(r); + } + + public void run() { + assert context_map.get(id) == this; + if (service_list.size() == 0) { + context_map.put(id, new Exception("Invalid context ID")); + for (Runnable r : waiting_list) r.run(); + } + else { + IService s = service_list.remove(0); + if (s instanceof IRunControl) { + ((IRunControl)s).getContext(id, new IRunControl.DoneGetContext() { + public void doneGetContext(IToken token, Exception error, IRunControl.RunControlContext context) { + if (error == null && context != null) { + context_map.put(id, context); + for (Runnable r : waiting_list) r.run(); + } + else { + run(); + } + } + }); + } + else if (s instanceof IStackTrace) { + ((IStackTrace)s).getContext(new String[]{ id }, new IStackTrace.DoneGetContext() { + public void doneGetContext(IToken token, Exception error, IStackTrace.StackTraceContext[] context) { + if (error == null && context != null && context.length == 1 && context[0] != null) { + context_map.put(id, context[0]); + for (Runnable r : waiting_list) r.run(); + } + else { + run(); + } + } + }); + } + else { + ((IRegisters)s).getContext(id, new IRegisters.DoneGetContext() { + public void doneGetContext(IToken token, Exception error, IRegisters.RegistersContext context) { + if (error == null && context != null) { + context_map.put(id, context); + for (Runnable r : waiting_list) r.run(); + } + else { + run(); + } + } + }); + } + } + } + } 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/TCFNodeExpression.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java index fd8f3f4a2..55918964f 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 @@ -55,6 +55,7 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT private final int index; private final boolean deref; private final String field_id; + private final String reg_id; private final TCFData<IExpressions.Expression> var_expression; private final TCFData<String> base_text; private final TCFData<Expression> expression; @@ -98,12 +99,13 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT } TCFNodeExpression(final TCFNode parent, final String script, - final String field_id, final String var_id, + final String field_id, final String var_id, final String reg_id, final int index, final boolean deref) { super(parent, var_id != null ? var_id : "Expr" + expr_cnt++); - assert script != null || field_id != null || var_id != null || index >= 0; + assert script != null || field_id != null || var_id != null || reg_id != null || index >= 0; this.script = script; this.field_id = field_id; + this.reg_id = reg_id; this.index = index; this.deref = deref; var_expression = new TCFData<IExpressions.Expression>(channel) { @@ -144,6 +146,10 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT set(null, err, exp); return true; } + if (reg_id != null) { + set(null, null, "${" + reg_id + "}"); + return true; + } TCFNode n = parent; while (n instanceof TCFNodeArrayPartition) n = n.parent; TCFDataCache<String> t = ((TCFNodeExpression)n).base_text; @@ -188,6 +194,24 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT } } } + else if (reg_id != null) { + if (!model.createNode(reg_id, this)) return false; + if (isValid()) return true; + TCFNodeRegister reg_node = (TCFNodeRegister)model.getNode(reg_id); + for (;;) { + TCFDataCache<IRegisters.RegistersContext> ctx_cache = reg_node.getContext(); + if (!ctx_cache.validate(this)) return false; + IRegisters.RegistersContext ctx_data = ctx_cache.getData(); + if (ctx_data == null) { + set(null, ctx_cache.getError(), null); + return true; + } + expr_text = expr_text == null ? ctx_data.getName() : ctx_data.getName() + "." + expr_text; + if (!(reg_node.parent instanceof TCFNodeRegister)) break; + reg_node = (TCFNodeRegister)reg_node.parent; + } + expr_text = "$" + expr_text; + } else { TCFDataCache<?> pending = null; TCFDataCache<ISymbols.Symbol> field = model.getSymbolInfoCache(field_id); @@ -603,6 +627,10 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT return field_id; } + String getRegisterID() { + return reg_id; + } + int getIndex() { return index; } @@ -891,6 +919,7 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT TCFDataCache<ISymbols.Symbol> field = model.getSymbolInfoCache(field_id); TCFDataCache<?> pending = null; if (field != null && !field.validate()) pending = field; + if (reg_id != null && !expression_text.validate(done)) pending = expression_text; if (!var_expression.validate()) pending = var_expression; if (!base_text.validate()) pending = base_text; if (!value.validate()) pending = value; @@ -909,6 +938,7 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT } } if (name == null && field != null && field.getData() != null) name = field.getData().getName(); + if (name == null && reg_id != null && expression_text.getData() != null) name = expression_text.getData(); if (name == null && var_expression.getData() != null) { TCFDataCache<ISymbols.Symbol> var = model.getSymbolInfoCache(var_expression.getData().getSymbolID()); if (var != null) { |