Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/TCF Service - Streams.html2
-rw-r--r--plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/internal/tcf/services/remote/SymbolsProxy.java46
-rw-r--r--plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/protocol/JSON.java7
-rw-r--r--plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/IMemory.java2
-rw-r--r--plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/services/ISymbols.java83
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java4
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java7
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java11
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java7
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestExpressions.java37
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestRCBP1.java21
11 files changed, 207 insertions, 20 deletions
diff --git a/docs/TCF Service - Streams.html b/docs/TCF Service - Streams.html
index 5a3378a13..edd875ab2 100644
--- a/docs/TCF Service - Streams.html
+++ b/docs/TCF Service - Streams.html
@@ -57,7 +57,7 @@
<li> Asynchronous overlapped data streaming: multiple 'read' or 'write' command can be issued at same time, both peers
can continue data processing concurrently with data transmission.
<li> Multicast: multiple clients can receive data from same stream.
- <li> Subscription model: clients are required to expressed interest in particular streams by subscribing for the service.
+ <li> Subscription model: clients are required to express interest in particular streams by subscribing for the service.
<li> Flow control: peers can throttle data flow of individual streams by delaying 'read' and 'write' commands.
</ul>
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++) {

Back to the top