- * The manager remembers the last active thread for every open trace. If the trace has never
- * been active, then the last active thread is null. If trace is the active trace, then this
- * will return the currently active thread.
- *
- * @param trace the trace
- * @return the thread, or null
- */
- TraceThread getCurrentThreadFor(Trace trace);
-
/**
* Get the active snap
*
@@ -255,47 +242,125 @@ public interface DebuggerTraceManagerService {
*/
void activate(DebuggerCoordinates coordinates);
+ /**
+ * Resolve coordinates for the given trace using the manager's "best judgment"
+ *
+ *
+ * The manager may use a variety of sources of context including the current trace, the last
+ * coordinates for a trace, the target's last/current focus, the list of active threads, etc.
+ *
+ * @param trace the trace
+ * @return the best coordinates
+ */
+ DebuggerCoordinates resolveTrace(Trace trace);
+
/**
* Activate the given trace
*
* @param trace the desired trace
*/
- void activateTrace(Trace trace);
+ default void activateTrace(Trace trace) {
+ activate(resolveTrace(trace));
+ }
+
+ /**
+ * Resolve coordinates for the given thread using the manager's "best judgment"
+ *
+ * @see #resolveTrace(Trace)
+ * @param thread the thread
+ * @return the best coordinates
+ */
+ DebuggerCoordinates resolveThread(TraceThread thread);
/**
* Activate the given thread
*
* @param thread the desired thread
*/
- void activateThread(TraceThread thread);
+ default void activateThread(TraceThread thread) {
+ activate(resolveThread(thread));
+ }
+
+ /**
+ * Resolve coordinates for the given snap using the manager's "best judgment"
+ *
+ * @see #resolveTrace(Trace)
+ * @param snap the snapshot key
+ * @return the best coordinates
+ */
+ DebuggerCoordinates resolveSnap(long snap);
/**
* Activate the given snapshot key
*
* @param snap the desired snapshot key
*/
- void activateSnap(long snap);
+ default void activateSnap(long snap) {
+ activate(resolveSnap(snap));
+ }
+
+ /**
+ * Resolve coordinates for the given time using the manager's "best judgment"
+ *
+ * @see #resolveTrace(Trace)
+ * @param time the time
+ * @return the best coordinates
+ */
+ DebuggerCoordinates resolveTime(TraceSchedule time);
/**
* Activate the given point in time, possibly invoking emulation
*
* @param time the desired schedule
*/
- void activateTime(TraceSchedule time);
+ default void activateTime(TraceSchedule time) {
+ activate(resolveTime(time));
+ }
+
+ /**
+ * Resolve coordinates for the given view using the manager's "best judgment"
+ *
+ * @see #resolveTrace(Trace)
+ * @param view the view
+ * @return the best coordinates
+ */
+ DebuggerCoordinates resolveView(TraceProgramView view);
+
+ /**
+ * Resolve coordinates for the given frame level using the manager's "best judgment"
+ *
+ * @see #resolveTrace(Trace)
+ * @param frameLevel the frame level, 0 being the innermost
+ * @return the best coordinates
+ */
+ DebuggerCoordinates resolveFrame(int frameLevel);
/**
* Activate the given stack frame
*
* @param frameLevel the level of the desired frame, 0 being innermost
*/
- void activateFrame(int frameLevel);
+ default void activateFrame(int frameLevel) {
+ activate(resolveFrame(frameLevel));
+ }
+
+ /**
+ * Resolve coordinates for the given object using the manager's "best judgment"
+ *
+ * @see #resolveTrace(Trace)
+ * @param object the object
+ * @return the best coordinates
+ */
+ DebuggerCoordinates resolveObject(TraceObject object);
/**
* Activate the given object
*
* @param object the desired object
*/
- void activateObject(TraceObject object);
+ default void activateObject(TraceObject object) {
+ activate(resolveObject(object));
+ }
/**
* Control whether the trace manager automatically activates the "present snapshot"
@@ -413,14 +478,6 @@ public interface DebuggerTraceManagerService {
*/
void removeAutoCloseOnTerminateChangeListener(BooleanChangeAdapter listener);
- /**
- * Fill in an incomplete coordinate specification, using the manager's "best judgment"
- *
- * @param coords the possibly-incomplete coordinates
- * @return the complete resolved coordinates
- */
- DebuggerCoordinates resolveCoordinates(DebuggerCoordinates coordinates);
-
/**
* If the given coordinates are already materialized, get the snapshot
*
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java
index 4234bfcf62..a472e03a4f 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java
@@ -1138,8 +1138,7 @@ public interface FlatDebuggerAPI {
* @return the editor
*/
default StateEditor createStateEditor(DebuggerCoordinates coordinates) {
- return getEditingService()
- .createStateEditor(getTraceManager().resolveCoordinates(coordinates));
+ return getEditingService().createStateEditor(coordinates);
}
/**
@@ -1150,9 +1149,9 @@ public interface FlatDebuggerAPI {
* @return the editor
*/
default StateEditor createStateEditor(Trace trace, long snap) {
- return getEditingService().createStateEditor(DebuggerCoordinates
- .trace(trace)
- .withSnap(snap));
+ return getEditingService().createStateEditor(getTraceManager()
+ .resolveTrace(trace)
+ .snap(snap));
}
/**
@@ -1164,10 +1163,10 @@ public interface FlatDebuggerAPI {
* @return the editor
*/
default StateEditor createStateEditor(TraceThread thread, int frame, long snap) {
- return getEditingService().createStateEditor(DebuggerCoordinates
- .thread(thread)
- .withSnap(snap)
- .withFrame(frame));
+ return getEditingService().createStateEditor(getTraceManager()
+ .resolveThread(thread)
+ .snap(snap)
+ .frame(frame));
}
/**
diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/AbstractGhidraHeadedDebuggerGUITest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/AbstractGhidraHeadedDebuggerGUITest.java
index 8efff5afda..b01d02f7b1 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/AbstractGhidraHeadedDebuggerGUITest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/AbstractGhidraHeadedDebuggerGUITest.java
@@ -600,7 +600,7 @@ public abstract class AbstractGhidraHeadedDebuggerGUITest
modelService.addModel(mb.testModel);
}
- protected TraceRecorder recordAndWaitSync() throws Exception {
+ protected TraceRecorder recordAndWaitSync() throws Throwable {
createTestModel();
mb.createTestProcessesAndThreads();
mb.createTestThreadRegisterBanks();
@@ -613,22 +613,7 @@ public abstract class AbstractGhidraHeadedDebuggerGUITest
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
- waitFor(() -> {
- TraceThread thread = recorder.getTraceThread(mb.testThread1);
- if (thread == null) {
- return false;
- }
- /*
- DebuggerRegisterMapper mapper = recorder.getRegisterMapper(thread);
- if (mapper == null) {
- return false;
- }
- if (!mapper.getRegistersOnTarget().containsAll(baseRegs)) {
- return false;
- }
- */
- return true;
- });
+ waitRecorder(recorder);
return recorder;
}
diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java
index 45330e0c65..5ad0ee9f24 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProviderTest.java
@@ -1343,7 +1343,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
regs.setValue(1, new RegisterValue(pc, new BigInteger("00404321", 16)));
}
waitForDomainObject(tb.trace);
- traceManager.activate(DebuggerCoordinates.threadSnap(thread, 0));
+ traceManager.activate(DebuggerCoordinates.NOWHERE.thread(thread).snap(0));
waitForSwing();
assertEquals(tb.addr(0x00401234), listingProvider.getLocation().getAddress());
@@ -1398,7 +1398,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
}
waitForDomainObject(tb.trace);
- traceManager.activate(DebuggerCoordinates.threadSnap(thread, 0));
+ traceManager.activate(DebuggerCoordinates.NOWHERE.thread(thread).snap(0));
waitForSwing();
assertEquals(tb.addr(0x00401234), listingProvider.getLocation().getAddress());
@@ -1432,7 +1432,7 @@ public class DebuggerListingProviderTest extends AbstractGhidraHeadedDebuggerGUI
stack.getFrame(0, true);
}
waitForDomainObject(tb.trace);
- traceManager.activate(DebuggerCoordinates.threadSnap(thread, 0));
+ traceManager.activate(DebuggerCoordinates.NOWHERE.thread(thread).snap(0));
waitForSwing();
assertEquals(tb.addr(0x00401234), listingProvider.getLocation().getAddress());
diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProviderTest.java
index 482b07bbb5..f5c7b90f59 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProviderTest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/memory/DebuggerMemoryBytesProviderTest.java
@@ -945,7 +945,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
regs.setValue(1, new RegisterValue(pc, new BigInteger("00404321", 16)));
}
waitForDomainObject(tb.trace);
- traceManager.activate(DebuggerCoordinates.threadSnap(thread, 0));
+ traceManager.activate(DebuggerCoordinates.NOWHERE.thread(thread).snap(0));
waitForSwing();
assertEquals(tb.addr(0x00401234), memBytesProvider.getLocation().getAddress());
@@ -1000,7 +1000,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
}
waitForDomainObject(tb.trace);
- traceManager.activate(DebuggerCoordinates.threadSnap(thread, 0));
+ traceManager.activate(DebuggerCoordinates.NOWHERE.thread(thread).snap(0));
waitForSwing();
assertEquals(tb.addr(0x00401234), memBytesProvider.getLocation().getAddress());
@@ -1034,7 +1034,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
stack.getFrame(0, true);
}
waitForDomainObject(tb.trace);
- traceManager.activate(DebuggerCoordinates.threadSnap(thread, 0));
+ traceManager.activate(DebuggerCoordinates.NOWHERE.thread(thread).snap(0));
waitForSwing();
assertEquals(tb.addr(0x00401234), memBytesProvider.getLocation().getAddress());
diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelProviderTest.java
index c73ca91c07..d38db9f7ca 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelProviderTest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/model/DebuggerModelProviderTest.java
@@ -27,6 +27,7 @@ import com.google.common.collect.Range;
import docking.widgets.table.DynamicTableColumn;
import docking.widgets.table.GDynamicColumnTableModel;
+import docking.widgets.tree.support.GTreeSelectionEvent.EventOrigin;
import generic.Unique;
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
@@ -40,10 +41,10 @@ import ghidra.dbg.target.TargetObject;
import ghidra.dbg.target.schema.SchemaContext;
import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName;
import ghidra.dbg.target.schema.XmlSchemaContext;
-import ghidra.trace.database.target.DBTraceObject;
-import ghidra.trace.database.target.DBTraceObjectManager;
import ghidra.trace.model.target.*;
import ghidra.trace.model.target.TraceObject.ConflictResolution;
+import ghidra.trace.model.thread.TraceObjectThread;
+import ghidra.trace.model.thread.TraceThread;
import ghidra.util.database.UndoableTransaction;
public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITest {
@@ -52,34 +53,45 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
static {
try {
- CTX = XmlSchemaContext.deserialize("" + //
- "" + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- " " + //
- "");
+ CTX = XmlSchemaContext.deserialize(
+ """
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ """);
}
catch (JDOMException e) {
throw new AssertionError();
@@ -104,9 +116,6 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
public void setUpModelProviderTest() throws Exception {
modelPlugin = addPlugin(tool, DebuggerModelPlugin.class);
modelProvider = waitForComponentProvider(DebuggerModelProvider.class);
-
- // So I can manipulate the coordinates
- //addPlugin(tool, DebuggerThreadsPlugin.class);
}
@After
@@ -126,16 +135,16 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
}
protected TraceObjectValue createSessionObject() throws Throwable {
- DBTraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObjectManager objects = tb.trace.getObjectManager();
try (UndoableTransaction tid = tb.startTransaction()) {
return objects.createRootObject(CTX.getSchema(new SchemaName("Session")));
}
}
- protected DBTraceObject createThread(long i, DBTraceObject prevThread) {
- DBTraceObjectManager objects = tb.trace.getObjectManager();
+ protected TraceObject createThread(long i, TraceObject prevThread) {
+ TraceObjectManager objects = tb.trace.getObjectManager();
TraceObjectKeyPath threadContainerPath = TraceObjectKeyPath.parse("Processes[0].Threads");
- DBTraceObject thread = objects.createObject(threadContainerPath.index(i));
+ TraceObject thread = objects.createObject(threadContainerPath.index(i));
thread.insert(Range.closed(i, 10L), ConflictResolution.DENY);
thread.insert(Range.atLeast(10 + i), ConflictResolution.DENY);
thread.setAttribute(Range.atLeast(i), "Attribute " + i, "Some value");
@@ -151,18 +160,31 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
return thread;
}
+ protected TraceObject createStack(TraceObject thread) {
+ try (UndoableTransaction tid = tb.startTransaction()) {
+ TraceObjectKeyPath stackPath = thread.getCanonicalPath().key("Stack");
+ TraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObject stack = objects.createObject(stackPath);
+ objects.createObject(stackPath.index(0))
+ .insert(thread.getLife().span(), ConflictResolution.TRUNCATE);
+ objects.createObject(stackPath.index(1))
+ .insert(thread.getLife().span(), ConflictResolution.TRUNCATE);
+ return stack;
+ }
+ }
+
protected void populateThreads() throws Throwable {
try (UndoableTransaction tid = tb.startTransaction()) {
- DBTraceObject prevThread = null;
+ TraceObject prevThread = null;
for (long i = 0; i < 10; i++) {
- DBTraceObject thread = createThread(i, prevThread);
+ TraceObject thread = createThread(i, prevThread);
prevThread = thread;
}
}
}
protected void addThread10() throws Throwable {
- DBTraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObjectManager objects = tb.trace.getObjectManager();
try (UndoableTransaction tid = tb.startTransaction()) {
createThread(10, objects.getObjectByCanonicalPath(
TraceObjectKeyPath.parse("Processes[0].Threads[9]")));
@@ -170,9 +192,9 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
}
protected void populateHandles() throws Throwable {
- DBTraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObjectManager objects = tb.trace.getObjectManager();
try (UndoableTransaction tid = tb.startTransaction()) {
- DBTraceObject handleContainer =
+ TraceObject handleContainer =
objects.createObject(TraceObjectKeyPath.parse("Processes[0].Handles"));
handleContainer.insert(Range.atLeast(0L), ConflictResolution.DENY);
for (int i = 0; i < 10; i++) {
@@ -183,10 +205,10 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
}
protected void populateLinks() throws Throwable {
- DBTraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObjectManager objects = tb.trace.getObjectManager();
TraceObjectKeyPath threadContainerPath = TraceObjectKeyPath.parse("Processes[0].Threads");
try (UndoableTransaction tid = tb.startTransaction()) {
- DBTraceObject linkContainer =
+ TraceObject linkContainer =
objects.createObject(TraceObjectKeyPath.parse("Processes[0].Links"));
linkContainer.insert(Range.atLeast(0L), ConflictResolution.DENY);
for (int i = 0; i < 10; i++) {
@@ -197,7 +219,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
}
protected void populateBoxedPrimitive() throws Throwable {
- DBTraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObjectManager objects = tb.trace.getObjectManager();
try (UndoableTransaction tid = tb.startTransaction()) {
TraceObject boxed =
objects.createObject(TraceObjectKeyPath.parse("Processes[0].Boxed"));
@@ -291,7 +313,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
createTraceAndPopulateObjects();
traceManager.activateTrace(tb.trace);
- waitForSwing();
+ waitForTasks();
modelProvider.objectsTreePanel
.setSelectedKeyPaths(List.of(TraceObjectKeyPath.parse("Processes[0].Threads")));
waitForSwing();
@@ -306,7 +328,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Threads"));
- waitForSwing();
+ waitForTasks();
ValueRow selElem = waitForValue(() -> {
List rows = modelProvider.elementsTablePanel.tableModel.getModelData();
@@ -316,7 +338,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
return rows.get(2);
});
modelProvider.elementsTablePanel.setSelectedItem(selElem);
- waitForSwing();
+ waitForTasks();
waitForPass(() -> assertEquals(3,
modelProvider.attributesTablePanel.tableModel.getModelData().size()));
@@ -329,7 +351,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].NoSuch"));
- waitForSwing();
+ waitForTasks();
assertEquals("No such object at path Processes[0].NoSuch", tool.getStatusInfo());
}
@@ -341,7 +363,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Handles"));
- waitForSwing();
+ waitForTasks();
int valColIndex =
waitForValue(() -> findColumnOfClass(modelProvider.elementsTablePanel.tableModel,
@@ -364,7 +386,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Threads"));
- waitForSwing();
+ waitForTasks();
modelProvider.pathField.setText("SomeNonsenseToBeCancelled");
triggerEscapeKey(modelProvider.pathField);
@@ -380,7 +402,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Links"));
- waitForSwing();
+ waitForTasks();
ValueRow row2 = waitForValue(() -> {
return modelProvider.elementsTablePanel.tableModel.getModelData()
@@ -390,7 +412,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
.orElse(null);
});
modelProvider.elementsTablePanel.setSelectedItem(row2);
- waitForSwing();
+ waitForTasks();
int rowIndex = waitForValue(() -> {
int index = modelProvider.elementsTablePanel.table.getSelectedRow();
if (index == -1) {
@@ -410,7 +432,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Threads"));
- waitForSwing();
+ waitForTasks();
ValueRow row2 = waitForValue(() -> {
return modelProvider.elementsTablePanel.tableModel.getModelData()
@@ -420,7 +442,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
.orElse(null);
});
modelProvider.elementsTablePanel.setSelectedItem(row2);
- waitForSwing();
+ waitForTasks();
int rowIndex = waitForValue(() -> {
int index = modelProvider.elementsTablePanel.table.getSelectedRow();
if (index == -1) {
@@ -458,9 +480,9 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Threads[2]"));
- waitForSwing();
+ waitForTasks();
selectAttribute("_next");
- waitForSwing();
+ waitForTasks();
int rowIndex = waitForValue(() -> {
int index = modelProvider.attributesTablePanel.table.getSelectedRow();
@@ -481,7 +503,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0]"));
- waitForSwing();
+ waitForTasks();
PathRow rowNext = waitForValue(() -> {
return modelProvider.attributesTablePanel.tableModel.getModelData()
@@ -497,7 +519,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
.orElse(null);
});
modelProvider.attributesTablePanel.setSelectedItem(rowNext);
- waitForSwing();
+ waitForTasks();
int rowIndex = waitForValue(() -> {
int index = modelProvider.attributesTablePanel.table.getSelectedRow();
if (index == -1) {
@@ -519,7 +541,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Threads"));
- waitForSwing();
+ waitForTasks();
assertPathIs(TraceObjectKeyPath.parse("Processes[0].Threads"), 10, 0);
@@ -545,7 +567,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Threads[2]"));
- waitForSwing();
+ waitForTasks();
AbstractNode nodeThread2 =
waitForValue(() -> modelProvider.objectsTreePanel.getSelectedItem());
@@ -573,14 +595,16 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Threads[2]"));
- waitForSwing();
+ waitForTasks();
selectAttribute("_next");
waitForSwing();
assertEnabled(modelProvider, modelProvider.actionFollowLink);
performAction(modelProvider.actionFollowLink, modelProvider, true);
- assertPathIs(TraceObjectKeyPath.parse("Processes[0].Threads[3]"), 0, 5);
+ TraceObjectKeyPath thread3Path = TraceObjectKeyPath.parse("Processes[0].Threads[3]");
+ assertPathIs(thread3Path, 0, 5);
+ assertEquals(thread3Path, traceManager.getCurrentObject().getCanonicalPath());
}
@Test
@@ -590,7 +614,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Threads[2]"));
- waitForSwing();
+ waitForTasks();
performAction(modelProvider.actionCloneWindow);
@@ -608,12 +632,12 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(path);
- waitForSwing();
+ waitForTasks();
assertPathIsThreadsContainer();
addThread10();
- waitForSwing();
+ waitForTasks();
assertPathIs(path, 11, 0);
}
@@ -626,15 +650,15 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(path);
- waitForSwing();
+ waitForTasks();
assertPathIs(path, 0, 3);
try (UndoableTransaction tid = tb.startTransaction()) {
- DBTraceObject thread = tb.trace.getObjectManager().getObjectByCanonicalPath(path);
+ TraceObject thread = tb.trace.getObjectManager().getObjectByCanonicalPath(path);
thread.setAttribute(Range.atLeast(0L), "NewAttribute", 11);
}
- waitForSwing();
+ waitForTasks();
assertPathIs(path, 0, 4);
}
@@ -647,15 +671,15 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(path);
- waitForSwing();
+ waitForTasks();
assertPathIsThreadsContainer();
try (UndoableTransaction tid = tb.startTransaction()) {
- DBTraceObject threads = tb.trace.getObjectManager().getObjectByCanonicalPath(path);
+ TraceObject threads = tb.trace.getObjectManager().getObjectByCanonicalPath(path);
threads.setElement(Range.all(), 2, null);
}
- waitForSwing();
+ waitForTasks();
assertPathIs(path, 9, 0);
}
@@ -668,15 +692,15 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(path);
- waitForSwing();
+ waitForTasks();
assertPathIs(path, 0, 3);
try (UndoableTransaction tid = tb.startTransaction()) {
- DBTraceObject thread = tb.trace.getObjectManager().getObjectByCanonicalPath(path);
+ TraceObject thread = tb.trace.getObjectManager().getObjectByCanonicalPath(path);
thread.setAttribute(Range.all(), "_self", null);
}
- waitForSwing();
+ waitForTasks();
assertPathIs(path, 0, 2);
}
@@ -693,21 +717,21 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateSnap(2);
waitForSwing();
modelProvider.setPath(path);
- waitForSwing();
+ waitForTasks();
assertPathIs(path, 3, 0);
try (UndoableTransaction tid = tb.startTransaction()) {
element2.setLifespan(Range.atLeast(10L), ConflictResolution.DENY);
}
- waitForSwing();
+ waitForTasks();
assertPathIs(path, 2, 0);
try (UndoableTransaction tid = tb.startTransaction()) {
element2.setLifespan(Range.atLeast(2L), ConflictResolution.DENY);
}
- waitForSwing();
+ waitForTasks();
assertPathIs(path, 3, 0);
}
@@ -725,21 +749,21 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateSnap(2);
waitForSwing();
modelProvider.setPath(path);
- waitForSwing();
+ waitForTasks();
assertPathIs(path, 0, 4); // _next created at snap 3
try (UndoableTransaction tid = tb.startTransaction()) {
attrSelf.setLifespan(Range.atLeast(10L), ConflictResolution.DENY);
}
- waitForSwing();
+ waitForTasks();
assertPathIs(path, 0, 3);
try (UndoableTransaction tid = tb.startTransaction()) {
attrSelf.setLifespan(Range.atLeast(2L), ConflictResolution.DENY);
}
- waitForSwing();
+ waitForTasks();
assertPathIs(path, 0, 4);
}
@@ -753,7 +777,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(path);
- waitForSwing();
+ waitForTasks();
AbstractNode node =
waitForValue(() -> modelProvider.objectsTreePanel.treeModel.getNode(path));
@@ -762,8 +786,253 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerGUITe
try (UndoableTransaction tid = tb.startTransaction()) {
thread.setAttribute(Range.atLeast(0L), "_display", "Renamed Thread");
}
- waitForSwing();
+ waitForTasks();
waitForPass(() -> assertEquals("Renamed Thread", node.getDisplayText()));
}
+
+ @Test
+ public void testTreeSelectionActivatesObject() throws Throwable {
+ createTraceAndPopulateObjects();
+
+ TraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObject root = objects.getRootObject();
+ TraceObjectKeyPath processesPath = TraceObjectKeyPath.parse("Processes");
+ TraceObject processes = objects.getObjectByCanonicalPath(processesPath);
+ traceManager.activateObject(root);
+ waitForTasks();
+
+ modelProvider.setTreeSelection(processesPath, EventOrigin.USER_GENERATED);
+ waitForSwing();
+ assertEquals(processes, traceManager.getCurrentObject());
+ }
+
+ @Test
+ public void testElementSelectionActivatesObject() throws Throwable {
+ createTraceAndPopulateObjects();
+ TraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObject processes =
+ objects.getObjectByCanonicalPath(TraceObjectKeyPath.parse("Processes"));
+ TraceObject process0 = processes.getElement(0, 0).getChild();
+ traceManager.activateObject(processes);
+ waitForTasks();
+
+ assertTrue(modelProvider.elementsTablePanel.trySelect(process0));
+ waitForSwing();
+ assertEquals(process0, traceManager.getCurrentObject());
+ }
+
+ @Test
+ public void testAttributeSelectionActivatesObject() throws Throwable {
+ createTraceAndPopulateObjects();
+
+ TraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObject root = objects.getRootObject();
+ TraceObject processes = root.getAttribute(0, "Processes").getChild();
+ traceManager.activateObject(root);
+ waitForTasks();
+
+ assertTrue(modelProvider.attributesTablePanel.trySelect(processes));
+ waitForSwing();
+ assertEquals(processes, traceManager.getCurrentObject());
+ }
+
+ @Test
+ public void testObjectActivationSelectsTree() throws Throwable {
+ createTraceAndPopulateObjects();
+ TraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObject root = objects.getRootObject();
+ TraceObject process0 =
+ objects.getObjectByCanonicalPath(TraceObjectKeyPath.parse("Processes[0]"));
+
+ traceManager.activateObject(root);
+ waitForTasks();
+ assertEquals(root, modelProvider.getTreeSelection().getChild());
+
+ /**
+ * NOTE: Have to skip a level, lest is select the child in the attributes pane instead
+ */
+ traceManager.activateObject(process0);
+ waitForTasks();
+ assertEquals(process0, modelProvider.getTreeSelection().getChild());
+ }
+
+ @Test
+ public void testObjectActivationParentDoesNothing() throws Throwable {
+ createTraceAndPopulateObjects();
+ TraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObject root = objects.getRootObject();
+ TraceObject processes = root.getAttribute(0, "Processes").getChild();
+
+ traceManager.activateObject(processes);
+ waitForTasks();
+ assertEquals(processes, modelProvider.getTreeSelection().getChild());
+
+ // TODO: Is this the desired behavior?
+ traceManager.activateObject(root);
+ waitForTasks();
+ assertEquals(processes, modelProvider.getTreeSelection().getChild());
+ }
+
+ @Test
+ public void testObjectActivationSiblingSelectsTree() throws Throwable {
+ createTraceAndPopulateObjects();
+ TraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObject thread0 =
+ objects.getObjectByCanonicalPath(TraceObjectKeyPath.parse("Processes[0].Threads[0]"));
+ TraceObject thread1 =
+ objects.getObjectByCanonicalPath(TraceObjectKeyPath.parse("Processes[0].Threads[1]"));
+
+ modelProvider.setShowHidden(true);
+ traceManager.activateObject(thread0);
+ traceManager.activateSnap(1);
+ waitForTasks();
+ modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].Threads[0]._self"));
+ waitForTasks();
+
+ traceManager.activateObject(thread1);
+ waitForSwing();
+ assertEquals(TraceObjectKeyPath.parse("Processes[0].Threads[0]._next"),
+ modelProvider.getPath());
+ }
+
+ @Test
+ public void testObjectActivationSelectsElement() throws Throwable {
+ createTraceAndPopulateObjects();
+ TraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObjectKeyPath processesPath = TraceObjectKeyPath.parse("Processes");
+ TraceObject processes = objects.getObjectByCanonicalPath(processesPath);
+ TraceObject process0 = processes.getElement(0, 0).getChild();
+ traceManager.activateObject(processes);
+ waitForTasks();
+
+ /**
+ * TODO: It's interesting that activating a parent then a child produces a different end
+ * result than activating the child directly.
+ */
+ traceManager.activateObject(process0);
+ waitForTasks();
+
+ assertEquals(processesPath, modelProvider.getPath());
+ assertEquals(process0,
+ modelProvider.elementsTablePanel.getSelectedItem().getValue().getChild());
+ }
+
+ @Test
+ public void testObjectActivationSelectsAttribute() throws Throwable {
+ createTraceAndPopulateObjects();
+ TraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObject root = objects.getRootObject();
+ TraceObject processes = root.getAttribute(0, "Processes").getChild();
+ traceManager.activateObject(root);
+ waitForTasks();
+
+ /**
+ * TODO: It's interesting that activating a parent then a child produces a different end
+ * result than activating the child directly.
+ */
+ traceManager.activateObject(processes);
+ waitForTasks();
+
+ assertEquals(TraceObjectKeyPath.of(), modelProvider.getPath());
+ assertEquals(processes, modelProvider.attributesTablePanel.getSelectedItem().getValue());
+ }
+
+ protected TraceThread populateThread0Stack() {
+ TraceObjectManager objects = tb.trace.getObjectManager();
+ TraceObject threadObj0 =
+ objects.getObjectByCanonicalPath(TraceObjectKeyPath.parse("Processes[0].Threads[0]"));
+ TraceThread thread0 = threadObj0.queryInterface(TraceObjectThread.class);
+ createStack(threadObj0);
+ return thread0;
+ }
+
+ @Test
+ public void testFrameActivationSelectsSibling() throws Throwable {
+ createTraceAndPopulateObjects();
+ TraceThread thread0 = populateThread0Stack();
+
+ traceManager.activate(DebuggerCoordinates.NOWHERE.thread(thread0).frame(0));
+ waitForSwing();
+ assertEquals(TraceObjectKeyPath.parse("Processes[0].Threads[0].Stack[0]"),
+ modelProvider.getPath());
+
+ traceManager.activateFrame(1);
+ waitForSwing();
+ assertEquals(TraceObjectKeyPath.parse("Processes[0].Threads[0].Stack[1]"),
+ modelProvider.getPath());
+ }
+
+ @Test
+ public void testFrameActivationSelectsElement() throws Throwable {
+ createTraceAndPopulateObjects();
+ TraceThread thread0 = populateThread0Stack();
+ TraceObjectKeyPath stackPath = TraceObjectKeyPath.parse("Processes[0].Threads[0].Stack");
+
+ traceManager.activateThread(thread0);
+ waitForSwing();
+ modelProvider.setPath(stackPath);
+ waitForTasks();
+
+ // Test 1 then 0, because 0 is default
+ traceManager.activateFrame(1);
+ waitForTasks();
+ assertEquals(stackPath, modelProvider.getPath());
+ assertEquals(stackPath.index(1),
+ modelProvider.elementsTablePanel.getSelectedItem().getValue().getCanonicalPath());
+
+ traceManager.activateFrame(0);
+ waitForTasks();
+ assertEquals(stackPath, modelProvider.getPath());
+ assertEquals(stackPath.index(0),
+ modelProvider.elementsTablePanel.getSelectedItem().getValue().getCanonicalPath());
+ }
+
+ @Test
+ public void testThreadActivationSelectsSibling() throws Throwable {
+ createTraceAndPopulateObjects();
+ TraceThread thread0 =
+ tb.trace.getThreadManager().getLiveThreadByPath(1, "Processes[0].Threads[0]");
+ TraceThread thread1 =
+ tb.trace.getThreadManager().getLiveThreadByPath(1, "Processes[0].Threads[1]");
+
+ traceManager.activateThread(thread0);
+ traceManager.activateSnap(1);
+ waitForSwing();
+ assertEquals(TraceObjectKeyPath.parse("Processes[0].Threads[0]"), modelProvider.getPath());
+
+ traceManager.activateThread(thread1);
+ waitForSwing();
+ assertEquals(TraceObjectKeyPath.parse("Processes[0].Threads[1]"), modelProvider.getPath());
+ }
+
+ @Test
+ public void testThreadActivationSelectsElement() throws Throwable {
+ createTraceAndPopulateObjects();
+ TraceThread thread0 =
+ tb.trace.getThreadManager().getLiveThreadByPath(1, "Processes[0].Threads[0]");
+ TraceThread thread1 =
+ tb.trace.getThreadManager().getLiveThreadByPath(1, "Processes[0].Threads[1]");
+ TraceObjectKeyPath threadsPath = TraceObjectKeyPath.parse("Processes[0].Threads");
+
+ traceManager.activateTrace(tb.trace);
+ traceManager.activateSnap(1);
+ waitForSwing();
+
+ modelProvider.setPath(threadsPath);
+ waitForTasks();
+
+ // Testing 1 then 0, because 0 is default
+ traceManager.activateThread(thread1);
+ waitForSwing();
+ assertEquals(threadsPath, modelProvider.getPath());
+ assertEquals(threadsPath.index(1),
+ modelProvider.elementsTablePanel.getSelectedItem().getValue().getCanonicalPath());
+
+ traceManager.activateThread(thread0);
+ waitForSwing();
+ assertEquals(threadsPath, modelProvider.getPath());
+ assertEquals(threadsPath.index(0),
+ modelProvider.elementsTablePanel.getSelectedItem().getValue().getCanonicalPath());
+ }
}
diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerStaticMappingProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerStaticMappingProviderTest.java
index b9bf7ea828..a94d6c3550 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerStaticMappingProviderTest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerStaticMappingProviderTest.java
@@ -182,7 +182,7 @@ public class DebuggerStaticMappingProviderTest extends AbstractGhidraHeadedDebug
// Select and remove the first 2 via the action
// NOTE: I'm not responsible for making the transaction here. The UI should do it.
mappingsProvider.mappingTable.getSelectionModel().setSelectionInterval(0, 1);
- performAction(mappingsProvider.actionRemove);
+ performEnabledAction(mappingsProvider, mappingsProvider.actionRemove, true);
waitForDomainObject(tb.trace);
// Now, check that only the final one remains
diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderTest.java
index 1bddd5c7a9..ef189443b4 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderTest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/register/DebuggerRegistersProviderTest.java
@@ -291,7 +291,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
}
@Test
- public void testLiveAddValuesThenActivatePopulatesPanel() throws Exception {
+ public void testLiveAddValuesThenActivatePopulatesPanel() throws Throwable {
TraceRecorder recorder = recordAndWaitSync();
traceManager.openTrace(recorder.getTrace());
waitForSwing();
@@ -725,8 +725,8 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
traceManager.activateSnap(1);
waitForSwing();
- assertEquals(1, registersProvider.current.getSnap().longValue());
- assertEquals(0, cloned.current.getSnap().longValue()); // TODO: Action to toggle snap tracking?
+ assertEquals(1, registersProvider.current.getSnap());
+ assertEquals(0, cloned.current.getSnap()); // TODO: Action to toggle snap tracking?
// NB, can't activate "null" trace. Manager ignores it.
traceManager.closeTrace(tb.trace);
diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProviderTest.java
index 326709d880..cf8c933d51 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProviderTest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/watch/DebuggerWatchesProviderTest.java
@@ -566,6 +566,8 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
@Test
public void testEditMemoryTarget() throws Throwable {
WatchRow row = prepareTestEditTarget("*:8 r0");
+ // Wait for the async reads to settle.
+ waitForPass(() -> assertEquals(tb.addr(0x00400000), row.getAddress()));
row.setRawValueString("0x1234");
retryVoid(() -> {
diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerLogicalBreakpointServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerLogicalBreakpointServiceTest.java
index d94396334b..42f67676a0 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerLogicalBreakpointServiceTest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/breakpoint/DebuggerLogicalBreakpointServiceTest.java
@@ -1293,11 +1293,17 @@ public class DebuggerLogicalBreakpointServiceTest extends AbstractGhidraHeadedDe
}
waitForDomainObject(trace);
+ waitOn(mappingService.changesSettled());
+ waitOn(breakpointService.changesSettled());
+
// Sanity
assertLogicalBreakpointForMappedSoftwareBreakpoint(trace);
expectMappingChange(() -> undo(trace));
+ waitOn(mappingService.changesSettled());
+ waitOn(breakpointService.changesSettled());
+
// NB. The bookmark remains
LogicalBreakpoint one = Unique.assertOne(breakpointService.getAllBreakpoints());
assertTrue(one.getTraceBreakpoints().isEmpty());
diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/editing/DebuggerStateEditingServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/editing/DebuggerStateEditingServiceTest.java
index 7ac389202c..4baf378161 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/editing/DebuggerStateEditingServiceTest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/editing/DebuggerStateEditingServiceTest.java
@@ -138,20 +138,20 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
@Test
public void testWriteEmuMemoryAfterStep() throws Throwable {
createAndOpenTrace();
- editingService.setCurrentMode(tb.trace, StateEditingMode.WRITE_EMULATOR);
+ editingService.setCurrentMode(tb.trace, StateEditingMode.WRITE_TRACE);
try (UndoableTransaction tid = tb.startTransaction()) {
// NB. TraceManager should automatically activate the first thread
TraceThread thread = tb.getOrAddThread("Threads[0]", 0);
AsyncPcodeExecutor executor =
- TracePcodeUtils.executorForCoordinates(
- DebuggerCoordinates.all(tb.trace, null, thread, null, TraceSchedule.ZERO, 0,
- null));
+ TracePcodeUtils.executorForCoordinates(DebuggerCoordinates.NOWHERE.thread(thread));
Assembler asm = Assemblers.getAssembler(tb.trace.getFixedProgramView(0));
asm.assemble(tb.addr(0x00400000), "imm r0,#123");
executor.executeSleighLine("pc = 0x00400000");
}
+ traceManager.activateTrace(tb.trace);
+ editingService.setCurrentMode(tb.trace, StateEditingMode.WRITE_EMULATOR);
waitForSwing();
TraceSchedule step1 = TraceSchedule.parse("0:t0-1");
@@ -163,7 +163,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
waitForSwing();
DebuggerCoordinates current = traceManager.getCurrent();
- assertEquals(0, current.getSnap().longValue()); // Chain edits, don't source from scratch
+ assertEquals(0, current.getSnap()); // Chain edits, don't source from scratch
long snap = current.getViewSnap();
assertTrue(DBTraceUtils.isScratch(snap));
@@ -175,21 +175,21 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
@Test
public void testWriteEmuRegisterAfterStep() throws Throwable {
createAndOpenTrace();
- editingService.setCurrentMode(tb.trace, StateEditingMode.WRITE_EMULATOR);
+ editingService.setCurrentMode(tb.trace, StateEditingMode.WRITE_TRACE);
TraceThread thread;
try (UndoableTransaction tid = tb.startTransaction()) {
// NB. TraceManager should automatically activate the first thread
thread = tb.getOrAddThread("Threads[0]", 0);
AsyncPcodeExecutor executor =
- TracePcodeUtils.executorForCoordinates(
- DebuggerCoordinates.all(tb.trace, null, thread, null, TraceSchedule.ZERO, 0,
- null));
+ TracePcodeUtils.executorForCoordinates(DebuggerCoordinates.NOWHERE.thread(thread));
Assembler asm = Assemblers.getAssembler(tb.trace.getFixedProgramView(0));
asm.assemble(tb.addr(0x00400000), "imm r0,#123");
executor.executeSleighLine("pc = 0x00400000");
}
+ traceManager.activateTrace(tb.trace);
+ editingService.setCurrentMode(tb.trace, StateEditingMode.WRITE_EMULATOR);
waitForSwing();
TraceSchedule step1 = TraceSchedule.parse("0:t0-1");
@@ -201,7 +201,7 @@ public class DebuggerStateEditingServiceTest extends AbstractGhidraHeadedDebugge
waitForSwing();
DebuggerCoordinates current = traceManager.getCurrent();
- assertEquals(0, current.getSnap().longValue()); // Chain edits, don't source from scratch
+ assertEquals(0, current.getSnap()); // Chain edits, don't source from scratch
long snap = current.getViewSnap();
assertTrue(DBTraceUtils.isScratch(snap));
diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServiceTest.java
index abf3ff2d30..e5fd7d20f3 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServiceTest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/tracemgr/DebuggerTraceManagerServiceTest.java
@@ -133,12 +133,12 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
waitForSwing();
assertNull(traceManager.getCurrentTrace());
- assertEquals(thread, traceManager.getCurrentThreadFor(tb.trace));
+ assertEquals(thread, traceManager.getCurrentFor(tb.trace).getThread());
traceManager.closeTrace(tb.trace);
waitForSwing();
- assertNull(traceManager.getCurrentThreadFor(tb.trace));
+ assertNull(traceManager.getCurrentFor(tb.trace).getThread());
}
@Test
diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/debug/flatapi/FlatDebuggerAPITest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/debug/flatapi/FlatDebuggerAPITest.java
index 8e9f8bec68..b4ea9a3ab4 100644
--- a/Ghidra/Debug/Debugger/src/test/java/ghidra/debug/flatapi/FlatDebuggerAPITest.java
+++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/debug/flatapi/FlatDebuggerAPITest.java
@@ -159,13 +159,13 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
@Test
public void testGetCurrentDebuggerCoordinates() throws Throwable {
- assertEquals(DebuggerCoordinates.NOWHERE, flat.getCurrentDebuggerCoordinates());
+ assertSame(DebuggerCoordinates.NOWHERE, flat.getCurrentDebuggerCoordinates());
createAndOpenTrace();
traceManager.activateTrace(tb.trace);
- assertEquals(DebuggerCoordinates.all(tb.trace, null, null, tb.trace.getProgramView(),
- TraceSchedule.parse("0"), 0, null), flat.getCurrentDebuggerCoordinates());
+ assertEquals(DebuggerCoordinates.NOWHERE.trace(tb.trace),
+ flat.getCurrentDebuggerCoordinates());
}
@Test
@@ -318,8 +318,8 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
waitForSwing();
assertEquals(thread, traceManager.getCurrentThread());
- flat.activateThread(null); // Ignored by manager
- assertEquals(thread, traceManager.getCurrentThread());
+ flat.activateThread(null);
+ assertNull(traceManager.getCurrentThread());
}
@Test
@@ -820,7 +820,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
TraceRecorder recorder = record(mb.testProcess1);
waitRecorder(recorder);
- mb.testModel.requestFocus(mb.testThread2);
+ waitOn(mb.testModel.requestFocus(mb.testThread2));
waitRecorder(recorder);
assertEquals(mb.testThread2, flat.getTargetFocus(recorder.getTrace()));
@@ -849,7 +849,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
createTestModel();
mb.createTestProcessesAndThreads();
TraceRecorder recorder = record(mb.testProcess1);
- recorder.requestFocus(mb.testThread2);
+ assertTrue(waitOn(recorder.requestFocus(mb.testThread2)));
waitRecorder(recorder);
assertTrue(step.apply(flat));
@@ -899,7 +899,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
createTestModel();
mb.createTestProcessesAndThreads();
TraceRecorder recorder = record(mb.testProcess1);
- recorder.requestFocus(mb.testThread2);
+ assertTrue(waitOn(recorder.requestFocus(mb.testThread2)));
waitRecorder(recorder);
assertTrue(resume.apply(flat));
@@ -933,7 +933,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
@Override
public CompletableFuture interrupt() {
observedThread = this;
- return super.resume();
+ return super.interrupt();
}
};
}
@@ -942,7 +942,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
createTestModel();
mb.createTestProcessesAndThreads();
TraceRecorder recorder = record(mb.testProcess1);
- recorder.requestFocus(mb.testThread2);
+ assertTrue(waitOn(recorder.requestFocus(mb.testThread2)));
waitRecorder(recorder);
assertTrue(interrupt.apply(flat));
@@ -976,7 +976,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
@Override
public CompletableFuture kill() {
observedThread = this;
- return super.resume();
+ return super.kill();
}
};
}
@@ -985,7 +985,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
createTestModel();
mb.createTestProcessesAndThreads();
TraceRecorder recorder = record(mb.testProcess1);
- recorder.requestFocus(mb.testThread2);
+ assertTrue(waitOn(recorder.requestFocus(mb.testThread2)));
waitRecorder(recorder);
assertTrue(kill.apply(flat));
@@ -1026,7 +1026,7 @@ public class FlatDebuggerAPITest extends AbstractGhidraHeadedDebuggerGUITest {
createTestModel();
mb.createTestProcessesAndThreads();
TraceRecorder recorder = record(mb.testProcess1);
- recorder.requestFocus(mb.testThread2);
+ assertTrue(waitOn(recorder.requestFocus(mb.testThread2)));
waitRecorder(recorder);
assertEquals("Response to cmd", executeCapture.apply(flat, "cmd"));
diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/model/TestTargetSession.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/model/TestTargetSession.java
index 9fdded43dd..0e43681f71 100644
--- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/model/TestTargetSession.java
+++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/model/TestTargetSession.java
@@ -68,8 +68,8 @@ public class TestTargetSession extends DefaultTargetModelRoot
@Override
public CompletableFuture requestFocus(TargetObject obj) {
return model.gateFuture(getModel().future(null).thenAccept(__ -> {
- changeAttributes(List.of(), List.of(), Map.of(FOCUS_ATTRIBUTE_NAME, obj //
- ), "Focus requested");
+ changeAttributes(List.of(), List.of(), Map.of(FOCUS_ATTRIBUTE_NAME, obj),
+ "Focus requested");
}));
}
diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceObjectStack.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceObjectStack.java
index a4c981d0aa..d8c2743de6 100644
--- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceObjectStack.java
+++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/stack/DBTraceObjectStack.java
@@ -205,10 +205,8 @@ public class DBTraceObjectStack implements TraceObjectStack, DBTraceObjectInterf
return doGetFrame(level);
}
}
- else {
- try (LockHold hold = object.getTrace().lockRead()) {
- return doGetFrame(level);
- }
+ try (LockHold hold = object.getTrace().lockRead()) {
+ return doGetFrame(level);
}
}
diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/target/DBTraceObjectValue.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/target/DBTraceObjectValue.java
index af0984c8b8..517a882aa5 100644
--- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/target/DBTraceObjectValue.java
+++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/target/DBTraceObjectValue.java
@@ -327,6 +327,9 @@ public class DBTraceObjectValue extends DBAnnotatedObject implements InternalTra
}
protected TraceObjectKeyPath doGetCanonicalPath() {
+ if (triple == null || triple.parent == null) {
+ return TraceObjectKeyPath.of();
+ }
return triple.parent.getCanonicalPath().extend(triple.key);
}