Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2010-02-22 18:19:02 +0000
committereutarass2010-02-22 18:19:02 +0000
commit4964b236049b5d07a21c1cf2ce1b20a0c624d567 (patch)
treeaf60be954c90030d73c4bf1cb703d064824d11aa /plugins
parente85adcdb0929eebd3adc3a75795acc850034325f (diff)
downloadorg.eclipse.tcf-4964b236049b5d07a21c1cf2ce1b20a0c624d567.tar.gz
org.eclipse.tcf-4964b236049b5d07a21c1cf2ce1b20a0c624d567.tar.xz
org.eclipse.tcf-4964b236049b5d07a21c1cf2ce1b20a0c624d567.zip
Work in progress: more TCF value-add support - all tests have passed when connecting to a target through TCF symbols server value-add.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFDataCache.java92
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/Activator.java4
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/CastToArrayCommand.java11
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/CastToTypeCommand.java11
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/RestoreDefaultTypeCommand.java9
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SignalsDialog.java2
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFPathMapTab.java8
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTargetTab.java31
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java25
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java2
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java2
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java2
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java4
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java37
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java1
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java18
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java177
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java4
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java115
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/trace/TraceView.java142
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java2
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/Main.java4
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TCFTestSuite.java20
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestAttachTerminate.java138
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestExpressions.java55
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestPathMap.java16
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestRCBP1.java87
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java18
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java3
29 files changed, 647 insertions, 393 deletions
diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFDataCache.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFDataCache.java
index 9b6394973..5ee753e85 100644
--- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFDataCache.java
+++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFDataCache.java
@@ -22,6 +22,27 @@ import org.eclipse.tm.tcf.protocol.Protocol;
* 1. Valid - cache is in sync with remote data, use getError() and getData() to get cached data;
* 2. Invalid - cache is out of sync, start data retrieval by calling validate();
* 3. Pending - cache is waiting result of a command that was sent to remote peer.
+ *
+ * A cache instance can be created on any data type that needs to be caches.
+ * Examples might be context children list, context properties, context state, memory data,
+ * register data, symbol, variable, etc.
+ * Clients of cache items can register for cache changes, but don’t need to think about any particular events
+ * since that is handled by the cache item itself.
+ *
+ * A typical cache client should implement Runnable interface.
+ * The implementation of run() method should:
+ *
+ * Validate all cache items required for client task.
+ * If anything is invalid then client should not alter any shared data structures,
+ * should discard any intermediate results and register (wait) for changes of invalid cache instance(s) state.
+ * When cache item state changes, client is invoked again and full validation is restarted.
+ * Once everything is valid, client completes its task in a single dispatch cycle.
+ *
+ * Note: clients should never retain copies of remote data across dispatch cycles!
+ * Such data would get out of sync and compromise data consistency.
+ * All remote data and everything derived from remote data should be kept in cache items
+ * that implement proper event handling and can keep data consistent across dispatch cycles.
+ *
* @param <V> - type of data to be stored in the cache.
*/
public abstract class TCFDataCache<V> implements Runnable {
@@ -29,6 +50,7 @@ public abstract class TCFDataCache<V> implements Runnable {
private Throwable error;
private boolean valid;
private boolean posted;
+ private boolean disposed;
private V data;
protected final IChannel channel;
@@ -49,7 +71,7 @@ public abstract class TCFDataCache<V> implements Runnable {
}
/**
- * @return true if cache contains up-to-date data (or data retrieval error).
+ * @return true if cache contains up-to-date data or error.
*/
public boolean isValid() {
return valid;
@@ -63,6 +85,13 @@ public abstract class TCFDataCache<V> implements Runnable {
}
/**
+ * @return true if cache is disposed.
+ */
+ public boolean isDisposed() {
+ return disposed;
+ }
+
+ /**
* @return error object if data retrieval ended with an error, or null if retrieval was successful.
* Note: It is prohibited to call this method when cache is not valid.
*/
@@ -105,6 +134,7 @@ public abstract class TCFDataCache<V> implements Runnable {
*/
public void wait(Runnable cb) {
assert Protocol.isDispatchThread();
+ assert !disposed;
assert !valid;
if (cb != null) waiting_list.add(cb);
}
@@ -116,9 +146,9 @@ public abstract class TCFDataCache<V> implements Runnable {
public boolean validate() {
assert Protocol.isDispatchThread();
if (channel.getState() != IChannel.STATE_OPEN) {
- error = null;
command = null;
valid = true;
+ error = null;
data = null;
}
else {
@@ -159,11 +189,16 @@ public abstract class TCFDataCache<V> implements Runnable {
assert Protocol.isDispatchThread();
if (command != token) return;
command = null;
- if (channel.getState() != IChannel.STATE_OPEN) data = null;
- this.error = error;
- this.data = data;
- valid = true;
- post();
+ if (!disposed) {
+ if (channel.getState() != IChannel.STATE_OPEN) {
+ error = null;
+ data = null;
+ }
+ this.error = error;
+ this.data = data;
+ valid = true;
+ post();
+ }
}
/**
@@ -176,36 +211,48 @@ public abstract class TCFDataCache<V> implements Runnable {
command.cancel();
command = null;
}
- this.data = data;
- error = null;
- valid = true;
- post();
+ if (!disposed) {
+ this.data = data;
+ error = null;
+ valid = true;
+ post();
+ }
}
/**
- * Invalidate the cache. If retrieval is in progress - let it continue.
+ * Invalidate the cache.
+ * If retrieval is in progress - let it continue.
*/
public void reset() {
assert Protocol.isDispatchThread();
- error = null;
- valid = false;
- data = null;
- post();
+ if (!disposed) {
+ error = null;
+ valid = false;
+ data = null;
+ post();
+ }
}
/**
- * Force cache to invalid state, cancel pending data retrieval if any.
+ * Invalidate the cache.
+ * Cancel pending data retrieval if any.
*/
public void cancel() {
- assert Protocol.isDispatchThread();
+ reset();
if (command != null) {
command.cancel();
command = null;
}
- error = null;
- valid = false;
- data = null;
- post();
+ }
+
+ /**
+ * Dispose the cache.
+ * Cancel pending data retrieval if any.
+ */
+ public void dispose() {
+ cancel();
+ valid = true;
+ disposed = true;
}
@Override
@@ -213,6 +260,7 @@ public abstract class TCFDataCache<V> implements Runnable {
StringBuffer bf = new StringBuffer();
bf.append('[');
if (valid) bf.append("valid,");
+ if (disposed) bf.append("disposed,");
if (posted) bf.append("posted,");
if (error != null) bf.append("error,");
bf.append("data=");
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 c3e18cc16..c38e27406 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
@@ -35,7 +35,9 @@ public class Activator extends AbstractUIPlugin {
private static final BundleListener bundle_listener = new BundleListener() {
public void bundleChanged(BundleEvent event) {
- if (plugin != null && event.getBundle() == plugin.getBundle() &&
+ if (plugin != null && event != null &&
+ plugin.getBundle() != null &&
+ event.getBundle() == plugin.getBundle() &&
plugin.getBundle().getState() != Bundle.ACTIVE) {
Protocol.invokeAndWait(new Runnable() {
public void run() {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/CastToArrayCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/CastToArrayCommand.java
index 8d8199911..9c2417abf 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/CastToArrayCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/CastToArrayCommand.java
@@ -18,6 +18,7 @@ import org.eclipse.tm.internal.tcf.debug.ui.Activator;
import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
import org.eclipse.tm.internal.tcf.debug.ui.model.ICastToType;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+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;
@@ -63,12 +64,16 @@ public class CastToArrayCommand extends AbstractActionDelegate {
if (node == null) return;
IWorkbenchWindow window = Activator.getDefault().getWorkbench().getActiveWorkbenchWindow();
if (window == null) return;
- String base_type_name = getBaseTypeName();
+ final String base_type_name = getBaseTypeName();
if (base_type_name == null) return;
CastToTypeDialog dialog = new CastToTypeDialog(window.getShell(), node.getModel().getCastToType(node.getID()));
if (dialog.open() != Window.OK) return;
- String new_type = dialog.getValue().trim();
- node.getModel().setCastToType(node.getID(), base_type_name + "[" + new_type + "]");
+ final String new_type = dialog.getValue().trim();
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ node.getModel().setCastToType(node.getID(), base_type_name + "[" + new_type + "]");
+ }
+ });
}
private String getBaseTypeName() {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/CastToTypeCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/CastToTypeCommand.java
index 34cdc8997..e953ed920 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/CastToTypeCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/CastToTypeCommand.java
@@ -18,6 +18,7 @@ import org.eclipse.tm.internal.tcf.debug.ui.Activator;
import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
import org.eclipse.tm.internal.tcf.debug.ui.model.ICastToType;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.ui.IWorkbenchWindow;
public class CastToTypeCommand extends AbstractActionDelegate {
@@ -48,14 +49,18 @@ public class CastToTypeCommand extends AbstractActionDelegate {
@Override
protected void run() {
- TCFNode node = getCastToTypeNode();
+ final TCFNode node = getCastToTypeNode();
if (node == null) return;
IWorkbenchWindow window = Activator.getDefault().getWorkbench().getActiveWorkbenchWindow();
if (window == null) return;
CastToTypeDialog dialog = new CastToTypeDialog(window.getShell(), node.getModel().getCastToType(node.getID()));
if (dialog.open() != Window.OK) return;
- String new_type = dialog.getValue().trim();
- node.getModel().setCastToType(node.getID(), new_type);
+ final String new_type = dialog.getValue().trim();
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ node.getModel().setCastToType(node.getID(), new_type);
+ }
+ });
}
@Override
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/RestoreDefaultTypeCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/RestoreDefaultTypeCommand.java
index 1e02cc19b..8bc9bd915 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/RestoreDefaultTypeCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/RestoreDefaultTypeCommand.java
@@ -12,14 +12,19 @@ package org.eclipse.tm.internal.tcf.debug.ui.commands;
import org.eclipse.tm.internal.tcf.debug.ui.model.ICastToType;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.tcf.protocol.Protocol;
public class RestoreDefaultTypeCommand extends AbstractActionDelegate {
@Override
protected void run() {
- TCFNode node = getCastToTypeNode();
+ final TCFNode node = getCastToTypeNode();
if (node == null) return;
- node.getModel().setCastToType(node.getID(), null);
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ node.getModel().setCastToType(node.getID(), null);
+ }
+ });
}
@Override
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SignalsDialog.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SignalsDialog.java
index 4a6face7f..4b840b82d 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SignalsDialog.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SignalsDialog.java
@@ -246,7 +246,7 @@ class SignalsDialog extends Dialog {
new TCFTask<Boolean>() {
public void run() {
- signal_list.reset(null);
+ signal_list.dispose();
done(Boolean.TRUE);
}
}.getE();
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFPathMapTab.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFPathMapTab.java
index f2194f6c1..0b37d9bcd 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFPathMapTab.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFPathMapTab.java
@@ -11,8 +11,10 @@
package org.eclipse.tm.internal.tcf.debug.ui.launch;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
@@ -219,6 +221,12 @@ public class TCFPathMapTab extends AbstractLaunchConfigurationTab {
});
}
+ List<IPathMap.PathMapRule> getPathMap() {
+ List<IPathMap.PathMapRule> l = new ArrayList<IPathMap.PathMapRule>();
+ for (PathMapRule r : map) l.add(r);
+ return Collections.unmodifiableList(l);
+ }
+
public void initializeFrom(ILaunchConfiguration config) {
setErrorMessage(null);
setMessage(null);
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTargetTab.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTargetTab.java
index 59886fc00..5f4e4c54d 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTargetTab.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/launch/TCFTargetTab.java
@@ -13,12 +13,14 @@ package org.eclipse.tm.internal.tcf.debug.ui.launch;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
@@ -59,6 +61,7 @@ import org.eclipse.tm.tcf.protocol.IPeer;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.protocol.IChannel.IChannelListener;
import org.eclipse.tm.tcf.services.ILocator;
+import org.eclipse.tm.tcf.services.IPathMap.PathMapRule;
/**
@@ -602,7 +605,7 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
}
else if (parent == peer_info) {
peer_info.locator = Protocol.getLocator();
- createLocatorListener(peer_info);
+ doneLoadChildren(parent, null, createLocatorListener(peer_info));
}
else {
final IChannel channel = parent.peer.openChannel();
@@ -615,9 +618,21 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
public void onChannelClosed(final Throwable error) {
assert !closed;
if (parent.channel != channel) return;
- if (parent.children_error == null) {
+ if (!opened) {
doneLoadChildren(parent, error, null);
}
+ else {
+ if (display != null) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (parent.children_pending) return;
+ parent.children = null;
+ parent.children_error = error;
+ updateItems(parent);
+ }
+ });
+ }
+ }
closed = true;
parent.channel = null;
parent.locator = null;
@@ -634,7 +649,7 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
parent.channel.close();
}
else {
- createLocatorListener(parent);
+ doneLoadChildren(parent, null, createLocatorListener(parent));
}
}
});
@@ -643,7 +658,7 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
});
}
- private void createLocatorListener(PeerInfo peer) {
+ private PeerInfo[] createLocatorListener(PeerInfo peer) {
assert Protocol.isDispatchThread();
Map<String,IPeer> map = peer.locator.getPeers();
PeerInfo[] buf = new PeerInfo[map.size()];
@@ -659,7 +674,7 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
}
peer.listener = new LocatorListener(peer);
peer.locator.addListener(peer.listener);
- doneLoadChildren(peer, null, buf);
+ return buf;
}
private void doneLoadChildren(final PeerInfo parent, final Throwable error, final PeerInfo[] children) {
@@ -917,7 +932,11 @@ public class TCFTargetTab extends AbstractLaunchConfigurationTab {
Protocol.invokeLater(new Runnable() {
public void run() {
try {
- test[0] = new TCFTestSuite(info.peer, done);
+ List<PathMapRule> map = null;
+ for (ILaunchConfigurationTab t : getLaunchConfigurationDialog().getTabs()) {
+ if (t instanceof TCFPathMapTab) map = ((TCFPathMapTab)t).getPathMap();
+ }
+ test[0] = new TCFTestSuite(info.peer, done, map);
}
catch (Throwable x) {
ArrayList<Throwable> errors = new ArrayList<Throwable>();
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java
index 6b249c266..b3528c6e6 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java
@@ -27,7 +27,6 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
private final int pool_margin;
private final Map<String,TCFNode> node_pool = new LinkedHashMap<String,TCFNode>(32, 0.75f, true);
- private boolean disposed;
private static final TCFNode[] EMPTY_NODE_ARRAY = new TCFNode[0];
@@ -46,15 +45,15 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
/**
* Dispose the cache and all nodes in the nodes pool.
*/
- void dispose() {
- assert !disposed;
+ @Override
+ public void dispose() {
+ assert !isDisposed();
if (!node_pool.isEmpty()) {
TCFNode a[] = node_pool.values().toArray(new TCFNode[node_pool.size()]);
for (int i = 0; i < a.length; i++) a[i].dispose();
assert node_pool.isEmpty();
}
- disposed = true;
- super.reset(null);
+ super.dispose();
}
/**
@@ -71,16 +70,8 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
}
}
- /**
- * Check if the cache is disposed.
- * @return true if disposed.
- */
- boolean isDisposed() {
- return disposed;
- }
-
private void addToPool(Map<String,TCFNode> data) {
- assert !disposed;
+ assert !isDisposed();
for (TCFNode n : data.values()) {
assert data.get(n.id) == n;
node_pool.put(n.id, n);
@@ -105,7 +96,7 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
@Override
public void set(IToken token, Throwable error, Map<String,TCFNode> data) {
array = null;
- if (disposed) {
+ if (isDisposed()) {
// A command can return data after the cache element has been disposed.
// Just ignore the data in such case.
super.set(token, null, null);
@@ -126,7 +117,7 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
*/
@Override
public void reset(Map<String,TCFNode> data) {
- assert !disposed;
+ assert !isDisposed();
array = null;
if (data != null) {
super.reset(data);
@@ -160,7 +151,7 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
* @param n - a node.
*/
void add(TCFNode n) {
- assert !disposed;
+ assert !isDisposed();
assert node_pool.get(n.id) == null;
node_pool.put(n.id, n);
if (isValid()) {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java
index f5e00cf92..639a8abc6 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExecContext.java
@@ -90,7 +90,7 @@ public class TCFChildrenExecContext extends TCFChildren {
}
@Override
- protected void dispose() {
+ public void dispose() {
super.dispose();
mem_children.dispose();
run_children.dispose();
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 67496ab4c..3c86e724a 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
@@ -57,7 +57,7 @@ public class TCFChildrenExpressions extends TCFChildren {
}
@Override
- void dispose() {
+ public void dispose() {
exp_manager.removeExpressionListener(listener);
super.dispose();
}
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 3b3768dd5..4b36d9417 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
@@ -40,7 +40,7 @@ public class TCFChildrenSubExpressions extends TCFChildren {
}
void onCastToTypeChanged() {
- reset();
+ cancel();
TCFNode a[] = getNodes().toArray(new TCFNode[getNodes().size()]);
for (int i = 0; i < a.length; i++) a[i].dispose();
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java
index c61901322..24c2c6d34 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java
@@ -138,8 +138,8 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
new TCFDebugTask<Boolean>() {
public void run() {
disposed = true;
- expression_value.reset(null);
- expression_type.reset(null);
+ expression_value.dispose();
+ expression_type.dispose();
if (remote_expression.isValid() && remote_expression.getData() != null) {
final IChannel channel = exec_ctx.getModel().getLaunch().getChannel();
if (channel.getState() == IChannel.STATE_OPEN) {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java
index 67b7b1930..70755ec66 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java
@@ -40,6 +40,7 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru
private final Map<TCFNode,TCFNode[]> node2children = new HashMap<TCFNode,TCFNode[]>();
private final Map<TCFNode,ModelDelta> node2delta = new HashMap<TCFNode,ModelDelta>();
+ private int all_flags;
private TCFNode selection;
private boolean posted;
private boolean disposed;
@@ -157,16 +158,18 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru
else {
node2flags.put(node, flags);
}
+ all_flags |= flags;
post();
}
}
void setSelection(TCFNode node) {
selection = node;
- addDelta(node, IModelDelta.REVEAL);
+ post();
}
void post() {
+ assert Protocol.isDispatchThread();
if (!posted) {
Protocol.invokeLater(this);
posted = true;
@@ -223,7 +226,13 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru
if (parent_flags_obj != null) parent_flags = parent_flags_obj;
ModelDelta parent = makeDelta(root, node.parent, parent_flags);
if (parent == null) return null;
- delta = parent.addNode(node, getNodeIndex(node), flags, getNodeChildren(node).length);
+ int index = -1;
+ int children = 0;
+ if ((all_flags & ~(IModelDelta.STATE | IModelDelta.CONTENT)) != 0) {
+ index = getNodeIndex(node);
+ children = getNodeChildren(node).length;
+ }
+ delta = parent.addNode(node, index, flags, children);
}
node2delta.put(node, delta);
}
@@ -235,26 +244,40 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Ru
posted = false;
assert Protocol.isDispatchThread();
if (disposed) return;
- if (node2flags.isEmpty()) return;
+ if (node2flags.isEmpty() && selection == null) return;
pending_node = null;
node2children.clear();
node2delta.clear();
ModelDelta root = new ModelDelta(DebugPlugin.getDefault().getLaunchManager(), IModelDelta.NO_CHANGE);
for (TCFNode node : node2flags.keySet()) makeDelta(root, node, node2flags.get(node));
if (pending_node == null) {
+ all_flags = 0;
node2flags.clear();
if (!node2delta.isEmpty()) {
fireModelChanged(root);
node2delta.clear();
}
if (selection != null) {
- root = new ModelDelta(DebugPlugin.getDefault().getLaunchManager(), IModelDelta.NO_CHANGE);
- makeDelta(root, selection, IModelDelta.SELECT);
- fireModelChanged(root);
+ all_flags = IModelDelta.REVEAL;
+ ModelDelta root1 = new ModelDelta(DebugPlugin.getDefault().getLaunchManager(), IModelDelta.NO_CHANGE);
+ makeDelta(root1, selection, IModelDelta.REVEAL);
+ node2delta.clear();
+ all_flags = IModelDelta.SELECT;
+ ModelDelta root2 = new ModelDelta(DebugPlugin.getDefault().getLaunchManager(), IModelDelta.NO_CHANGE);
+ makeDelta(root2, selection, IModelDelta.SELECT);
node2delta.clear();
- selection = null;
+ if (pending_node == null) {
+ fireModelChanged(root1);
+ fireModelChanged(root2);
+ selection = null;
+ }
+ all_flags = 0;
}
}
+
+ if (pending_node == null) {
+ // OK
+ }
else if (pending_node.getData(children_count_update, this)) {
assert false;
post();
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java
index adaf843ce..07e98d1dc 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java
@@ -33,7 +33,6 @@ public class TCFNodeArrayPartition extends TCFNode {
@Override
void dispose() {
- children.reset(null);
children.dispose();
super.dispose();
}
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 df5cb65e2..5b5fc27cd 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
@@ -45,7 +45,7 @@ public class TCFNodeExecContext extends TCFNode {
private final TCFDataCache<IRunControl.RunControlContext> run_context;
private final TCFDataCache<IProcesses.ProcessContext> prs_context;
private final TCFDataCache<TCFContextState> state;
- private final TCFDataCache<BigInteger> address;
+ private final TCFDataCache<BigInteger> address; // Current PC as BigInteger
private final Map<BigInteger,TCFSourceRef> line_info_cache;
@@ -166,11 +166,11 @@ public class TCFNodeExecContext extends TCFNode {
@Override
void dispose() {
- run_context.reset(null);
- prs_context.reset(null);
- mem_context.reset(null);
- state.reset(null);
- address.reset(null);
+ run_context.dispose();
+ prs_context.dispose();
+ mem_context.dispose();
+ state.dispose();
+ address.dispose();
children_exec.dispose();
children_stack.dispose();
super.dispose();
@@ -359,6 +359,8 @@ public class TCFNodeExecContext extends TCFNode {
void onContextChanged(IRunControl.RunControlContext context) {
assert !disposed;
run_context.reset(context);
+ state.reset();
+ children_stack.reset();
children_stack.onSourceMappingChange();
addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT);
}
@@ -466,8 +468,8 @@ public class TCFNodeExecContext extends TCFNode {
addModelDelta(IModelDelta.CONTENT);
}
- // Return true if at least one child is suspended
- // The method will fail if node is not validated, see validateChildrenState()
+ // Return true if at least one child is suspended.
+ // Return null if waiting for a cache element.
private Boolean hasSuspendedChildren(Runnable done) {
if (!children_exec.validate(done)) return null;
Map<String,TCFNode> m = children_exec.getData();
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 d63cf0bb7..c83970c23 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
@@ -210,12 +210,22 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT
e = new Expression(context);
e.must_be_disposed = true;
}
- set(token, error, e);
- if (isDisposed()) disposeExpression();
+ if (!isDisposed()) set(token, error, e);
+ else if (e != null) e.dispose();
}
});
return false;
}
+ @Override
+ public void cancel() {
+ if (isValid() && getData() != null) getData().dispose();
+ super.cancel();
+ }
+ @Override
+ public void dispose() {
+ if (isValid() && getData() != null) getData().dispose();
+ super.dispose();
+ }
};
value = new TCFDataCache<IExpressions.Value>(channel) {
@Override
@@ -380,108 +390,95 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT
}
};
type_name = new TCFDataCache<String>(channel) {
- String name;
- TCFDataCache<ISymbols.Symbol> type_cache;
@Override
protected boolean startDataRetrieval() {
- if (name == null) type_cache = type;
- if (!type_cache.validate(this)) return false;
- String s = null;
- boolean get_base_type = false;
- ISymbols.Symbol t = type_cache.getData();
- if (t != null) {
- s = t.getName();
- if (s != null && t.getTypeClass() == ISymbols.TypeClass.composite) {
- s = "struct " + s;
- }
- if (s == null && t.getSize() == 0) s = "void";
- if (s == null) {
- switch (t.getTypeClass()) {
- case integer:
- switch (t.getSize()) {
- case 1: s = "char"; break;
- case 2: s = "short"; break;
- case 4: s = "int"; break;
- case 8: s = "long long"; break;
- default: s = "<Integer>"; break;
- }
- break;
- case cardinal:
- switch (t.getSize()) {
- case 1: s = "unsigned char"; break;
- case 2: s = "unsigned short"; break;
- case 4: s = "unsigned"; break;
- case 8: s = "unsigned long long"; break;
- default: s = "<Unsigned>"; break;
- }
- break;
- case real:
- switch (t.getSize()) {
- case 4: s = "float"; break;
- case 8: s = "double"; break;
- default: s = "<Float>"; break;
+ String name = null;
+ TCFDataCache<ISymbols.Symbol> type_cache = type;
+ for (;;) {
+ String s = null;
+ boolean get_base_type = false;
+ if (!type_cache.validate(this)) return false;
+ ISymbols.Symbol type_symbol = type_cache.getData();
+ if (type_symbol != null) {
+ s = type_symbol.getName();
+ if (s != null && type_symbol.getTypeClass() == ISymbols.TypeClass.composite) s = "struct " + s;
+ if (s == null && type_symbol.getSize() == 0) s = "void";
+ if (s == null) {
+ switch (type_symbol.getTypeClass()) {
+ case integer:
+ switch (type_symbol.getSize()) {
+ case 1: s = "char"; break;
+ case 2: s = "short"; break;
+ case 4: s = "int"; break;
+ case 8: s = "long long"; break;
+ default: s = "<Integer>"; break;
+ }
+ break;
+ case cardinal:
+ switch (type_symbol.getSize()) {
+ case 1: s = "unsigned char"; break;
+ case 2: s = "unsigned short"; break;
+ case 4: s = "unsigned"; break;
+ case 8: s = "unsigned long long"; break;
+ default: s = "<Unsigned>"; break;
+ }
+ break;
+ case real:
+ switch (type_symbol.getSize()) {
+ case 4: s = "float"; break;
+ case 8: s = "double"; break;
+ default: s = "<Float>"; break;
+ }
+ break;
+ case pointer:
+ s = "*";
+ get_base_type = true;
+ break;
+ case array:
+ s = "[]";
+ get_base_type = true;
+ break;
+ case composite:
+ s = "<Structure>";
+ break;
+ case function:
+ s = "<Function>";
+ break;
}
- break;
- case pointer:
- s = "*";
- get_base_type = true;
- break;
- case array:
- s = "[]";
- get_base_type = true;
- break;
- case composite:
- s = "<Structure>";
- break;
- case function:
- s = "<Function>";
- break;
}
}
- }
- if (s == null) name = "N/A";
- else if (name == null) name = s;
- else if (!get_base_type) name = s + " " + name;
- else name = s + name;
- if (get_base_type) {
- type_cache = model.getSymbolInfoCache(t.getBaseTypeID());
- if (type_cache == null) {
+ if (s == null) {
name = "N/A";
+ break;
}
- else {
- Protocol.invokeLater(this);
- return false;
+ if (name == null) name = s;
+ else if (!get_base_type) name = s + " " + name;
+ else name = s + name;
+
+ if (!get_base_type) break;
+
+ type_cache = model.getSymbolInfoCache(type_symbol.getBaseTypeID());
+ if (type_cache == null) {
+ name = "N/A";
+ break;
}
}
set(null, null, name);
return true;
}
- @Override
- public void reset() {
- super.reset();
- name = null;
- }
};
children = new TCFChildrenSubExpressions(this, 0, 0, 0);
}
- private void disposeExpression() {
- if (expression.isValid() && expression.getData() != null) {
- expression.getData().dispose();
- }
- expression.cancel();
- }
-
@Override
void dispose() {
- var_expression.reset(null);
- value.reset(null);
- type.reset(null);
- type_name.reset(null);
- string.reset(null);
- children.reset(null);
+ var_expression.dispose();
+ value.dispose();
+ type.dispose();
+ type_name.dispose();
+ string.dispose();
children.dispose();
- disposeExpression();
+ expression.dispose();
super.dispose();
}
@@ -506,11 +503,11 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor, ICastT
public void onCastToTypeChanged() {
- disposeExpression();
- value.reset();
- type.reset();
- type_name.reset();
- string.reset();
+ expression.cancel();
+ value.cancel();
+ type.cancel();
+ type_name.cancel();
+ string.cancel();
children.onCastToTypeChanged();
addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT);
}
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 4f4ab22f6..9413e9934 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
@@ -82,8 +82,8 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor {
@Override
public void dispose() {
- context.reset(null);
- value.reset(null);
+ context.dispose();
+ value.dispose();
super.dispose();
}
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 9c685522b..6d219f875 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
@@ -176,15 +176,11 @@ public class TCFNodeStackFrame extends TCFNode {
this.frame_no = frame_no;
}
- public TCFDataCache<TCFSourceRef> getLineInfo() {
- return line_info;
- }
-
@Override
void dispose() {
- stack_trace_context.reset(null);
- line_info.reset(null);
- address.reset(null);
+ stack_trace_context.dispose();
+ line_info.dispose();
+ address.dispose();
children_regs.dispose();
children_vars.dispose();
children_exps.dispose();
@@ -198,6 +194,10 @@ public class TCFNodeStackFrame extends TCFNode {
children_exps.dispose(id);
}
+ public TCFDataCache<TCFSourceRef> getLineInfo() {
+ return line_info;
+ }
+
public TCFDataCache<IStackTrace.StackTraceContext> getStackTraceContext() {
return stack_trace_context;
}
@@ -224,19 +224,33 @@ public class TCFNodeStackFrame extends TCFNode {
return super.getRelevantModelDeltaFlags(p);
}
+ private TCFChildren getChildren(IPresentationContext ctx) {
+ String id = ctx.getId();
+ if (IDebugUIConstants.ID_REGISTER_VIEW.equals(id)) return children_regs;
+ if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(id)) return children_vars;
+ if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(id)) return children_exps;
+ return null;
+ }
+
@Override
- protected boolean getData(IChildrenCountUpdate result, Runnable done) {
- if (IDebugUIConstants.ID_REGISTER_VIEW.equals(result.getPresentationContext().getId())) {
- if (!children_regs.validate(done)) return false;
- result.setChildCount(children_regs.size());
+ protected boolean getData(IHasChildrenUpdate result, Runnable done) {
+ TCFChildren c = getChildren(result.getPresentationContext());
+ if (c != null) {
+ if (!c.validate(done)) return false;
+ result.setHasChilren(c.size() > 0);
}
- else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(result.getPresentationContext().getId())) {
- if (!children_vars.validate(done)) return false;
- result.setChildCount(children_vars.size());
+ else {
+ result.setHasChilren(false);
}
- else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(result.getPresentationContext().getId())) {
- if (!children_exps.validate(done)) return false;
- result.setChildCount(children_exps.size());
+ return true;
+ }
+
+ @Override
+ protected boolean getData(IChildrenCountUpdate result, Runnable done) {
+ TCFChildren c = getChildren(result.getPresentationContext());
+ if (c != null) {
+ if (!c.validate(done)) return false;
+ result.setChildCount(c.size());
}
else {
result.setChildCount(0);
@@ -247,20 +261,13 @@ public class TCFNodeStackFrame extends TCFNode {
@Override
protected boolean getData(IChildrenUpdate result, Runnable done) {
TCFNode[] arr = null;
- if (IDebugUIConstants.ID_REGISTER_VIEW.equals(result.getPresentationContext().getId())) {
- if (!children_regs.validate(done)) return false;
- arr = children_regs.toArray();
- }
- else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(result.getPresentationContext().getId())) {
- if (!children_vars.validate(done)) return false;
- arr = children_vars.toArray();
- }
- else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(result.getPresentationContext().getId())) {
- if (!children_exps.validate(done)) return false;
- arr = children_exps.toArray();
+ TCFChildren c = getChildren(result.getPresentationContext());
+ if (c != null) {
+ if (!c.validate(done)) return false;
+ arr = c.toArray();
}
else {
- arr = new TCFNode[0];
+ return true;
}
int offset = 0;
int r_offset = result.getOffset();
@@ -275,28 +282,7 @@ public class TCFNodeStackFrame extends TCFNode {
}
@Override
- protected boolean getData(IHasChildrenUpdate result, Runnable done) {
- if (IDebugUIConstants.ID_REGISTER_VIEW.equals(result.getPresentationContext().getId())) {
- if (!children_regs.validate(done)) return false;
- result.setHasChilren(children_regs.size() > 0);
- }
- else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(result.getPresentationContext().getId())) {
- if (!children_vars.validate(done)) return false;
- result.setHasChilren(children_vars.size() > 0);
- }
- else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(result.getPresentationContext().getId())) {
- if (!children_exps.validate(done)) return false;
- result.setHasChilren(children_exps.size() > 0);
- }
- else {
- result.setHasChilren(false);
- }
- return true;
- }
-
- @Override
protected boolean getData(ILabelUpdate result, Runnable done) {
- String image_name = null;
TCFChildrenStackTrace stack_trace_cache = ((TCFNodeExecContext)parent).getStackTrace();
if (!stack_trace_cache.validate(done)) return false;
if (stack_trace_cache.getData().get(id) == null) {
@@ -304,14 +290,21 @@ public class TCFNodeStackFrame extends TCFNode {
}
else {
TCFDataCache<TCFContextState> state_cache = ((TCFNodeExecContext)parent).getState();
- if (!state_cache.validate(done)) return false;
- TCFContextState state_data = state_cache.getData();
- if (state_data != null && state_data.is_suspended) image_name = ImageCache.IMG_STACK_FRAME_SUSPENDED;
- else image_name = ImageCache.IMG_STACK_FRAME_RUNNING;
- if (!stack_trace_context.validate(done)) return false;
- if (!line_info.validate(done)) return false;
- Throwable error = stack_trace_context.getError();
+ TCFDataCache<?> pending = null;
+ if (!state_cache.validate()) pending = state_cache;
+ if (!stack_trace_context.validate()) pending = stack_trace_context;
+ if (!line_info.validate()) pending = line_info;
+ if (pending != null) {
+ pending.wait(done);
+ return false;
+ }
+ Throwable error = state_cache.getError();
+ if (error == null) error = stack_trace_context.getError();
if (error == null) error = line_info.getError();
+ TCFContextState state_data = state_cache.getData();
+ String image_name = state_data != null && state_data.is_suspended ?
+ ImageCache.IMG_STACK_FRAME_SUSPENDED :
+ ImageCache.IMG_STACK_FRAME_RUNNING;
if (error != null && state_data != null && state_data.is_suspended) {
result.setForeground(new RGB(255, 0, 0), 0);
result.setLabel(error.getClass().getName() + ": " + error.getMessage(), 0);
@@ -329,8 +322,8 @@ public class TCFNodeStackFrame extends TCFNode {
result.setLabel(label, 0);
}
}
+ result.setImageDescriptor(ImageCache.getImageDescriptor(image_name), 0);
}
- result.setImageDescriptor(ImageCache.getImageDescriptor(image_name), 0);
return true;
}
@@ -352,9 +345,9 @@ public class TCFNodeStackFrame extends TCFNode {
}
void onSuspended() {
- stack_trace_context.reset();
- line_info.reset();
- address.reset();
+ stack_trace_context.cancel();
+ line_info.cancel();
+ address.cancel();
children_regs.onSuspended();
children_vars.onSuspended();
children_exps.onSuspended();
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/trace/TraceView.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/trace/TraceView.java
index 58c4d7479..48fefb008 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/trace/TraceView.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/trace/TraceView.java
@@ -11,18 +11,24 @@
package org.eclipse.tm.internal.tcf.debug.ui.trace;
import java.io.UnsupportedEncodingException;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.tm.tcf.core.AbstractChannel;
import org.eclipse.tm.tcf.protocol.IChannel;
import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.JSON;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.ui.part.ViewPart;
@@ -93,10 +99,17 @@ public class TraceView extends ViewPart implements Protocol.ChannelOpenListener
Page(AbstractChannel channel) {
this.channel = channel;
+ update_thread.setName("TCF Trace View");
update_thread.start();
}
public void dispose() {
+ if (closed) return;
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ channel.removeTraceListener(Page.this);
+ }
+ });
synchronized (this) {
closed = true;
update_thread.interrupt();
@@ -116,7 +129,6 @@ public class TraceView extends ViewPart implements Protocol.ChannelOpenListener
public synchronized void onChannelClosed(Throwable error) {
if (error == null) {
- channel.removeTraceListener(this);
getSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
dispose();
@@ -148,15 +160,7 @@ public class TraceView extends ViewPart implements Protocol.ChannelOpenListener
bf.append(name);
}
if (data != null) {
- int i = 0;
- while (i < data.length) {
- int j = i;
- while (j < data.length && data[j] != 0) j++;
- bf.append(' ');
- bf.append(new String(data, i, j - i, "UTF8"));
- if (j < data.length && data[j] == 0) j++;
- i = j;
- }
+ appendData(bf, data);
}
bf.append('\n');
bf_line_cnt++;
@@ -185,15 +189,7 @@ public class TraceView extends ViewPart implements Protocol.ChannelOpenListener
bf.append(name);
}
if (data != null) {
- int i = 0;
- while (i < data.length) {
- int j = i;
- while (j < data.length && data[j] != 0) j++;
- bf.append(' ');
- bf.append(new String(data, i, j - i, "UTF8"));
- if (j < data.length && data[j] == 0) j++;
- i = j;
- }
+ appendData(bf, data);
}
bf.append('\n');
bf_line_cnt++;
@@ -228,7 +224,6 @@ public class TraceView extends ViewPart implements Protocol.ChannelOpenListener
Protocol.invokeAndWait(new Runnable() {
public void run() {
Protocol.removeChannelOpenListener(TraceView.this);
- for (Page p : pages) p.channel.removeTraceListener(p);
}
});
for (Page p : pages) p.dispose();
@@ -274,6 +269,81 @@ public class TraceView extends ViewPart implements Protocol.ChannelOpenListener
});
}
+ private void appendData(StringBuffer bf, byte[] data) throws UnsupportedEncodingException {
+ int pos = bf.length();
+ try {
+ Object[] o = JSON.parseSequence(data);
+ for (int i = 0; i < o.length; i++) {
+ bf.append(' ');
+ appendJSON(bf, o[i]);
+ }
+ }
+ catch (Throwable z) {
+ bf.setLength(pos);
+ for (int i = 0; i < data.length; i++) {
+ bf.append(' ');
+ int x = (data[i] >> 4) & 0xf;
+ int y = data[i] & 0xf;
+ bf.append((char)(x < 10 ? '0' + x : 'a' + x - 10));
+ bf.append((char)(y < 10 ? '0' + y : 'a' + y - 10));
+ }
+ }
+ }
+
+ private void appendJSON(StringBuffer bf, Object o) {
+ if (o instanceof byte[]) {
+ int l = ((byte[])o).length;
+ bf.append('(');
+ bf.append(l);
+ bf.append(')');
+ }
+ else if (o instanceof Collection) {
+ int cnt = 0;
+ bf.append('[');
+ for (Object i : (Collection<?>)o) {
+ if (cnt > 0) bf.append(',');
+ appendJSON(bf, i);
+ cnt++;
+ }
+ bf.append(']');
+ }
+ else if (o instanceof Map) {
+ int cnt = 0;
+ bf.append('{');
+ for (Object k : ((Map<?,?>)o).keySet()) {
+ if (cnt > 0) bf.append(',');
+ bf.append(k.toString());
+ bf.append(':');
+ appendJSON(bf, ((Map<?,?>)o).get(k));
+ cnt++;
+ }
+ bf.append('}');
+ }
+ else if (o instanceof String) {
+ bf.append('"');
+ String s = (String)o;
+ int l = s.length();
+ for (int i = 0; i < l; i++) {
+ char ch = s.charAt(i);
+ if (ch < ' ') {
+ bf.append('\\');
+ bf.append('u');
+ for (int j = 0; j < 4; j++) {
+ int x = (ch >> (4 * (3 - j))) & 0xf;
+ bf.append((char)(x < 10 ? '0' + x : 'a' + x - 10));
+ }
+ }
+ else {
+ bf.append(ch);
+ }
+ }
+ bf.append('"');
+ }
+ else {
+ bf.append(o);
+ }
+ }
+
private void showTabs() {
boolean b = false;
if (no_data != null) {
@@ -283,6 +353,38 @@ public class TraceView extends ViewPart implements Protocol.ChannelOpenListener
}
if (tabs == null) {
tabs = new TabFolder(parent, SWT.NONE);
+ Menu menu = new Menu(tabs);
+ MenuItem mi_close = new MenuItem(menu, SWT.NONE);
+ mi_close.setText("Close");
+ mi_close.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ public void widgetSelected(SelectionEvent e) {
+ if (tabs == null) return;
+ TabItem[] s = tabs.getSelection();
+ for (TabItem i : s) {
+ Page p = tab2page.get(i);
+ if (p != null) p.dispose();
+ else i.dispose();
+ }
+ }
+ });
+ MenuItem mi_close_all = new MenuItem(menu, SWT.NONE);
+ mi_close_all.setText("Close All");
+ mi_close_all.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ public void widgetSelected(SelectionEvent e) {
+ if (tabs == null) return;
+ TabItem[] s = tabs.getItems();
+ for (TabItem i : s) {
+ Page p = tab2page.get(i);
+ if (p != null) p.dispose();
+ else i.dispose();
+ }
+ }
+ });
+ tabs.setMenu(menu);
b = true;
}
if (b) parent.layout();
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
index 6ee7d861a..abfd4f531 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
@@ -530,8 +530,8 @@ public class TCFLaunch extends Launch {
listeners.remove(listener);
}
+ /** Thread safe method */
public IChannel getChannel() {
- assert Protocol.isDispatchThread();
return channel;
}
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/Main.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/Main.java
index 8724c35ca..9b9d80dfc 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/Main.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/Main.java
@@ -110,7 +110,7 @@ public class Main {
}
private static void runTestSuite(IPeer peer) {
- TCFTestSuite.TestListener listenr = new TCFTestSuite.TestListener() {
+ TCFTestSuite.TestListener listener = new TCFTestSuite.TestListener() {
public void done(Collection<Throwable> errors) {
if (errors == null || errors.isEmpty()) {
@@ -129,7 +129,7 @@ public class Main {
};
try {
- new TCFTestSuite(peer, listenr);
+ new TCFTestSuite(peer, listener, null);
}
catch (Throwable x) {
System.err.println("Cannot start test suite:");
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TCFTestSuite.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TCFTestSuite.java
index 6c9c6cc63..21fb3b639 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TCFTestSuite.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TCFTestSuite.java
@@ -16,11 +16,13 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import org.eclipse.tm.tcf.protocol.IChannel;
import org.eclipse.tm.tcf.protocol.IPeer;
import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.IPathMap.PathMapRule;
/**
* TCF Test Suite implements stress testing of communication channels and capabilities of remote peer.
@@ -49,7 +51,7 @@ public class TCFTestSuite {
public void done(Collection<Throwable> errors);
}
- public TCFTestSuite(final IPeer peer, final TestListener listener) throws IOException {
+ public TCFTestSuite(final IPeer peer, final TestListener listener, final List<PathMapRule> path_map) throws IOException {
this.listener = listener;
pending_tests.add(new Runnable() {
public void run() {
@@ -77,6 +79,14 @@ public class TCFTestSuite {
});
pending_tests.add(new Runnable() {
public void run() {
+ listener.progress("Running Path Map Test...", ++count_done, count_total);
+ for (IChannel channel : channels) {
+ active_tests.put(new TestPathMap(TCFTestSuite.this, channel, path_map), channel);
+ }
+ }
+ });
+ pending_tests.add(new Runnable() {
+ public void run() {
listener.progress("Running Expressions Test...", ++count_done, count_total);
for (IChannel channel : channels) {
active_tests.put(new TestExpressions(TCFTestSuite.this, channel), channel);
@@ -119,14 +129,6 @@ public class TCFTestSuite {
});
pending_tests.add(new Runnable() {
public void run() {
- listener.progress("Running Path Map Test...", ++count_done, count_total);
- for (IChannel channel : channels) {
- active_tests.put(new TestPathMap(TCFTestSuite.this, channel), channel);
- }
- }
- });
- pending_tests.add(new Runnable() {
- public void run() {
listener.progress("Running Interability Test...", ++count_done, count_total);
for (int i = 0; i < channels.length; i++) {
ITCFTest test = null;
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestAttachTerminate.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestAttachTerminate.java
index 35ea71bba..a2211c774 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestAttachTerminate.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestAttachTerminate.java
@@ -15,6 +15,7 @@ import java.util.HashSet;
import java.util.Map;
import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IErrorReport;
import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.IDiagnostics;
@@ -27,13 +28,12 @@ class TestAttachTerminate implements ITCFTest, IRunControl.RunControlListener {
private final IDiagnostics diag;
private final IRunControl rc;
- private final HashMap<String,IRunControl.RunControlContext> map =
+ private int cnt = 0;
+
+ private final HashMap<String,IRunControl.RunControlContext> ctx_map =
new HashMap<String,IRunControl.RunControlContext>();
private final HashSet<String> process_ids = new HashSet<String>();
- private int cnt;
- private int wait_cnt;
-
TestAttachTerminate(TCFTestSuite test_suite, IChannel channel) {
this.test_suite = test_suite;
diag = channel.getRemoteService(IDiagnostics.class);
@@ -41,11 +41,11 @@ class TestAttachTerminate implements ITCFTest, IRunControl.RunControlListener {
}
public void start() {
- if (diag == null) {
+ if (diag == null || rc == null) {
test_suite.done(this, null);
}
else {
- if (rc != null) rc.addListener(this);
+ rc.addListener(this);
diag.getTestList(new IDiagnostics.DoneGetTestList() {
public void doneGetTestList(IToken token, Throwable error, String[] list) {
assert test_suite.isActive(TestAttachTerminate.this);
@@ -56,6 +56,25 @@ class TestAttachTerminate implements ITCFTest, IRunControl.RunControlListener {
for (int i = 0; i < list.length; i++) {
if (list[i].equals("RCBP1")) {
startProcess();
+ Protocol.invokeLater(1000, new Runnable() {
+ int cnt = 0;
+ public void run() {
+ if (!test_suite.isActive(TestAttachTerminate.this)) return;
+ cnt++;
+ if (cnt < 10) {
+ Protocol.invokeLater(1000, this);
+ }
+ else if (test_suite.cancel) {
+ exit(null);
+ }
+ else if (process_ids.isEmpty()) {
+ exit(new Error("Missing 'contextAdded' event"));
+ }
+ else {
+ exit(new Error("Missing 'contextRemoved' event for " + process_ids));
+ }
+ }
+ });
return;
}
}
@@ -67,70 +86,34 @@ class TestAttachTerminate implements ITCFTest, IRunControl.RunControlListener {
}
private void startProcess() {
- if (test_suite.cancel || cnt == 4) {
- if (!process_ids.isEmpty()) {
- new Thread() {
- public void run() {
- try {
- sleep(100);
- Protocol.invokeLater(new Runnable() {
- public void run() {
- wait_cnt++;
- if (test_suite.cancel) exit(null);
- if (process_ids.isEmpty()) {
- exit(null);
- }
- else if (wait_cnt < 300) {
- startProcess();
- }
- else {
- exit(new Error("Missing 'contextRemoved' event for " + process_ids));
- }
- }
- });
- }
- catch (IllegalStateException x) {
- }
- catch (InterruptedException x) {
- }
- }
- }.start();
- }
- else {
- exit(null);
- }
- return;
- }
- cnt++;
- diag.runTest("RCBP1", new IDiagnostics.DoneRunTest() {
- public void doneRunTest(IToken token, Throwable error, String context_id) {
- if (error != null) {
- exit(error);
- }
- else {
- assert context_id != null;
- if (rc != null && map.get(context_id) == null) {
- exit(new Error("Missing 'contextAdded' event for context " + context_id));
+ for (int i = 0; i < 4; i++) {
+ diag.runTest("RCBP1", new IDiagnostics.DoneRunTest() {
+ public void doneRunTest(IToken token, Throwable error, String context_id) {
+ cnt--;
+ if (error != null) {
+ exit(error);
}
- process_ids.add(context_id);
- diag.cancelTest(context_id, new IDiagnostics.DoneCancelTest() {
- public void doneCancelTest(IToken token, Throwable error) {
- if (error != null) {
- exit(error);
- }
- else {
- startProcess();
- }
+ else {
+ assert context_id != null;
+ if (ctx_map.get(context_id) == null) {
+ exit(new Error("Missing 'contextAdded' event for context " + context_id));
}
- });
+ process_ids.add(context_id);
+ diag.cancelTest(context_id, new IDiagnostics.DoneCancelTest() {
+ public void doneCancelTest(IToken token, Throwable error) {
+ if (error != null) exit(error);
+ }
+ });
+ }
}
- }
- });
+ });
+ cnt++;
+ }
}
private void exit(Throwable x) {
if (!test_suite.isActive(this)) return;
- if (rc != null) rc.removeListener(this);
+ rc.removeListener(this);
test_suite.done(this, x);
}
@@ -148,23 +131,23 @@ class TestAttachTerminate implements ITCFTest, IRunControl.RunControlListener {
public void contextAdded(RunControlContext[] contexts) {
for (RunControlContext ctx : contexts) {
- if (map.get(ctx.getID()) != null) exit(new Error("Invalid 'contextAdded' event"));
- map.put(ctx.getID(), ctx);
+ if (ctx_map.get(ctx.getID()) != null) exit(new Error("Invalid 'contextAdded' event"));
+ ctx_map.put(ctx.getID(), ctx);
}
}
public void contextChanged(RunControlContext[] contexts) {
for (RunControlContext ctx : contexts) {
- if (map.get(ctx.getID()) == null) return;
- map.put(ctx.getID(), ctx);
+ if (ctx_map.get(ctx.getID()) == null) return;
+ ctx_map.put(ctx.getID(), ctx);
}
}
public void contextException(String context, String msg) {
- IRunControl.RunControlContext ctx = map.get(context);
+ IRunControl.RunControlContext ctx = ctx_map.get(context);
if (ctx == null) return;
if (process_ids.contains(ctx.getParentID())) {
- /* TODO: FIXME: Linux-64 PTrace sometimes intercepts SIGKILL instead of delivering it to the process
+ /*
exit(new Error("Unexpected 'contextException' event for " + context + ": " + msg));
*/
}
@@ -172,22 +155,27 @@ class TestAttachTerminate implements ITCFTest, IRunControl.RunControlListener {
public void contextRemoved(String[] context_ids) {
for (String id : context_ids) {
- map.remove(id);
+ ctx_map.remove(id);
process_ids.remove(id);
}
+ if (cnt == 0 && process_ids.isEmpty()) exit(null);
}
public void contextResumed(String context) {
}
- public void contextSuspended(String context, String pc, String reason,
- Map<String, Object> params) {
+ public void contextSuspended(String context, String pc, String reason, Map<String,Object> params) {
assert context != null;
- IRunControl.RunControlContext ctx = map.get(context);
- if (ctx == null) return;
- if (process_ids.contains(ctx.getParentID())) {
+ IRunControl.RunControlContext ctx = ctx_map.get(context);
+ if (ctx != null && process_ids.contains(ctx.getParentID())) {
ctx.resume(IRunControl.RM_RESUME, 1, new IRunControl.DoneCommand() {
public void doneCommand(IToken token, Exception error) {
+ if (error instanceof IErrorReport) {
+ int code = ((IErrorReport)error).getErrorCode();
+ if (code == IErrorReport.TCF_ERROR_ALREADY_RUNNING) return;
+ if (code == IErrorReport.TCF_ERROR_INV_CONTEXT) return;
+ }
+ if (error != null) exit(error);
}
});
}
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 d36f51caf..9975b5773 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
@@ -16,13 +16,16 @@ import java.util.HashMap;
import java.util.Map;
import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IErrorReport;
import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.IBreakpoints;
import org.eclipse.tm.tcf.services.IDiagnostics;
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 {
@@ -40,13 +43,13 @@ class TestExpressions implements ITCFTest,
private IDiagnostics.ISymbol sym_func3;
private String process_id;
private String thread_id;
- private boolean process_exited;
private boolean test_done;
private IRunControl.RunControlContext thread_ctx;
private String suspended_pc;
private boolean waiting_suspend;
private String[] stack_trace;
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>();
private final Map<String,IExpressions.Value> expr_val = new HashMap<String,IExpressions.Value>();
private final Map<String,ISymbols.Symbol> expr_sym = new HashMap<String,ISymbols.Symbol>();
@@ -85,6 +88,7 @@ class TestExpressions implements ITCFTest,
"(func2_local2 >> 1) == 1",
"+func2_local2 == 2",
"-func2_local2 == -2",
+ "(short)(int)(long)((char *)func2_local2 + 1) == 3",
"((func2_local1 + func2_local2) * 2 - 2) / 2 == 2",
"func2_local3.f_struct->f_struct->f_struct == &func2_local3"
};
@@ -117,6 +121,22 @@ class TestExpressions implements ITCFTest,
for (int i = 0; i < list.length; i++) {
if (list[i].equals("RCBP1")) {
runTest();
+ Protocol.invokeLater(1000, new Runnable() {
+ int cnt = 0;
+ public void run() {
+ if (!test_suite.isActive(TestExpressions.this)) return;
+ cnt++;
+ if (cnt < 10) {
+ Protocol.invokeLater(1000, this);
+ }
+ else if (test_suite.cancel) {
+ exit(null);
+ }
+ else {
+ exit(new Error("Missing 'contextRemoved' event for " + process_id));
+ }
+ }
+ });
return;
}
}
@@ -407,7 +427,7 @@ class TestExpressions implements ITCFTest,
test_done = true;
diag.cancelTest(process_id, new IDiagnostics.DoneCancelTest() {
public void doneCancelTest(IToken token, Throwable error) {
- exit(error);
+ if (error != null) exit(error);
}
});
}
@@ -434,9 +454,17 @@ class TestExpressions implements ITCFTest,
}
public void contextAdded(IRunControl.RunControlContext[] contexts) {
+ for (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) {
+ if (ctx_map.get(ctx.getID()) == null) return;
+ ctx_map.put(ctx.getID(), ctx);
+ }
}
public void contextException(String context, String msg) {
@@ -444,9 +472,11 @@ class TestExpressions implements ITCFTest,
public void contextRemoved(String[] context_ids) {
for (String id : context_ids) {
+ ctx_map.remove(id);
if (id.equals(process_id)) {
- process_exited = true;
- if (!test_done) exit(new Exception("Test process exited too soon"));
+ if (test_done) exit(null);
+ else exit(new Exception("Test process exited too soon"));
+ return;
}
}
}
@@ -462,6 +492,21 @@ class TestExpressions implements ITCFTest,
runTest();
}
}
+ if (test_done) {
+ IRunControl.RunControlContext ctx = ctx_map.get(context);
+ if (ctx != null && process_id != null && process_id.equals(ctx.getParentID())) {
+ ctx.resume(IRunControl.RM_RESUME, 1, new IRunControl.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (error instanceof IErrorReport) {
+ int code = ((IErrorReport)error).getErrorCode();
+ if (code == IErrorReport.TCF_ERROR_ALREADY_RUNNING) return;
+ if (code == IErrorReport.TCF_ERROR_INV_CONTEXT) return;
+ }
+ if (error != null) exit(error);
+ }
+ });
+ }
+ }
}
//--------------------------- Expressions listener ---------------------------//
@@ -473,7 +518,7 @@ class TestExpressions implements ITCFTest,
@SuppressWarnings("unchecked")
public void breakpointStatusChanged(String id, Map<String,Object> status) {
- if (id.equals(bp_id) && process_id != null && !process_exited) {
+ if (id.equals(bp_id) && process_id != null) {
String s = (String)status.get(IBreakpoints.STATUS_ERROR);
if (s != null) exit(new Exception("Invalid BP status: " + s));
Collection<Map<String,Object>> list = (Collection<Map<String,Object>>)status.get(IBreakpoints.STATUS_INSTANCES);
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestPathMap.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestPathMap.java
index 1b75e020f..998f07a02 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestPathMap.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/tests/TestPathMap.java
@@ -1,6 +1,7 @@
package org.eclipse.tm.internal.tcf.debug.tests;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Random;
@@ -12,6 +13,7 @@ import org.eclipse.tm.tcf.services.IPathMap.PathMapRule;
class TestPathMap implements ITCFTest {
private final TCFTestSuite test_suite;
+ private final List<PathMapRule> map;
private final IPathMap service;
private final Random rnd = new Random();
@@ -62,8 +64,9 @@ class TestPathMap implements ITCFTest {
}
}
- TestPathMap(TCFTestSuite test_suite, IChannel channel) {
+ TestPathMap(TCFTestSuite test_suite, IChannel channel, List<PathMapRule> map) {
this.test_suite = test_suite;
+ this.map = map;
service = channel.getRemoteService(IPathMap.class);
}
@@ -78,7 +81,16 @@ class TestPathMap implements ITCFTest {
private void test_map() {
if (cnt >= 40) {
- exit(null);
+ if (map == null) {
+ exit(null);
+ }
+ else {
+ service.set(map.toArray(new PathMapRule[map.size()]), new IPathMap.DoneSet() {
+ public void doneSet(IToken token, Exception error) {
+ exit(error);
+ }
+ });
+ }
}
else {
cnt++;
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 b86b20d55..b47a39155 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
@@ -78,7 +78,6 @@ class TestRCBP1 implements ITCFTest,
final String pc;
final String reason;
final Map<String,Object> params;
- boolean resumed;
SuspendedContext(String id, String pc, String reason, Map<String,Object> params) {
this.id = id;
@@ -338,7 +337,7 @@ class TestRCBP1 implements ITCFTest,
exit(new Exception("Invalid result of getState command"));
}
else {
- resume(sc);
+ resume(id);
}
}
else {
@@ -458,7 +457,7 @@ class TestRCBP1 implements ITCFTest,
if (error != null) exit(error);
}
});
- for (SuspendedContext s : suspended.values()) resume(s);
+ for (SuspendedContext s : suspended.values()) resume(s.id);
}
});
}
@@ -538,7 +537,12 @@ class TestRCBP1 implements ITCFTest,
}
public void contextResumed(String id) {
- if (threads.get(id) == null) return;
+ IRunControl.RunControlContext ctx = threads.get(id);
+ if (ctx == null) return;
+ if (!ctx.hasState()) {
+ exit(new Exception("Resumed event for context that HasState = false"));
+ return;
+ }
SuspendedContext sc = suspended.remove(id);
if (isMyBreakpoint(sc)) suspended_prev.put(id, sc);
running.add(id);
@@ -569,8 +573,13 @@ class TestRCBP1 implements ITCFTest,
return false;
}
- public void contextSuspended(String id, String pc, String reason, Map<String, Object> params) {
- if (threads.get(id) == null) return;
+ public void contextSuspended(final String id, String pc, String reason, Map<String, Object> params) {
+ IRunControl.RunControlContext ctx = threads.get(id);
+ if (ctx == null) return;
+ if (!ctx.hasState()) {
+ exit(new Exception("Suspended event for context that HasState = false"));
+ return;
+ }
running.remove(id);
SuspendedContext sc = suspended.get(id);
if (sc != null) {
@@ -591,7 +600,7 @@ class TestRCBP1 implements ITCFTest,
main_thread_id = id;
}
if (main_thread_id == null) {
- resume(sc);
+ resume(id);
return;
}
if (isMyBreakpoint(sc)) {
@@ -619,10 +628,19 @@ class TestRCBP1 implements ITCFTest,
final SuspendedContext sc0 = sc;
ILineNumbers.DoneMapToSource ln_done = new ILineNumbers.DoneMapToSource() {
public void doneMapToSource(IToken token, Exception error, CodeArea[] areas) {
- if (error != null) exit(error);
- else if (mm != null) runMemoryTest(sc0);
- else if (rg != null) runRegistersTest(sc0);
- else resume(sc0);
+ if (error != null) {
+ exit(error);
+ return;
+ }
+ runMemoryTest(sc0, new Runnable() {
+ public void run() {
+ runRegistersTest(sc0, new Runnable() {
+ public void run() {
+ resume(id);
+ }
+ });
+ }
+ });
}
};
if (ln != null) {
@@ -635,27 +653,27 @@ class TestRCBP1 implements ITCFTest,
}
}
- private void resume(final SuspendedContext sc) {
+ private void resume(final String id) {
assert done_starting_test_process || resume_cnt == 0;
if (!done_starting_test_process) return;
resume_cnt++;
- IRunControl.RunControlContext ctx = threads.get(sc.id);
- if (ctx != null && !sc.resumed) {
- sc.resumed = true;
+ 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() {
public void doneCommand(IToken token, Exception error) {
if (test_suite.cancel) return;
if (!test_suite.isActive(TestRCBP1.this)) return;
- if (threads.get(sc.id) == null) return;
+ if (threads.get(id) == null) return;
if (error != null) exit(error);
}
});
}
}
- private void runMemoryTest(final SuspendedContext sc) {
- if (test_suite.target_lock) {
- resume(sc);
+ private void runMemoryTest(final SuspendedContext sc, final Runnable done) {
+ if (mm == null || test_suite.target_lock) {
+ Protocol.invokeLater(done);
return;
}
test_suite.target_lock = true;
@@ -703,7 +721,7 @@ class TestRCBP1 implements ITCFTest,
if (mem_address.longValue() == 0) {
exit(new Exception("Bad value of 'tcf_test_array': " + mem_address));
}
- testSetMemoryCommand(sc, mem_ctx, mem_address, buf);
+ testSetMemoryCommand(sc, mem_ctx, mem_address, buf, done);
}
});
}
@@ -712,7 +730,8 @@ class TestRCBP1 implements ITCFTest,
private void testSetMemoryCommand(final SuspendedContext sc,
final IMemory.MemoryContext mem_ctx,
- final Number addr, final byte[] buf) {
+ final Number addr, final byte[] buf,
+ final Runnable done) {
final byte[] data = new byte[buf.length];
new Random().nextBytes(data);
mem_ctx.set(addr, 1, data, 0, data.length, 0, new IMemory.DoneMemory() {
@@ -743,7 +762,7 @@ class TestRCBP1 implements ITCFTest,
return;
}
}
- testFillMemoryCommand(sc, mem_ctx, addr, buf);
+ testFillMemoryCommand(sc, mem_ctx, addr, buf, done);
}
});
}
@@ -752,7 +771,8 @@ class TestRCBP1 implements ITCFTest,
private void testFillMemoryCommand(final SuspendedContext sc,
final IMemory.MemoryContext mem_ctx,
- final Number addr, final byte[] buf) {
+ final Number addr, final byte[] buf,
+ final Runnable done) {
final byte[] data = new byte[buf.length / 7];
new Random().nextBytes(data);
mem_ctx.fill(addr, 1, data, buf.length, 0, new IMemory.DoneMemory() {
@@ -784,15 +804,18 @@ class TestRCBP1 implements ITCFTest,
}
}
test_suite.target_lock = false;
- if (rg != null) runRegistersTest(sc);
- else resume(sc);
+ done.run();
}
});
}
});
}
- private void runRegistersTest(final SuspendedContext sc) {
+ private void runRegistersTest(final SuspendedContext sc, final Runnable done) {
+ if (rg == null) {
+ Protocol.invokeLater(done);
+ return;
+ }
if (regs.get(sc.id) == null) {
final Map<String,IRegisters.RegistersContext> reg_map =
new HashMap<String,IRegisters.RegistersContext>();
@@ -828,7 +851,7 @@ class TestRCBP1 implements ITCFTest,
}
reg_map.put(id, context);
if (cmds.isEmpty()) {
- testGetSetRegisterCommands(sc);
+ testGetSetRegisterCommands(sc, done);
}
}
}));
@@ -837,11 +860,11 @@ class TestRCBP1 implements ITCFTest,
}));
}
else {
- testGetSetRegisterCommands(sc);
+ testGetSetRegisterCommands(sc, done);
}
}
- private void testGetSetRegisterCommands(final SuspendedContext sc) {
+ private void testGetSetRegisterCommands(final SuspendedContext sc, final Runnable done) {
final Set<IToken> cmds = new HashSet<IToken>();
Map<String,IRegisters.RegistersContext> reg_map = regs.get(sc.id);
for (final IRegisters.RegistersContext ctx : reg_map.values()) {
@@ -866,7 +889,7 @@ class TestRCBP1 implements ITCFTest,
return;
}
if (cmds.isEmpty()) {
- resume(sc);
+ done.run();
}
}
}));
@@ -906,7 +929,7 @@ class TestRCBP1 implements ITCFTest,
return;
}
if (cmds.isEmpty()) {
- resume(sc);
+ done.run();
}
}
}));
@@ -914,7 +937,7 @@ class TestRCBP1 implements ITCFTest,
}));
}
if (cmds.isEmpty()) {
- resume(sc);
+ done.run();
}
}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java
index 0f84629d7..0bcacf4ee 100644
--- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFRegisters.java
@@ -395,7 +395,6 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d
final IDMContext[] parents;
Map<String,ObjectDMC> dmc_pool = new HashMap<String,ObjectDMC>();;
- boolean disposed;
public RegisterChildrenCache(IChannel channel, String id, IDMContext[] parents) {
super(channel);
@@ -410,18 +409,16 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d
}
}
- void dispose() {
- assert !disposed;
- reset();
+ @Override
+ public void dispose() {
+ super.dispose();
for (ObjectDMC dmc : dmc_pool.values()) dmc.dispose();
dmc_pool.clear();
- disposed = true;
}
@Override
public boolean startDataRetrieval() {
assert command == null;
- assert !disposed;
if (tcf_reg_service == null) {
reset(null);
return true;
@@ -484,8 +481,6 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d
final org.eclipse.tm.tcf.services.IRegisters.RegistersContext context;
final String fmt;
- boolean disposed;
-
public RegisterValueCache(IChannel channel,
org.eclipse.tm.tcf.services.IRegisters.RegistersContext context, String fmt) {
super(channel);
@@ -498,7 +493,6 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d
assert command == null;
assert tcf_reg_service != null;
assert context != null;
- assert !disposed;
command = context.get(new org.eclipse.tm.tcf.services.IRegisters.DoneGet() {
public void doneGet(IToken token, Exception err, byte[] value) {
if (command != token) return;
@@ -536,12 +530,6 @@ public class TCFDSFRegisters extends AbstractDsfService implements org.eclipse.d
});
return false;
}
-
- void dispose() {
- assert !disposed;
- reset();
- disposed = true;
- }
}
private static class RegisterGroupChangedEvent extends AbstractDMEvent<IRegisterGroupDMContext>
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java
index c7e10f766..f002f1f0f 100644
--- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java
@@ -262,9 +262,6 @@ public class TCFDSFStack extends AbstractDsfService implements IStack {
dmc.source_cache.reset();
}
}
-
- void dispose() {
- }
}
private final IChannel channel;

Back to the top