diff options
author | eutarass | 2010-03-10 01:18:55 +0000 |
---|---|---|
committer | eutarass | 2010-03-10 01:18:55 +0000 |
commit | c12de90aa1437b8eac7b1d983e13164aa232e375 (patch) | |
tree | f7fb1e7407156b1b1f03ed75ff6ba06c5419e3fd /plugins | |
parent | 3c71c9e409ad39a155a5378aaa4b3ba5c423a55e (diff) | |
download | org.eclipse.tcf-c12de90aa1437b8eac7b1d983e13164aa232e375.tar.gz org.eclipse.tcf-c12de90aa1437b8eac7b1d983e13164aa232e375.tar.xz org.eclipse.tcf-c12de90aa1437b8eac7b1d983e13164aa232e375.zip |
TCF Agent: more symbols value-add code.
Diffstat (limited to 'plugins')
10 files changed, 206 insertions, 19 deletions
diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/SymbolsProxy.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/SymbolsProxy.java index 7916c2255..4aa7bf4ee 100644 --- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/SymbolsProxy.java +++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/SymbolsProxy.java @@ -23,6 +23,16 @@ public class SymbolsProxy implements ISymbols { value = JSON.toByteArray(props.get(PROP_VALUE)); } + public String getOwnerID() { + return (String)props.get(PROP_OWNER_ID); + } + + public int getUpdatePolicy() { + Number n = (Number)props.get(PROP_UPDATE_POLICY); + if (n == null) return 0; + return n.intValue(); + } + public Number getAddress() { return (Number)props.get(PROP_ADDRESS); } @@ -110,6 +120,12 @@ public class SymbolsProxy implements ISymbols { public byte[] getValue() { return value; } + + public boolean isBigEndian() { + Boolean b = (Boolean)props.get(PROP_LENGTH); + if (b == null) return false; + return b.booleanValue(); + } } public SymbolsProxy(IChannel channel) { @@ -151,6 +167,36 @@ public class SymbolsProxy implements ISymbols { }.token; } + public IToken find(String context_id, String name, final DoneFind done) { + return new Command(channel, this, "find", new Object[]{ context_id, name }) { + @Override + public void done(Exception error, Object[] args) { + String id = null; + if (error == null) { + assert args.length == 2; + error = toError(args[0]); + id = (String)args[1]; + } + done.doneFind(token, error, id); + } + }.token; + } + + public IToken list(String context_id, final DoneList done) { + return new Command(channel, this, "list", new Object[]{ context_id }) { + @Override + public void done(Exception error, Object[] args) { + String[] lst = null; + if (error == null) { + assert args.length == 2; + error = toError(args[0]); + lst = toStringArray(args[1]); + } + done.doneList(token, error, lst); + } + }.token; + } + @SuppressWarnings("unchecked") private String[] toStringArray(Object o) { if (o == null) return null; diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/JSON.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/JSON.java index 1762ec5f8..43cd9fe57 100644 --- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/JSON.java +++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/JSON.java @@ -372,6 +372,13 @@ public final class JSON { if (cur_ch != 'e') error(); read(); return Boolean.TRUE; + case 'N': + read(); + if (cur_ch != 'a') error(); + read(); + if (cur_ch != 'N') error(); + read(); + return Float.NaN; default: boolean neg = cur_ch == '-'; if (neg) read(); diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IMemory.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IMemory.java index 794877bbe..38d426f4b 100644 --- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IMemory.java +++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IMemory.java @@ -146,7 +146,7 @@ public interface IMemory extends IService { /** * Get memory endianess. - * @return true if memory id big-endian. + * @return true if memory is big-endian. */ boolean isBigEndian(); diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ISymbols.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ISymbols.java index 0c3dcb845..1d876564c 100644 --- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ISymbols.java +++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ISymbols.java @@ -53,6 +53,23 @@ public interface ISymbols extends IService { String getID(); /** + * Get symbol owner ID. + * The owner can a thread or memory space (process). + * Certain changes in owner state can invalidate cached symbol properties, + * see getUpdatePolicy() and UPDATE_*. + */ + String getOwnerID(); + + /** + * Get symbol properties update policy ID. + * Symbol properties can change during program execution. + * If a client wants to cache symbols, it should invalidate cached data + * according to update policies of cached symbols. + * @return symbol update policy ID, see UPDATE_* + */ + int getUpdatePolicy(); + + /** * Get symbol name. * @return symbol name or null. */ @@ -141,6 +158,12 @@ public interface ISymbols extends IService { byte[] getValue(); /** + * Get symbol values endianess. + * @return true if symbol is big-endian. + */ + boolean isBigEndian(); + + /** * Get complete map of context properties. * @return map of context properties. */ @@ -152,6 +175,8 @@ public interface ISymbols extends IService { */ static final String PROP_ID = "ID", + PROP_OWNER_ID = "OwnerID", + PROP_UPDATE_POLICY = "UpdatePolicy", PROP_NAME = "Name", PROP_SYMBOL_CLASS = "Class", PROP_TYPE_CLASS = "TypeClass", @@ -164,9 +189,28 @@ public interface ISymbols extends IService { PROP_UPPER_BOUND = "UpperBound", PROP_OFFSET = "Offset", PROP_ADDRESS = "Address", - PROP_VALUE = "Value"; + PROP_VALUE = "Value", + PROP_BIG_ENDIAN = "BigEndian"; - // TODO: BigEndian property + /** + * Symbol context properties update policies. + */ + static final int + /** + * Update policy "Memory Map": symbol properties become invalid when + * memory map changes - when modules are loaded or unloaded. + * Symbol OwnerID indicates memory space (process) that is invalidation events source. + * Most static variables and types have this update policy. + */ + UPDATE_ON_MEMORY_MAP_CHANGES = 0, + + /** + * Update policy "Execution State": symbol properties become invalid when + * execution state changes - a thread is suspended, resumed or exited. + * Symbol OwnerID indicates executable context (thread) that is invalidation events source. + * Most stack (auto) variables have this update policy. + */ + UPDATE_ON_EXE_STATE_CHANGES = 1; /** * Retrieve symbol context info for given symbol ID. @@ -215,4 +259,39 @@ public interface ISymbols extends IService { */ void doneGetChildren(IToken token, Exception error, String[] context_ids); } + + /** + * Search symbol with given name in given context. + * The context can be memory space, process, thread or stack frame. + * + * @param context_id – a search scope. + * @param name – symbol name. + * @param done - call back interface called when operation is completed. + * @return - pending command handle. + */ + IToken find(String context_id, String name, DoneFind done); + + /** + * Client call back interface for find(). + */ + interface DoneFind { + void doneFind(IToken token, Exception error, String symbol_id); + } + + /** + * List all symbols in given context. + * The context can be a stack frame. + * + * @param context_id – a scope. + * @param done - call back interface called when operation is completed. + * @return - pending command handle. + */ + IToken list(String context_id, DoneList done); + + /** + * Client call back interface for list(). + */ + interface DoneList { + void doneList(IToken token, Exception error, String[] symbol_ids); + } } diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java index dbd2d9b48..0990935ea 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java @@ -55,6 +55,10 @@ public class TCFChildrenStackTrace extends TCFChildren { for (TCFNode n : getNodes()) ((TCFNodeStackFrame)n).onRegistersChanged(); } + void onRegisterValueChanged() { + for (TCFNode n : getNodes()) ((TCFNodeStackFrame)n).onRegisterValueChanged(); + } + void onResumed() { reset(null); } 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 5b5fc27cd..db7701a33 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 @@ -468,6 +468,13 @@ public class TCFNodeExecContext extends TCFNode { addModelDelta(IModelDelta.CONTENT); } + void onRegisterValueChanged() { + state.reset(); + address.reset(); + children_stack.onRegisterValueChanged(); + addModelDelta(IModelDelta.CONTENT); + } + // Return true if at least one child is suspended. // Return null if waiting for a cache element. private Boolean hasSuspendedChildren(Runnable done) { diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java index 9413e9934..3275e557d 100644 --- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java +++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java @@ -317,7 +317,16 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor { } void onValueChanged() { - onSuspended(); + prev_value = next_value; + value.reset(); + TCFNode n = parent; + while (n != null) { + if (n instanceof TCFNodeExecContext) { + ((TCFNodeExecContext)n).onRegisterValueChanged(); + } + n = n.parent; + } + addModelDelta(IModelDelta.STATE); } void onSuspended() { 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 6d219f875..541ee4bd4 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 @@ -366,6 +366,13 @@ public class TCFNodeStackFrame extends TCFNode { addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT); } + void onRegisterValueChanged() { + stack_trace_context.cancel(); + line_info.cancel(); + address.cancel(); + addModelDelta(IModelDelta.STATE); + } + @Override public int compareTo(TCFNode n) { if (n instanceof TCFNodeStackFrame) { diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestExpressions.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestExpressions.java index 9975b5773..2dfbe5176 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestExpressions.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestExpressions.java @@ -25,7 +25,6 @@ import org.eclipse.tm.tcf.services.IExpressions; import org.eclipse.tm.tcf.services.IRunControl; import org.eclipse.tm.tcf.services.IStackTrace; import org.eclipse.tm.tcf.services.ISymbols; -import org.eclipse.tm.tcf.services.IRunControl.RunControlContext; class TestExpressions implements ITCFTest, IRunControl.RunControlListener, IExpressions.ExpressionsListener, IBreakpoints.BreakpointsListener { @@ -48,6 +47,7 @@ class TestExpressions implements ITCFTest, private String suspended_pc; private boolean waiting_suspend; private String[] stack_trace; + private IStackTrace.StackTraceContext[] stack_frames; private String[] local_vars; private final HashMap<String,IRunControl.RunControlContext> ctx_map = new HashMap<String,IRunControl.RunControlContext>(); private final Map<String,IExpressions.Expression> expr_ctx = new HashMap<String,IExpressions.Expression>(); @@ -293,6 +293,25 @@ class TestExpressions implements ITCFTest, }); return; } + if (stack_frames == null) { + stk.getContext(stack_trace, new IStackTrace.DoneGetContext() { + public void doneGetContext(IToken token, Exception error, IStackTrace.StackTraceContext[] frames) { + if (error != null) { + exit(error); + } + else { + stack_frames = frames; + if (stack_frames == null || stack_frames.length != stack_trace.length) { + exit(new Exception("Invalid stack trace")); + } + else { + runTest(); + } + } + } + }); + return; + } if (local_vars == null) { expr.getChildren(stack_trace[stack_trace.length - 2], new IExpressions.DoneGetChildren() { public void doneGetChildren(IToken token, Exception error, String[] context_ids) { @@ -454,14 +473,14 @@ class TestExpressions implements ITCFTest, } public void contextAdded(IRunControl.RunControlContext[] contexts) { - for (RunControlContext ctx : contexts) { + for (IRunControl.RunControlContext ctx : contexts) { if (ctx_map.get(ctx.getID()) != null) exit(new Error("Invalid 'contextAdded' event")); ctx_map.put(ctx.getID(), ctx); } } public void contextChanged(IRunControl.RunControlContext[] contexts) { - for (RunControlContext ctx : contexts) { + for (IRunControl.RunControlContext ctx : contexts) { if (ctx_map.get(ctx.getID()) == null) return; ctx_map.put(ctx.getID(), ctx); } @@ -474,8 +493,16 @@ class TestExpressions implements ITCFTest, for (String id : context_ids) { ctx_map.remove(id); if (id.equals(process_id)) { - if (test_done) exit(null); - else exit(new Exception("Test process exited too soon")); + if (test_done) { + bp.set(null, new IBreakpoints.DoneCommand() { + public void doneCommand(IToken token, Exception error) { + exit(error); + } + }); + } + else { + exit(new Exception("Test process exited too soon")); + } return; } } diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestRCBP1.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestRCBP1.java index b47a39155..2d7d2fe8e 100644 --- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestRCBP1.java +++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestRCBP1.java @@ -57,6 +57,7 @@ class TestRCBP1 implements ITCFTest, private final Map<String,Map<String,IRegisters.RegistersContext>> regs = new HashMap<String,Map<String,IRegisters.RegistersContext>>(); private final Map<String,Map<String,Object>> bp_list = new HashMap<String,Map<String,Object>>(); + private final Random rnd = new Random(); private String context_id; // Test process context ID private IRunControl.RunControlContext context; @@ -229,7 +230,7 @@ class TestRCBP1 implements ITCFTest, Map<String,Object> m[] = new Map[4]; for (int i = 0; i < m.length; i++) { m[i] = new HashMap(); - m[i].put(IBreakpoints.PROP_ID, "TcfTestBP" + i); + m[i].put(IBreakpoints.PROP_ID, "TcfTestBP" + i + "" + channel_id); m[i].put(IBreakpoints.PROP_ENABLED, Boolean.TRUE); switch (i) { case 0: @@ -247,7 +248,6 @@ class TestRCBP1 implements ITCFTest, break; case 3: // Breakpoint that will be enabled with "enable" command - m[i].put(IBreakpoints.PROP_ID, "TcfTestBP3" + channel_id); m[i].put(IBreakpoints.PROP_ENABLED, Boolean.FALSE); m[i].put(IBreakpoints.PROP_LOCATION, "tcf_test_func2"); break; @@ -526,10 +526,10 @@ class TestRCBP1 implements ITCFTest, exit(new Exception("Test main thread breakpoint count = " + bp_cnt + ", expected 30")); } rc.removeListener(this); - // Flush communication channel of pending commands - Protocol.sync(new Runnable() { - public void run() { - exit(null); + // Reset breakpoint list + bp.set(null, new IBreakpoints.DoneCommand() { + public void doneCommand(IToken token, Exception error) { + exit(error); } }); } @@ -660,7 +660,9 @@ class TestRCBP1 implements ITCFTest, SuspendedContext sc = suspended.get(id); IRunControl.RunControlContext ctx = threads.get(id); if (ctx != null && sc != null) { - ctx.resume(IRunControl.RM_RESUME, 1, new HashMap<String,Object>(), new IRunControl.DoneCommand() { + int rm = rnd.nextInt(6); + if (!ctx.canResume(rm)) rm = IRunControl.RM_RESUME; + ctx.resume(rm, 1, new HashMap<String,Object>(), new IRunControl.DoneCommand() { public void doneCommand(IToken token, Exception error) { if (test_suite.cancel) return; if (!test_suite.isActive(TestRCBP1.this)) return; @@ -733,7 +735,7 @@ class TestRCBP1 implements ITCFTest, final Number addr, final byte[] buf, final Runnable done) { final byte[] data = new byte[buf.length]; - new Random().nextBytes(data); + rnd.nextBytes(data); mem_ctx.set(addr, 1, data, 0, data.length, 0, new IMemory.DoneMemory() { public void doneMemory(IToken token, MemoryError error) { if (suspended.get(sc.id) != sc) { @@ -774,7 +776,7 @@ class TestRCBP1 implements ITCFTest, final Number addr, final byte[] buf, final Runnable done) { final byte[] data = new byte[buf.length / 7]; - new Random().nextBytes(data); + rnd.nextBytes(data); mem_ctx.fill(addr, 1, data, buf.length, 0, new IMemory.DoneMemory() { public void doneMemory(IToken token, MemoryError error) { if (suspended.get(sc.id) != sc) { @@ -897,7 +899,6 @@ class TestRCBP1 implements ITCFTest, })); } if (!reg_map.isEmpty()) { - Random rnd = new Random(); List<IRegisters.Location> locs = new ArrayList<IRegisters.Location>(); String[] ids = reg_map.keySet().toArray(new String[reg_map.size()]); for (int i = 0; i < rnd.nextInt(32); i++) { |