Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2011-10-26 19:23:54 +0000
committerEugene Tarassov2011-10-26 19:23:54 +0000
commit2263bebeb49134bbe6bdb13e0eee1edc1884c1a3 (patch)
treef59112576a5a0065c4ba5215309e2437ed568a97 /plugins
parente17435b5ec772877dd33ecbad9465bd02d689dfc (diff)
downloadorg.eclipse.tcf-2263bebeb49134bbe6bdb13e0eee1edc1884c1a3.tar.gz
org.eclipse.tcf-2263bebeb49134bbe6bdb13e0eee1edc1884c1a3.tar.xz
org.eclipse.tcf-2263bebeb49134bbe6bdb13e0eee1edc1884c1a3.zip
TCF Debugger: added change management support in TCFMemoryBlockRetrieval.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java79
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java30
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java2
3 files changed, 93 insertions, 18 deletions
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 81e523edd..18a3f5704 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
@@ -31,6 +31,7 @@ import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
import org.eclipse.tm.internal.tcf.debug.ui.Activator;
import org.eclipse.tm.tcf.protocol.IChannel;
import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.IExpressions;
import org.eclipse.tm.tcf.services.IMemory;
import org.eclipse.tm.tcf.services.ISymbols;
@@ -46,6 +47,20 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
private final TCFNodeExecContext exec_ctx;
private final HashSet<MemoryBlock> mem_blocks = new HashSet<MemoryBlock>();
+ private static class MemData {
+ final BigInteger addr;
+ final MemoryByte[] data;
+ final byte[] bytes;
+
+ MemData(BigInteger addr, MemoryByte[] data) {
+ int i = 0;
+ this.addr = addr;
+ this.data = data;
+ this.bytes = new byte[data.length];
+ for (MemoryByte b : data) bytes[i++] = b.getValue();
+ }
+ }
+
private class MemoryBlock extends PlatformObject implements IMemoryBlockExtension {
private final String expression;
@@ -57,6 +72,10 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
private boolean disposed;
+ private MemData mem_data; // current memory block data
+ private MemData mem_prev; // previous data - before last suspend
+ private MemData mem_last; // last retrieved memory block data
+
MemoryBlock(final String expression, long length) {
this.expression = expression;
this.length = length;
@@ -236,6 +255,20 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
return new TCFDebugTask<MemoryByte[]>(exec_ctx.getChannel()) {
int offs = 0;
public void run() {
+ if (mem_data != null &&
+ address.compareTo(mem_data.addr) >= 0 &&
+ address.add(BigInteger.valueOf(units)).compareTo(
+ mem_data.addr.add(BigInteger.valueOf(mem_data.data.length))) <= 0) {
+ offs = address.subtract(mem_data.addr).intValue();
+ MemoryByte[] res = mem_data.data;
+ if (units < mem_data.data.length) {
+ res = new MemoryByte[(int)units];
+ System.arraycopy(mem_data, offs, res, 0, res.length);
+ }
+ setHistoryFlags();
+ done(res);
+ return;
+ }
if (exec_ctx.isDisposed()) {
error("Context is disposed");
return;
@@ -269,14 +302,14 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
IMemory.ErrorOffset ofs = (IMemory.ErrorOffset)error;
int status = ofs.getStatus(cnt);
if (status == IMemory.ErrorOffset.BYTE_VALID) {
- flags = MemoryByte.READABLE | MemoryByte.WRITABLE;
+ flags |= MemoryByte.READABLE | MemoryByte.WRITABLE;
}
else if ((status & IMemory.ErrorOffset.BYTE_UNKNOWN) != 0) {
if (cnt > 0) break;
}
}
else if (error == null) {
- flags = MemoryByte.READABLE | MemoryByte.WRITABLE;
+ flags |= MemoryByte.READABLE | MemoryByte.WRITABLE;
}
res[offs] = new MemoryByte(buf[offs], (byte)flags);
offs++;
@@ -286,6 +319,8 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
mem.get(address.add(BigInteger.valueOf(offs)), 1, buf, offs, size - offs, mode, this);
}
else {
+ mem_last = mem_data = new MemData(address, res);
+ setHistoryFlags();
done(res);
}
}
@@ -294,6 +329,32 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
}.getD();
}
+ private void setHistoryFlags() {
+ if (mem_data == null) return;
+ BigInteger addr = mem_data.addr;
+ BigInteger his_start = null;
+ BigInteger his_end = null;
+ if (mem_prev != null) {
+ his_start = mem_prev.addr;
+ his_end = mem_prev.addr.add(BigInteger.valueOf(mem_prev.data.length));
+ }
+ for (MemoryByte b : mem_data.data) {
+ int flags = b.getFlags();
+ if (mem_prev != null && addr.compareTo(his_start) >= 0 && addr.compareTo(his_end) < 0) {
+ flags |= MemoryByte.HISTORY_KNOWN;
+ int offs = addr.subtract(his_start).intValue();
+ if (b.getValue() != mem_prev.data[offs].getValue()) {
+ flags |= MemoryByte.CHANGED;
+ }
+ }
+ else {
+ flags &= ~(MemoryByte.HISTORY_KNOWN | MemoryByte.CHANGED);
+ }
+ b.setFlags((byte)flags);
+ addr = addr.add(BigInteger.valueOf(1));
+ }
+ }
+
public MemoryByte[] getBytesFromOffset(BigInteger offset, long units) throws DebugException {
return getBytesFromAddress(getBigBaseAddress().add(offset), units);
}
@@ -368,11 +429,12 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
}
public boolean supportsChangeManagement() {
- return false;
+ return true;
}
public byte[] getBytes() throws DebugException {
- return null;
+ if (mem_data == null) return null;
+ return mem_data.bytes;
}
public void setValue(long offset, byte[] bytes) throws DebugException {
@@ -428,10 +490,17 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
return true;
}
- void onMemoryChanged() {
+ public String getMemoryID() {
+ return exec_ctx.id;
+ }
+
+ void onMemoryChanged(boolean suspended) {
+ assert Protocol.isDispatchThread();
if (mem_blocks.size() == 0) return;
ArrayList<DebugEvent> list = new ArrayList<DebugEvent>();
for (MemoryBlock b : mem_blocks) {
+ if (suspended) b.mem_prev = b.mem_last;
+ b.mem_data = null;
list.add(new DebugEvent(b, DebugEvent.CHANGE, DebugEvent.CONTENT));
}
DebugPlugin.getDefault().fireDebugEventSet(list.toArray(new DebugEvent[list.size()]));
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
index c4eb40d9c..1f8787bd4 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
@@ -222,6 +222,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
private class MemoryBlocksUpdate extends TCFDataCache<Map<String,TCFMemoryBlockRetrieval>> {
final Set<String> changeset = new HashSet<String>();
+ final Set<String> suspended = new HashSet<String>();
MemoryBlocksUpdate(IChannel channel) {
super(channel);
@@ -230,7 +231,9 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (!validate(this)) return;
Map<String,TCFMemoryBlockRetrieval> map = getData();
if (map != null) { // map can be null if, for example, the channel was closed
- for (TCFMemoryBlockRetrieval r : map.values()) r.onMemoryChanged();
+ for (TCFMemoryBlockRetrieval r : map.values()) {
+ r.onMemoryChanged(suspended.contains(r.getMemoryID()));
+ }
}
launch.removePendingClient(mem_blocks_update);
mem_blocks_update = null;
@@ -238,8 +241,9 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
});
}
- void add(String id) {
+ void add(String id, boolean suspended) {
changeset.add(id);
+ if (suspended) this.suspended.add(id);
}
public boolean startDataRetrieval() {
@@ -262,9 +266,11 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (!c.validate(this)) return false;
node = c.getData();
if (node == null) continue;
- if (map.get(node.id) != null) continue;
TCFMemoryBlockRetrieval r = mem_retrieval.get(node.id);
- if (r != null) map.put(node.id, r);
+ if (r != null) {
+ map.put(node.id, r);
+ if (suspended.contains(id)) suspended.add(node.id);
+ }
}
}
set(null, null, map);
@@ -329,7 +335,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onContextChanged(ctx);
}
- onMemoryChanged(id, true);
+ onMemoryChanged(id, true, false);
}
}
@@ -342,7 +348,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onMemoryChanged(addr, size);
}
- onMemoryChanged(id, true);
+ onMemoryChanged(id, true, false);
}
};
@@ -368,7 +374,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (!id.equals(context) && node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onContainerSuspended();
}
- onMemoryChanged(id, false);
+ onMemoryChanged(id, false, true);
}
TCFNode node = getNode(context);
if (node instanceof TCFNodeExecContext) {
@@ -407,7 +413,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onContextChanged(ctx);
}
- onMemoryChanged(id, true);
+ onMemoryChanged(id, true, false);
}
launch_node.onAnyContextSuspendedOrChanged();
}
@@ -442,7 +448,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
setDebugViewSelection(node, reason);
annotation_manager.updateAnnotations(null, launch);
}
- onMemoryChanged(id, false);
+ onMemoryChanged(id, false, true);
}
};
@@ -454,7 +460,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
TCFNodeExecContext exe = (TCFNodeExecContext)node;
exe.onMemoryMapChanged();
}
- onMemoryChanged(id, true);
+ onMemoryChanged(id, true, false);
display.asyncExec(new Runnable() {
public void run() {
if (PlatformUI.isWorkbenchRunning()) {
@@ -770,7 +776,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
Activator.log(bf.toString(), x);
}
- void onMemoryChanged(String id, boolean notify_references) {
+ void onMemoryChanged(String id, boolean notify_references, boolean context_suspended) {
if (channel == null) return;
if (notify_references) {
for (Object obj : context_map.values()) {
@@ -792,7 +798,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
launch.addPendingClient(mem_blocks_update);
}
}
- mem_blocks_update.add(id);
+ mem_blocks_update.add(id, context_suspended);
}
public TCFAction getActiveAction(String id) {
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 6f35b4668..833a1f933 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
@@ -1118,7 +1118,7 @@ public class TCFNodeExecContext extends TCFNode implements ISymbolOwner {
@Override
public void refresh(IWorkbenchPart part) {
if (part instanceof IMemoryRenderingSite) {
- model.onMemoryChanged(id, false);
+ model.onMemoryChanged(id, false, false);
}
else {
last_children_list = null;

Back to the top