mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Merge remote-tracking branch 'origin/GP-5229_Dan_fixTreeRegValUpdate'
This commit is contained in:
commit
11ac891e9c
3 changed files with 77 additions and 5 deletions
|
@ -340,8 +340,16 @@ public class ObjectTreeModel implements DisplaysModified {
|
||||||
while (ic < current.size() && ig < generated.size()) {
|
while (ic < current.size() && ig < generated.size()) {
|
||||||
GTreeNode nc = current.get(ic);
|
GTreeNode nc = current.get(ic);
|
||||||
GTreeNode ng = generated.get(ig);
|
GTreeNode ng = generated.get(ig);
|
||||||
|
if (nc == ng) {
|
||||||
|
ic++;
|
||||||
|
ig++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
int comp = nc.compareTo(ng);
|
int comp = nc.compareTo(ng);
|
||||||
if (comp == 0) {
|
if (comp == 0) {
|
||||||
|
// Same path, but not identical. Replace.
|
||||||
|
addNode(ic + diff, ng);
|
||||||
|
removeNode(nc);
|
||||||
ic++;
|
ic++;
|
||||||
ig++;
|
ig++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import ghidra.app.plugin.core.debug.gui.model.ObjectTreeModel.AbstractNode;
|
||||||
import ghidra.app.plugin.core.debug.gui.model.PathTableModel.PathRow;
|
import ghidra.app.plugin.core.debug.gui.model.PathTableModel.PathRow;
|
||||||
import ghidra.app.plugin.core.debug.gui.model.columns.*;
|
import ghidra.app.plugin.core.debug.gui.model.columns.*;
|
||||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||||
|
import ghidra.trace.database.ToyDBTraceBuilder.EventSuspension;
|
||||||
import ghidra.trace.model.Lifespan;
|
import ghidra.trace.model.Lifespan;
|
||||||
import ghidra.trace.model.target.*;
|
import ghidra.trace.model.target.*;
|
||||||
import ghidra.trace.model.target.TraceObject.ConflictResolution;
|
import ghidra.trace.model.target.TraceObject.ConflictResolution;
|
||||||
|
@ -46,8 +47,8 @@ import ghidra.trace.model.target.iface.TraceObjectEventScope;
|
||||||
import ghidra.trace.model.target.iface.TraceObjectInterface;
|
import ghidra.trace.model.target.iface.TraceObjectInterface;
|
||||||
import ghidra.trace.model.target.path.KeyPath;
|
import ghidra.trace.model.target.path.KeyPath;
|
||||||
import ghidra.trace.model.target.schema.SchemaContext;
|
import ghidra.trace.model.target.schema.SchemaContext;
|
||||||
import ghidra.trace.model.target.schema.XmlSchemaContext;
|
|
||||||
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
|
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
|
||||||
|
import ghidra.trace.model.target.schema.XmlSchemaContext;
|
||||||
import ghidra.trace.model.thread.TraceObjectThread;
|
import ghidra.trace.model.thread.TraceObjectThread;
|
||||||
import ghidra.trace.model.thread.TraceThread;
|
import ghidra.trace.model.thread.TraceThread;
|
||||||
|
|
||||||
|
@ -694,6 +695,47 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
|
||||||
assertPathIs(path, 11, 0);
|
assertPathIs(path, 11, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The trace-rmi handler suspends trace events during a remote transaction. Also, if there are
|
||||||
|
* sufficient events to overload the queue, the event support with clear them and just issue an
|
||||||
|
* OBJ_RESTORED event instead. This test ensures we update attributes in the tree when that
|
||||||
|
* happens.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testTreeTracksChangeAttributeWithEventsSuspended() throws Throwable {
|
||||||
|
createTraceAndPopulateObjects();
|
||||||
|
KeyPath path = KeyPath.parse("Processes[0].Threads[2].Bytes");
|
||||||
|
try (Transaction tx = tb.startTransaction()) {
|
||||||
|
TraceObject thread =
|
||||||
|
tb.trace.getObjectManager().getObjectByCanonicalPath(path.parent());
|
||||||
|
thread.setAttribute(Lifespan.nowOn(0), "Bytes", tb.arr(1, 2, 3, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
traceManager.activateTrace(tb.trace);
|
||||||
|
waitForSwing();
|
||||||
|
runSwing(() -> modelProvider.setShowPrimitivesInTree(true));
|
||||||
|
waitForTasks();
|
||||||
|
modelProvider.setPath(path);
|
||||||
|
waitForTasks();
|
||||||
|
|
||||||
|
waitForPass(() -> {
|
||||||
|
AbstractNode node = modelProvider.objectsTreePanel.treeModel.getNode(path);
|
||||||
|
assertEquals("<html>Bytes: 01:02:03:04", node.getDisplayText());
|
||||||
|
});
|
||||||
|
|
||||||
|
try (Transaction tx = tb.startTransaction(); EventSuspension es = tb.suspendEvents()) {
|
||||||
|
TraceObject thread =
|
||||||
|
tb.trace.getObjectManager().getObjectByCanonicalPath(path.parent());
|
||||||
|
thread.setAttribute(Lifespan.nowOn(0), "Bytes", tb.arr(5, 6, 7, 8));
|
||||||
|
}
|
||||||
|
waitForTasks();
|
||||||
|
|
||||||
|
waitForPass(() -> {
|
||||||
|
AbstractNode node = modelProvider.objectsTreePanel.treeModel.getNode(path);
|
||||||
|
assertEquals("<html>Bytes: 05:06:07:08", node.getDisplayText());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPanesTrackAddAttribute() throws Throwable {
|
public void testPanesTrackAddAttribute() throws Throwable {
|
||||||
createTraceAndPopulateObjects();
|
createTraceAndPopulateObjects();
|
||||||
|
@ -1239,11 +1281,9 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
|
||||||
traceManager.activateTrace(tb.trace);
|
traceManager.activateTrace(tb.trace);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
tb.trace.setEventsEnabled(false);
|
try (Transaction tx = tb.startTransaction(); EventSuspension es = tb.suspendEvents()) {
|
||||||
try (Transaction tx = tb.startTransaction()) {
|
|
||||||
tb.trace.getTimeManager().getSnapshot(30, true);
|
tb.trace.getTimeManager().getSnapshot(30, true);
|
||||||
}
|
}
|
||||||
tb.trace.setEventsEnabled(true);
|
|
||||||
waitForDomainObject(tb.trace);
|
waitForDomainObject(tb.trace);
|
||||||
|
|
||||||
// NB. The plot adds a margin of 1
|
// NB. The plot adds a margin of 1
|
||||||
|
|
|
@ -56,8 +56,9 @@ import ghidra.trace.model.*;
|
||||||
import ghidra.trace.model.guest.TraceGuestPlatform;
|
import ghidra.trace.model.guest.TraceGuestPlatform;
|
||||||
import ghidra.trace.model.guest.TracePlatform;
|
import ghidra.trace.model.guest.TracePlatform;
|
||||||
import ghidra.trace.model.symbol.TraceReferenceManager;
|
import ghidra.trace.model.symbol.TraceReferenceManager;
|
||||||
import ghidra.trace.model.target.*;
|
import ghidra.trace.model.target.TraceObject;
|
||||||
import ghidra.trace.model.target.TraceObject.ConflictResolution;
|
import ghidra.trace.model.target.TraceObject.ConflictResolution;
|
||||||
|
import ghidra.trace.model.target.TraceObjectValue;
|
||||||
import ghidra.trace.model.target.path.KeyPath;
|
import ghidra.trace.model.target.path.KeyPath;
|
||||||
import ghidra.trace.model.target.path.PathFilter;
|
import ghidra.trace.model.target.path.PathFilter;
|
||||||
import ghidra.trace.model.thread.TraceObjectThread;
|
import ghidra.trace.model.thread.TraceObjectThread;
|
||||||
|
@ -432,6 +433,17 @@ public class ToyDBTraceBuilder implements AutoCloseable {
|
||||||
return result.flip();
|
return result.flip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class EventSuspension implements AutoCloseable {
|
||||||
|
public EventSuspension() {
|
||||||
|
trace.setEventsEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
trace.setEventsEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a transaction on the trace
|
* Start a transaction on the trace
|
||||||
*
|
*
|
||||||
|
@ -444,6 +456,18 @@ public class ToyDBTraceBuilder implements AutoCloseable {
|
||||||
return trace.openTransaction("Testing");
|
return trace.openTransaction("Testing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suspend events for the trace
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Use this in a {@code try-with-resources} block
|
||||||
|
*
|
||||||
|
* @return the suspension handle
|
||||||
|
*/
|
||||||
|
public EventSuspension suspendEvents() {
|
||||||
|
return new EventSuspension();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure the given bookmark type exists and retrieve it
|
* Ensure the given bookmark type exists and retrieve it
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue