diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengBreakpointsTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengBreakpointsTest.java index 107fe39b2b..1c96abc136 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengBreakpointsTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengBreakpointsTest.java @@ -15,13 +15,14 @@ */ package agent.dbgeng.model; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; import java.util.List; -import ghidra.dbg.target.*; import ghidra.dbg.target.TargetBreakpointSpec.TargetBreakpointKind; import ghidra.dbg.target.TargetBreakpointSpecContainer.TargetBreakpointKindSet; +import ghidra.dbg.target.TargetObject; +import ghidra.dbg.target.TargetStackFrame; import ghidra.dbg.test.*; import ghidra.dbg.util.PathUtils; import ghidra.program.model.address.*; @@ -79,10 +80,4 @@ public abstract class AbstractModelForDbgengBreakpointsTest throw new AssertionError(); } } - - @Override - protected TargetObject findProcessContainer() throws Throwable { - return m.findContainer(TargetProcess.class, PathUtils.parse("Sessions[0]")); - } - } diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengFrameFocusTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengFrameFocusTest.java index 5b213a3163..2f20254a04 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengFrameFocusTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengFrameFocusTest.java @@ -46,7 +46,7 @@ public abstract class AbstractModelForDbgengFrameFocusTest return retry(() -> { Map, TargetStackFrame> frames = - m.findAll(TargetStackFrame.class, seedPath()); + m.findAll(TargetStackFrame.class, seedPath(), true); assertTrue(frames.size() >= 3); return Set.copyOf(frames.values()); }, List.of(AssertionError.class)); diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengInterpreterTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengInterpreterTest.java index 3eaa4b7a9b..feea8bb3a5 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengInterpreterTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengInterpreterTest.java @@ -17,6 +17,7 @@ package agent.dbgeng.model; import java.util.List; +import ghidra.dbg.target.TargetProcess; import ghidra.dbg.test.AbstractDebuggerModelInterpreterTest; import ghidra.dbg.util.PathUtils; @@ -48,6 +49,16 @@ public abstract class AbstractModelForDbgengInterpreterTest return ".attach " + Long.toHexString(dummy.pid); } + @Override + protected String getDetachCommand(TargetProcess process) { + return ".detach"; + } + + @Override + protected String getKillCommand(TargetProcess process) { + return ".kill"; + } + @Override public DebuggerTestSpecimen getAttachSpecimen() { return WindowsSpecimen.NOTEPAD; diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengProcessFocusTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengProcessFocusTest.java index 8f3dabc1da..c1f7befdce 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengProcessFocusTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengProcessFocusTest.java @@ -44,7 +44,7 @@ public abstract class AbstractModelForDbgengProcessFocusTest } return retry(() -> { Map, TargetProcess> found = - m.findAll(TargetProcess.class, PathUtils.parse("Sessions[0]")); + m.findAll(TargetProcess.class, PathUtils.parse("Sessions[0]"), true); assertEquals(count, found.size()); return Set.copyOf(found.values()); }, List.of(AssertionError.class)); diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengRootAttacherTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengRootAttacherTest.java index 3946bb6cd7..040ddd790a 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengRootAttacherTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengRootAttacherTest.java @@ -20,7 +20,7 @@ import static org.junit.Assert.assertTrue; import java.util.List; -import ghidra.dbg.target.*; +import ghidra.dbg.target.TargetEnvironment; import ghidra.dbg.target.TargetMethod.TargetParameterMap; import ghidra.dbg.test.AbstractDebuggerModelAttacherTest; import ghidra.dbg.util.PathUtils; @@ -28,21 +28,11 @@ import ghidra.dbg.util.PathUtils; public abstract class AbstractModelForDbgengRootAttacherTest extends AbstractDebuggerModelAttacherTest { - @Override - protected TargetObject findProcessContainer() throws Throwable { - return m.findContainer(TargetProcess.class, PathUtils.parse("Sessions[0]")); - } - @Override public List getExpectedAttachableContainerPath() { return List.of("Available"); } - @Override - public List getExpectedProcessesContainerPath() { - return PathUtils.parse("Sessions[0].Processes"); - } - @Override public List getExpectedAttacherPath() { return PathUtils.parse(""); diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengRootLauncherTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengRootLauncherTest.java index 7ab270ed91..7695ca7358 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengRootLauncherTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengRootLauncherTest.java @@ -21,7 +21,7 @@ import static org.junit.Assert.assertTrue; import java.util.List; import java.util.Map; -import ghidra.dbg.target.*; +import ghidra.dbg.target.TargetEnvironment; import ghidra.dbg.target.TargetMethod.ParameterDescription; import ghidra.dbg.target.TargetMethod.TargetParameterMap; import ghidra.dbg.test.AbstractDebuggerModelLauncherTest; @@ -30,16 +30,6 @@ import ghidra.dbg.util.PathUtils; public abstract class AbstractModelForDbgengRootLauncherTest extends AbstractDebuggerModelLauncherTest { - @Override - protected TargetObject findProcessContainer() throws Throwable { - return m.findContainer(TargetProcess.class, PathUtils.parse("Sessions[0]")); - } - - @Override - public List getExpectedProcessesContainerPath() { - return PathUtils.parse("Sessions[0].Processes"); - } - @Override public List getExpectedLauncherPath() { return PathUtils.parse(""); diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioCloneExitTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioCloneExitTest.java index 3543a3cf75..c7988ca763 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioCloneExitTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioCloneExitTest.java @@ -15,19 +15,11 @@ */ package agent.dbgeng.model; -import ghidra.dbg.target.TargetObject; -import ghidra.dbg.target.TargetProcess; import ghidra.dbg.test.AbstractDebuggerModelScenarioCloneExitTest; -import ghidra.dbg.util.PathUtils; public abstract class AbstractModelForDbgengScenarioCloneExitTest extends AbstractDebuggerModelScenarioCloneExitTest { - @Override - protected TargetObject findProcessContainer() throws Throwable { - return m.findContainer(TargetProcess.class, PathUtils.parse("Sessions[0]")); - } - @Override protected DebuggerTestSpecimen getSpecimen() { return WindowsSpecimen.CREATE_THREAD_EXIT; diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioForkExitTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioForkExitTest.java index 41d8134739..e4f3ff6c29 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioForkExitTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioForkExitTest.java @@ -18,18 +18,12 @@ package agent.dbgeng.model; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import ghidra.dbg.target.*; +import ghidra.dbg.target.TargetEnvironment; import ghidra.dbg.test.AbstractDebuggerModelScenarioForkExitTest; -import ghidra.dbg.util.PathUtils; public abstract class AbstractModelForDbgengScenarioForkExitTest extends AbstractDebuggerModelScenarioForkExitTest { - @Override - protected TargetObject findProcessContainer() throws Throwable { - return m.findContainer(TargetProcess.class, PathUtils.parse("Sessions[0]")); - } - @Override protected DebuggerTestSpecimen getSpecimen() { return WindowsSpecimen.CREATE_PROCESS; diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioMemoryTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioMemoryTest.java index f7e7ef169d..72533dd256 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioMemoryTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioMemoryTest.java @@ -29,11 +29,6 @@ import ghidra.program.model.address.Address; public abstract class AbstractModelForDbgengScenarioMemoryTest extends AbstractDebuggerModelScenarioMemoryTest { - @Override - protected TargetObject findProcessContainer() throws Throwable { - return m.findContainer(TargetProcess.class, PathUtils.parse("Sessions[0]")); - } - @Override protected WindowsSpecimen getSpecimen() { return WindowsSpecimen.PRINT; diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioStackTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioStackTest.java index 8043110215..902df89660 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioStackTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioStackTest.java @@ -31,11 +31,6 @@ public abstract class AbstractModelForDbgengScenarioStackTest List.of("break_here", "funcC", "funcB", "funcA"); protected NavigableMap symbolsByAddress = new TreeMap<>(); - @Override - protected TargetObject findProcessContainer() throws Throwable { - return m.findContainer(TargetProcess.class, PathUtils.parse("Sessions[0]")); - } - @Override protected WindowsSpecimen getSpecimen() { return WindowsSpecimen.STACK; diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioX64RegistersTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioX64RegistersTest.java index 3da0568e59..7950007d55 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioX64RegistersTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengScenarioX64RegistersTest.java @@ -20,19 +20,12 @@ import static org.junit.Assert.assertEquals; import java.util.Map; import agent.dbgeng.model.impl.DbgModelTargetProcessImpl; -import ghidra.dbg.target.TargetObject; import ghidra.dbg.target.TargetProcess; import ghidra.dbg.test.AbstractDebuggerModelScenarioRegistersTest; -import ghidra.dbg.util.PathUtils; public abstract class AbstractModelForDbgengScenarioX64RegistersTest extends AbstractDebuggerModelScenarioRegistersTest { - @Override - protected TargetObject findProcessContainer() throws Throwable { - return m.findContainer(TargetProcess.class, PathUtils.parse("Sessions[0]")); - } - @Override protected DebuggerTestSpecimen getSpecimen() { return WindowsSpecimen.REGISTERS; diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengSteppableTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengSteppableTest.java index 8d64f780a7..6764c4ef7e 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengSteppableTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengSteppableTest.java @@ -17,19 +17,11 @@ package agent.dbgeng.model; import java.util.List; -import ghidra.dbg.target.TargetObject; -import ghidra.dbg.target.TargetProcess; import ghidra.dbg.test.*; -import ghidra.dbg.util.PathUtils; public abstract class AbstractModelForDbgengSteppableTest extends AbstractDebuggerModelSteppableTest implements ProvidesTargetViaLaunchSpecimen { - @Override - protected TargetObject findProcessContainer() throws Throwable { - return m.findContainer(TargetProcess.class, PathUtils.parse("Sessions[0]")); - } - @Override public AbstractDebuggerModelTest getTest() { return this; diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengThreadFocusTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengThreadFocusTest.java index f4289640da..153b6799cd 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengThreadFocusTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengThreadFocusTest.java @@ -44,7 +44,7 @@ public abstract class AbstractModelForDbgengThreadFocusTest } return retry(() -> { Map, TargetThread> found = - m.findAll(TargetThread.class, PathUtils.parse("Sessions[0]")); + m.findAll(TargetThread.class, PathUtils.parse("Sessions[0]"), true); assertEquals(count, found.size()); return Set.copyOf(found.values()); }, List.of(AssertionError.class)); diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengX64RegistersTest.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengX64RegistersTest.java index 88106957ec..ade035368f 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengX64RegistersTest.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/AbstractModelForDbgengX64RegistersTest.java @@ -18,8 +18,6 @@ package agent.dbgeng.model; import java.util.List; import java.util.Map; -import ghidra.dbg.target.TargetObject; -import ghidra.dbg.target.TargetProcess; import ghidra.dbg.test.*; import ghidra.dbg.util.PathUtils; @@ -37,11 +35,6 @@ public abstract class AbstractModelForDbgengX64RegistersTest return this; } - @Override - protected TargetObject findProcessContainer() throws Throwable { - return m.findContainer(TargetProcess.class, PathUtils.parse("Sessions[0]")); - } - @Override public List getExpectedRegisterBankPath(List threadPath) { return PathUtils.extend(threadPath, PathUtils.parse("Registers")); diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/WindowsSpecimen.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/WindowsSpecimen.java index 789860e850..d992f31b2c 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/WindowsSpecimen.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/test/java/agent/dbgeng/model/WindowsSpecimen.java @@ -100,7 +100,6 @@ public enum WindowsSpecimen implements DebuggerTestSpecimen, DebuggerModelTestUt public String getBinModuleName() { return getShortName(getCommandLine().split("\\s+")[0]); - } @Override @@ -109,7 +108,7 @@ public enum WindowsSpecimen implements DebuggerTestSpecimen, DebuggerModelTestUt // NB. ShellUtils.parseArgs removes the \s. Not good. String expected = getBinModuleName(); Collection modules = - test.m.findAll(TargetModule.class, process.getPath()).values(); + test.m.findAll(TargetModule.class, process.getPath(), true).values(); return modules.stream() .anyMatch(m -> expected.equalsIgnoreCase(getShortName(m.getModuleName()))); } diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/test/java/agent/gdb/model/AbstractModelForGdbAttacherTest.java b/Ghidra/Debug/Debugger-agent-gdb/src/test/java/agent/gdb/model/AbstractModelForGdbAttacherTest.java index 900c05157d..4e03e2123c 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/test/java/agent/gdb/model/AbstractModelForGdbAttacherTest.java +++ b/Ghidra/Debug/Debugger-agent-gdb/src/test/java/agent/gdb/model/AbstractModelForGdbAttacherTest.java @@ -31,11 +31,6 @@ public abstract class AbstractModelForGdbAttacherTest extends AbstractDebuggerMo return List.of("Available"); } - @Override - public List getExpectedProcessesContainerPath() { - return List.of("Inferiors"); - } - @Override public DebuggerTestSpecimen getAttachSpecimen() { return GdbLinuxSpecimen.DD; diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/test/java/agent/gdb/model/AbstractModelForGdbInterpreterTest.java b/Ghidra/Debug/Debugger-agent-gdb/src/test/java/agent/gdb/model/AbstractModelForGdbInterpreterTest.java index addbd57d91..3d2289a630 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/test/java/agent/gdb/model/AbstractModelForGdbInterpreterTest.java +++ b/Ghidra/Debug/Debugger-agent-gdb/src/test/java/agent/gdb/model/AbstractModelForGdbInterpreterTest.java @@ -17,6 +17,7 @@ package agent.gdb.model; import java.util.List; +import ghidra.dbg.target.TargetProcess; import ghidra.dbg.test.AbstractDebuggerModelInterpreterTest; public abstract class AbstractModelForGdbInterpreterTest @@ -41,6 +42,16 @@ public abstract class AbstractModelForGdbInterpreterTest return "attach " + dummy.pid; } + @Override + protected String getDetachCommand(TargetProcess process) { + return "detach"; + } + + @Override + protected String getKillCommand(TargetProcess process) { + return "kill"; + } + @Override public DebuggerTestSpecimen getAttachSpecimen() { return GdbLinuxSpecimen.DD; diff --git a/Ghidra/Debug/Debugger-agent-gdb/src/test/java/agent/gdb/model/AbstractModelForGdbLauncherTest.java b/Ghidra/Debug/Debugger-agent-gdb/src/test/java/agent/gdb/model/AbstractModelForGdbLauncherTest.java index d0fa3705b0..9dae006f11 100644 --- a/Ghidra/Debug/Debugger-agent-gdb/src/test/java/agent/gdb/model/AbstractModelForGdbLauncherTest.java +++ b/Ghidra/Debug/Debugger-agent-gdb/src/test/java/agent/gdb/model/AbstractModelForGdbLauncherTest.java @@ -18,7 +18,6 @@ package agent.gdb.model; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import java.util.List; import java.util.Map; import ghidra.dbg.target.TargetEnvironment; @@ -28,11 +27,6 @@ import ghidra.dbg.test.AbstractDebuggerModelLauncherTest; public abstract class AbstractModelForGdbLauncherTest extends AbstractDebuggerModelLauncherTest { - @Override - public List getExpectedProcessesContainerPath() { - return List.of("Inferiors"); - } - @Override public DebuggerTestSpecimen getLaunchSpecimen() { return GdbLinuxSpecimen.ECHO_HW; diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java index 8551280e29..8140f33431 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/gui/modules/DebuggerModulesProviderTest.java @@ -21,8 +21,7 @@ import java.awt.event.MouseEvent; import java.util.*; import java.util.concurrent.TimeUnit; -import org.junit.Before; -import org.junit.Test; +import org.junit.*; import com.google.common.collect.Range; @@ -489,6 +488,7 @@ public class DebuggerModulesProviderTest extends AbstractGhidraHeadedDebuggerGUI } @Test + @Ignore("This action is hidden until supported") public void testActionCaptureTypes() throws Exception { assertFalse(modulesProvider.actionCaptureTypes.isEnabled()); createTestModel(); diff --git a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AbstractTargetObject.java b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AbstractTargetObject.java index 5fad3dad96..949827a20d 100644 --- a/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AbstractTargetObject.java +++ b/Ghidra/Debug/Framework-Debugging/src/main/java/ghidra/dbg/agent/AbstractTargetObject.java @@ -26,6 +26,7 @@ import ghidra.dbg.target.schema.EnumerableTargetObjectSchema; import ghidra.dbg.target.schema.TargetObjectSchema; import ghidra.dbg.util.PathUtils; import ghidra.lifecycle.Internal; +import ghidra.util.Msg; import ghidra.util.datastruct.ListenerSet; /** @@ -245,8 +246,13 @@ public abstract class AbstractTargetObject

implements Sp valid = false; model.objectInvalidated(getProxy()); listeners.fire.invalidated(getProxy(), branch, reason); - listeners.clear(); - listeners.clearChained(); + CompletableFuture.runAsync(() -> { + listeners.clear(); + listeners.clearChained(); + }, model.clientExecutor).exceptionally(ex -> { + Msg.error(this, "Error emptying invalidated object's listener set: ", ex); + return null; + }); } protected void doInvalidateElements(Map elems, String reason) { diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelAttacherTest.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelAttacherTest.java index 53b55a9cb6..50a97c74b8 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelAttacherTest.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelAttacherTest.java @@ -16,7 +16,8 @@ package ghidra.dbg.test; import static org.junit.Assert.*; -import static org.junit.Assume.*; +import static org.junit.Assume.assumeNotNull; +import static org.junit.Assume.assumeTrue; import java.lang.invoke.MethodHandles; import java.util.Collection; @@ -33,7 +34,6 @@ import ghidra.dbg.error.DebuggerIllegalArgumentException; import ghidra.dbg.target.*; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.dbg.target.TargetMethod.TargetParameterMap; -import ghidra.dbg.testutil.ElementTrackingListener; import ghidra.program.model.address.AddressFactory; public abstract class AbstractDebuggerModelAttacherTest extends AbstractDebuggerModelTest @@ -47,10 +47,6 @@ public abstract class AbstractDebuggerModelAttacherTest extends AbstractDebugger return null; } - public List getExpectedProcessesContainerPath() { - return null; - } - public abstract TargetParameterMap getExpectedAttachParameters(); public abstract void assertEnvironment(TargetEnvironment environment); @@ -65,16 +61,6 @@ public abstract class AbstractDebuggerModelAttacherTest extends AbstractDebugger assertEquals(expectedAttacherPath, attacher.getPath()); } - @Test - public void testProcessContainerIsWhereExpected() throws Throwable { - List expectedProcessContainerPath = getExpectedProcessesContainerPath(); - assumeNotNull(expectedProcessContainerPath); - m.build(); - - TargetObject container = findProcessContainer(); - assertEquals(expectedProcessContainerPath, container.getPath()); - } - @Test public void testAttachableContainerIsWhereExpected() throws Throwable { List expectedAttachableContainerPath = getExpectedAttachableContainerPath(); @@ -195,12 +181,12 @@ public abstract class AbstractDebuggerModelAttacherTest extends AbstractDebugger runTestAttachByObjBogusThrowsException(attacher); } - protected void runTestAttachByPidThenDetach(TargetAttacher attacher, TargetObject container) + protected void runTestAttachByPidThenDetach(TargetAttacher attacher) throws Throwable { DebuggerTestSpecimen specimen = getAttachSpecimen(); - assertNull(getProcessRunning(container, specimen, this)); + assertNull(getProcessRunning(specimen, this)); runTestAttachByPid(attacher); - runTestDetach(container, specimen); + runTestDetach(specimen); assertTrue(dummy.process.isAlive()); } @@ -212,16 +198,15 @@ public abstract class AbstractDebuggerModelAttacherTest extends AbstractDebugger dummy = specimen.runDummy(); TargetAttacher attacher = findAttacher(); - TargetObject container = findProcessContainer(); - runTestAttachByPidThenDetach(attacher, container); + runTestAttachByPidThenDetach(attacher); } - protected void runTestAttachByPidThenKill(TargetAttacher attacher, TargetObject container) + protected void runTestAttachByPidThenKill(TargetAttacher attacher) throws Throwable { DebuggerTestSpecimen specimen = getAttachSpecimen(); - assertNull(getProcessRunning(container, specimen, this)); + assertNull(getProcessRunning(specimen, this)); runTestAttachByPid(attacher); - runTestKill(container, specimen); + runTestKill(specimen); retryVoid(() -> assertFalse(dummy.process.isAlive()), List.of(AssertionError.class)); } @@ -233,16 +218,14 @@ public abstract class AbstractDebuggerModelAttacherTest extends AbstractDebugger dummy = specimen.runDummy(); TargetAttacher attacher = findAttacher(); - TargetObject container = findProcessContainer(); - runTestAttachByPidThenKill(attacher, container); + runTestAttachByPidThenKill(attacher); } - protected void runTestAttachByPidThenResumeInterrupt(TargetAttacher attacher, - TargetObject container) throws Throwable { + protected void runTestAttachByPidThenResumeInterrupt(TargetAttacher attacher) throws Throwable { DebuggerTestSpecimen specimen = getAttachSpecimen(); - assertNull(getProcessRunning(container, specimen, this)); + assertNull(getProcessRunning(specimen, this)); runTestAttachByPid(attacher); - runTestResumeInterruptMany(container, specimen, 3); + runTestResumeInterruptMany(specimen, 3); assertTrue(dummy.process.isAlive()); } @@ -254,16 +237,14 @@ public abstract class AbstractDebuggerModelAttacherTest extends AbstractDebugger dummy = specimen.runDummy(); TargetAttacher attacher = findAttacher(); - TargetObject container = findProcessContainer(); - runTestAttachByPidThenResumeInterrupt(attacher, container); + runTestAttachByPidThenResumeInterrupt(attacher); } - protected void runTestAttachShowsInProcessContainer(TargetAttacher attacher, - TargetObject container) throws Throwable { + protected void runTestAttachShowsInProcessContainer(TargetAttacher attacher) throws Throwable { DebuggerTestSpecimen specimen = getAttachSpecimen(); - assertNull(getProcessRunning(container, specimen, this)); + assertNull(getProcessRunning(specimen, this)); runTestAttachByPid(attacher); - retryForProcessRunning(container, specimen, this); + retryForProcessRunning(specimen, this); } @Test @@ -274,36 +255,6 @@ public abstract class AbstractDebuggerModelAttacherTest extends AbstractDebugger dummy = specimen.runDummy(); TargetAttacher attacher = findAttacher(); - TargetObject container = findProcessContainer(); - runTestAttachShowsInProcessContainer(attacher, container); - } - - protected void runTestAttachShowsInProcessContainerViaListener(TargetAttacher attacher, - TargetObject container) throws Throwable { - DebuggerTestSpecimen specimen = getAttachSpecimen(); - ElementTrackingListener procListener = - new ElementTrackingListener<>(TargetProcess.class); - container.addListener(procListener); - // NB. Have to express interest, otherwise model is not obligated to invoke listener - Collection procsBefore = fetchProcesses(container); - procListener.putAll(container.getCachedElements()); - assertNull(getProcessRunning(procsBefore, specimen, this)); - runTestAttachByPid(attacher); - retryVoid(() -> { - // Cannot fetch elements. rely only on listener. - assertNotNull(getProcessRunning(procListener.elements.values(), specimen, this)); - }, List.of(AssertionError.class)); - } - - @Test - public void testAttachShowsInProcessContainerViaListener() throws Throwable { - DebuggerTestSpecimen specimen = getAttachSpecimen(); - assumeTrue(m.hasProcessContainer()); - m.build(); - dummy = specimen.runDummy(); - - TargetAttacher attacher = findAttacher(); - TargetObject container = findProcessContainer(); - runTestAttachShowsInProcessContainerViaListener(attacher, container); + runTestAttachShowsInProcessContainer(attacher); } } diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelBreakpointsTest.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelBreakpointsTest.java index f042174e1e..6a8ce0ca62 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelBreakpointsTest.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelBreakpointsTest.java @@ -16,7 +16,8 @@ package ghidra.dbg.test; import static org.junit.Assert.*; -import static org.junit.Assume.*; +import static org.junit.Assume.assumeNotNull; +import static org.junit.Assume.assumeTrue; import java.util.*; import java.util.Map.Entry; @@ -38,18 +39,16 @@ import ghidra.util.Msg; * Tests the functionality of breakpoints * *

- * Note that this test does not check for nuances regarding specification vs. - * location, as it is meant to generalize across models for interests of the UI - * only. As such, we only test that we can set breakpoints at given addresses - * and that a location manifests there, regardless of the intervening - * mechanisms. We also test some basic operations on the breakpoint (location) - * itself. Models which have separate specifications from locations, or for - * which you want to test non-address specifications will need to add their own - * tests, tailored to the semantics of that model's breakpoint specifications. + * Note that this test does not check for nuances regarding specification vs. location, as it is + * meant to generalize across models for interests of the UI only. As such, we only test that we can + * set breakpoints at given addresses and that a location manifests there, regardless of the + * intervening mechanisms. We also test some basic operations on the breakpoint (location) itself. + * Models which have separate specifications from locations, or for which you want to test + * non-address specifications will need to add their own tests, tailored to the semantics of that + * model's breakpoint specifications. * *

- * TODO: Enable, disable (if supported), delete (if supported), manipulation via - * CLI is synced + * TODO: Enable, disable (if supported), delete (if supported), manipulation via CLI is synced */ public abstract class AbstractDebuggerModelBreakpointsTest extends AbstractDebuggerModelTest implements RequiresTarget { @@ -225,7 +224,7 @@ public abstract class AbstractDebuggerModelBreakpointsTest extends AbstractDebug waitOn(container.placeBreakpoint(range, Set.of(kind))); retryVoid(() -> { Collection found = - m.findAll(TargetBreakpointLocation.class, target.getPath()).values(); + m.findAll(TargetBreakpointLocation.class, target.getPath(), true).values(); assertAtLeastOneLocCovers(found, range, kind); }, List.of(AssertionError.class)); } @@ -261,7 +260,7 @@ public abstract class AbstractDebuggerModelBreakpointsTest extends AbstractDebug waitOn(container.placeBreakpoint(range, Set.of(kind))); locs.add(retry(() -> { Collection found = - m.findAll(TargetBreakpointLocation.class, target.getPath()).values(); + m.findAll(TargetBreakpointLocation.class, target.getPath(), true).values(); return assertAtLeastOneLocCovers(found, range, kind); }, List.of(AssertionError.class))); } diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelFocusTest.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelFocusTest.java index 7d7b3d1b63..59d16128cd 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelFocusTest.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelFocusTest.java @@ -27,6 +27,10 @@ import ghidra.dbg.target.TargetFocusScope; import ghidra.dbg.target.TargetObject; import ghidra.dbg.util.PathUtils; +/** + * TODO: Since activation and focus are separate concepts, we need to fix the terminology here and + * ensure we're testing the right things. + */ public abstract class AbstractDebuggerModelFocusTest extends AbstractDebuggerModelTest { /** diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelInterpreterTest.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelInterpreterTest.java index 6513117dbd..86698ab9bf 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelInterpreterTest.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelInterpreterTest.java @@ -15,9 +15,10 @@ */ package ghidra.dbg.test; -import static ghidra.lifecycle.Unfinished.*; +import static ghidra.lifecycle.Unfinished.TODO; import static org.junit.Assert.*; -import static org.junit.Assume.*; +import static org.junit.Assume.assumeNotNull; +import static org.junit.Assume.assumeTrue; import java.util.List; import java.util.stream.Collectors; @@ -27,23 +28,39 @@ import org.junit.Ignore; import org.junit.Test; import ghidra.async.AsyncReference; +import ghidra.dbg.DebugModelConventions; import ghidra.dbg.DebuggerModelListener; import ghidra.dbg.error.DebuggerModelTerminatingException; +import ghidra.dbg.target.*; import ghidra.dbg.target.TargetConsole.Channel; -import ghidra.dbg.target.TargetInterpreter; -import ghidra.dbg.target.TargetObject; import ghidra.dbg.testutil.CatchOffThread; import ghidra.util.Msg; public abstract class AbstractDebuggerModelInterpreterTest extends AbstractDebuggerModelTest implements RequiresAttachSpecimen, RequiresLaunchSpecimen { + /** + * Get the path of the expected result of {@link #findInterpreter()} for this test + * + * @return the expected path + */ public List getExpectedInterpreterPath() { return null; } + /** + * Get the CLI command to echo a string back + * + * @param msg the message to echo + * @return the command + */ protected abstract String getEchoCommand(String msg); + /** + * If applicable, get the CLI command to terminate the session / model + * + * @return the command + */ protected abstract String getQuitCommand(); /** @@ -53,6 +70,30 @@ public abstract class AbstractDebuggerModelInterpreterTest extends AbstractDebug */ protected abstract String getAttachCommand(); + /** + * Get the CLI command to detach from the given process + * + *

+ * Note that the given process should already be the current/active process of the interpreter, + * so the parameter may not be needed. + * + * @param process the process to detach from, which should already be active + * @return the command + */ + protected abstract String getDetachCommand(TargetProcess process); + + /** + * Get the CLI command to kill the given process + * + *

+ * Note that the given process should already be the current/active process of the interpreter, + * so the parameter may not be needed. + * + * @param process the process to kill, which should already be active + * @return the command + */ + protected abstract String getKillCommand(TargetProcess process); + @Test public void testInterpreterIsWhereExpected() throws Throwable { List expectedInterpreterPath = getExpectedInterpreterPath(); @@ -126,6 +167,11 @@ public abstract class AbstractDebuggerModelInterpreterTest extends AbstractDebug runTestExecuteCapture(interpreter, cmd); } + /** + * Test that the user quitting via the CLI properly terminates the model + * + * @throws Throwable expected since the model will terminate + */ @Test(expected = DebuggerModelTerminatingException.class) public void testExecuteQuit() throws Throwable { String cmd = getQuitCommand(); @@ -151,14 +197,22 @@ public abstract class AbstractDebuggerModelInterpreterTest extends AbstractDebug // TODO: Delete (spec vs. loc?) } - protected void runTestLaunchViaInterpreterShowsInProcessContainer(TargetInterpreter interpreter, - TargetObject container) throws Throwable { + protected TargetProcess runTestLaunchViaInterpreterShowsInProcessContainer( + TargetInterpreter interpreter) throws Throwable { DebuggerTestSpecimen specimen = getLaunchSpecimen(); - assertNull(getProcessRunning(container, specimen, this)); + assertNull(getProcessRunning(specimen, this)); for (String line : specimen.getLaunchScript()) { waitOn(interpreter.execute(line)); } - retryForProcessRunning(container, specimen, this); + return retryForProcessRunning(specimen, this); + } + + protected void runTestKillViaInterpreter(TargetProcess process, TargetInterpreter interpreter) + throws Throwable { + waitOn(interpreter.execute(getKillCommand(process))); + retryVoid(() -> { + assertFalse(DebugModelConventions.isProcessAlive(process)); + }, List.of(AssertionError.class)); } @Test @@ -167,18 +221,26 @@ public abstract class AbstractDebuggerModelInterpreterTest extends AbstractDebug m.build(); TargetInterpreter interpreter = findInterpreter(); - TargetObject container = findProcessContainer(); - assertNotNull("No process container", container); - runTestLaunchViaInterpreterShowsInProcessContainer(interpreter, container); + TargetProcess process = runTestLaunchViaInterpreterShowsInProcessContainer(interpreter); + + runTestKillViaInterpreter(process, interpreter); } - protected void runTestAttachViaInterpreterShowsInProcessContainer(TargetInterpreter interpreter, - TargetObject container) throws Throwable { + protected TargetProcess runTestAttachViaInterpreterShowsInProcessContainer( + TargetInterpreter interpreter) throws Throwable { DebuggerTestSpecimen specimen = getAttachSpecimen(); - assertNull(getProcessRunning(container, specimen, this)); + assertNull(getProcessRunning(specimen, this)); String cmd = getAttachCommand(); waitOn(interpreter.execute(cmd)); - retryForProcessRunning(container, specimen, this); + return retryForProcessRunning(specimen, this); + } + + protected void runTestDetachViaInterpreter(TargetProcess process, TargetInterpreter interpreter) + throws Throwable { + waitOn(interpreter.execute(getDetachCommand(process))); + retryVoid(() -> { + assertFalse(DebugModelConventions.isProcessAlive(process)); + }, List.of(AssertionError.class)); } @Test @@ -189,8 +251,8 @@ public abstract class AbstractDebuggerModelInterpreterTest extends AbstractDebug dummy = specimen.runDummy(); TargetInterpreter interpreter = findInterpreter(); - TargetObject container = findProcessContainer(); - assertNotNull("No process container", container); - runTestAttachViaInterpreterShowsInProcessContainer(interpreter, container); + TargetProcess process = runTestAttachViaInterpreterShowsInProcessContainer(interpreter); + + runTestDetachViaInterpreter(process, interpreter); } } diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelLauncherTest.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelLauncherTest.java index 2665d96790..102f96a140 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelLauncherTest.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelLauncherTest.java @@ -15,12 +15,12 @@ */ package ghidra.dbg.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assume.assumeNotNull; import static org.junit.Assume.assumeTrue; import java.lang.invoke.MethodHandles; -import java.util.Collection; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -31,7 +31,6 @@ import ghidra.dbg.DebugModelConventions; import ghidra.dbg.target.*; import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.dbg.target.TargetMethod.TargetParameterMap; -import ghidra.dbg.testutil.ElementTrackingListener; public abstract class AbstractDebuggerModelLauncherTest extends AbstractDebuggerModelTest implements RequiresLaunchSpecimen { @@ -40,10 +39,6 @@ public abstract class AbstractDebuggerModelLauncherTest extends AbstractDebugger return null; } - public List getExpectedProcessesContainerPath() { - return null; - } - public abstract TargetParameterMap getExpectedLauncherParameters(); public abstract void assertEnvironment(TargetEnvironment environment); @@ -58,16 +53,6 @@ public abstract class AbstractDebuggerModelLauncherTest extends AbstractDebugger assertEquals(expectedLauncherPath, launcher.getPath()); } - @Test - public void testProcessContainerIsWhereExpected() throws Throwable { - List expectedProcessContainerPath = getExpectedProcessesContainerPath(); - assumeNotNull(expectedProcessContainerPath); - m.build(); - - TargetObject container = findProcessContainer(); - assertEquals(expectedProcessContainerPath, container.getPath()); - } - protected void runTestLaunchParameters(TargetLauncher launcher, TargetParameterMap expectedParameters) throws Throwable { waitAcc(launcher); @@ -123,12 +108,11 @@ public abstract class AbstractDebuggerModelLauncherTest extends AbstractDebugger waitOn(listener.observedCreated); } - protected void runTestLaunchThenDetach(TargetLauncher launcher, - TargetObject container) throws Throwable { + protected void runTestLaunchThenDetach(TargetLauncher launcher) throws Throwable { DebuggerTestSpecimen specimen = getLaunchSpecimen(); - assertNull(getProcessRunning(container, specimen, this)); + assertNull(getProcessRunning(specimen, this)); runTestLaunch(launcher); - runTestDetach(container, specimen); + runTestDetach(specimen); } @Test @@ -137,16 +121,14 @@ public abstract class AbstractDebuggerModelLauncherTest extends AbstractDebugger m.build(); TargetLauncher launcher = findLauncher(); - TargetObject container = findProcessContainer(); - runTestLaunchThenDetach(launcher, container); + runTestLaunchThenDetach(launcher); } - protected void runTestLaunchThenKill(TargetLauncher launcher, - TargetObject container) throws Throwable { + protected void runTestLaunchThenKill(TargetLauncher launcher) throws Throwable { DebuggerTestSpecimen specimen = getLaunchSpecimen(); - assertNull(getProcessRunning(container, specimen, this)); + assertNull(getProcessRunning(specimen, this)); runTestLaunch(launcher); - runTestKill(container, specimen); + runTestKill(specimen); } @Test @@ -155,16 +137,14 @@ public abstract class AbstractDebuggerModelLauncherTest extends AbstractDebugger m.build(); TargetLauncher launcher = findLauncher(); - TargetObject container = findProcessContainer(); - runTestLaunchThenKill(launcher, container); + runTestLaunchThenKill(launcher); } - protected void runTestLaunchThenResume(TargetLauncher launcher, - TargetObject container) throws Throwable { + protected void runTestLaunchThenResume(TargetLauncher launcher) throws Throwable { DebuggerTestSpecimen specimen = getLaunchSpecimen(); - assertNull(getProcessRunning(container, specimen, this)); + assertNull(getProcessRunning(specimen, this)); runTestLaunch(launcher); - runTestResumeTerminates(container, specimen); + runTestResumeTerminates(specimen); } @Test @@ -173,16 +153,14 @@ public abstract class AbstractDebuggerModelLauncherTest extends AbstractDebugger m.build(); TargetLauncher launcher = findLauncher(); - TargetObject container = findProcessContainer(); - runTestLaunchThenResume(launcher, container); + runTestLaunchThenResume(launcher); } - protected void runTestLaunchShowsInProcessContainer(TargetLauncher launcher, - TargetObject container) throws Throwable { + protected void runTestLaunchShowsInProcessContainer(TargetLauncher launcher) throws Throwable { DebuggerTestSpecimen specimen = getLaunchSpecimen(); - assertNull(getProcessRunning(container, specimen, this)); + assertNull(getProcessRunning(specimen, this)); runTestLaunch(launcher); - retryForProcessRunning(container, specimen, this); + retryForProcessRunning(specimen, this); } @Test @@ -191,34 +169,6 @@ public abstract class AbstractDebuggerModelLauncherTest extends AbstractDebugger m.build(); TargetLauncher launcher = findLauncher(); - TargetObject container = findProcessContainer(); - runTestLaunchShowsInProcessContainer(launcher, container); - } - - protected void runTestLaunchShowsInProcessContainerViaListener( - TargetLauncher launcher, TargetObject container) throws Throwable { - DebuggerTestSpecimen specimen = getLaunchSpecimen(); - ElementTrackingListener procListener = - new ElementTrackingListener<>(TargetProcess.class); - container.addListener(procListener); - // NB. Have to express interest, otherwise model is not obligated to invoke listener - Collection procsBefore = fetchProcesses(container); - procListener.putAll(container.getCachedElements()); - assertNull(getProcessRunning(procsBefore, specimen, this)); - runTestLaunch(launcher); - retryVoid(() -> { - // Cannot fetch elements. rely only on listener. - assertNotNull(getProcessRunning(procListener.elements.values(), specimen, this)); - }, List.of(AssertionError.class)); - } - - @Test - public void testLaunchShowsInProcessContainerViaListener() throws Throwable { - assumeTrue(m.hasProcessContainer()); - m.build(); - - TargetLauncher launcher = findLauncher(); - TargetObject container = findProcessContainer(); - runTestLaunchShowsInProcessContainerViaListener(launcher, container); + runTestLaunchShowsInProcessContainer(launcher); } } diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioCloneExitTest.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioCloneExitTest.java index 663598f1c5..03ca83ccb5 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioCloneExitTest.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioCloneExitTest.java @@ -15,7 +15,8 @@ */ package ghidra.dbg.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.lang.invoke.MethodHandles; import java.util.*; @@ -131,14 +132,12 @@ public abstract class AbstractDebuggerModelScenarioCloneExitTest extends Abstrac Msg.debug(this, "Launching " + specimen); waitOn(launcher.launch(specimen.getLauncherArgs())); Msg.debug(this, " Done launching"); - TargetObject processContainer = findProcessContainer(); - assertNotNull("No process container", processContainer); - TargetProcess process = retryForProcessRunning(processContainer, specimen, this); + TargetProcess process = retryForProcessRunning(specimen, this); postLaunch(process); - TargetBreakpointSpecContainer breakpointContainer = + TargetBreakpointSpecContainer bpContainer = findBreakpointSpecContainer(process.getPath()); Msg.debug(this, "Placing breakpoint"); - waitOn(breakpointContainer.placeBreakpoint(getBreakpointExpression(), + waitOn(bpContainer.placeBreakpoint(getBreakpointExpression(), Set.of(TargetBreakpointKind.SW_EXECUTE))); assertTrue(DebugModelConventions.isProcessAlive(process)); diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioForkExitTest.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioForkExitTest.java index 340edcf20b..8ea92e69d9 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioForkExitTest.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioForkExitTest.java @@ -182,8 +182,6 @@ public abstract class AbstractDebuggerModelScenarioForkExitTest extends Abstract Msg.debug(this, "Launching " + specimen); waitOn(launcher.launch(specimen.getLauncherArgs())); Msg.debug(this, " Done launching"); - TargetObject processContainer = findProcessContainer(); - assertNotNull("No process container", processContainer); TargetProcess parentProcess = waitOn(stateMonitor.observedParent); Msg.debug(this, "Parent is " + parentProcess.getJoinedPath(".")); postLaunch(parentProcess); @@ -201,7 +199,7 @@ public abstract class AbstractDebuggerModelScenarioForkExitTest extends Abstract Msg.debug(this, " Done " + i); waitAcc(access(parentProcess)); try { - childProcess = retryForOtherProcessRunning(processContainer, specimen, this, + childProcess = retryForOtherProcessRunning(specimen, this, p -> p != parentProcess, WAIT_FOR_CHILD_MS); } catch (AssertionError e) { diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioMemoryTest.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioMemoryTest.java index 4199ab289c..1797b9b4ef 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioMemoryTest.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioMemoryTest.java @@ -141,8 +141,7 @@ public abstract class AbstractDebuggerModelScenarioMemoryTest extends AbstractDe Msg.debug(this, "Launching " + specimen); waitOn(launcher.launch(specimen.getLauncherArgs())); Msg.debug(this, " Done launching"); - TargetObject processContainer = findProcessContainer(); - TargetProcess process = retryForProcessRunning(processContainer, specimen, this); + TargetProcess process = retryForProcessRunning(specimen, this); postLaunch(process); Address address = Objects.requireNonNull(getAddressToWrite(process)); diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioRegistersTest.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioRegistersTest.java index 83e158a857..58b7756839 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioRegistersTest.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioRegistersTest.java @@ -15,7 +15,6 @@ */ package ghidra.dbg.test; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.lang.invoke.MethodHandles; @@ -138,9 +137,7 @@ public abstract class AbstractDebuggerModelScenarioRegistersTest extends Abstrac Msg.debug(this, "Launching " + specimen); waitOn(launcher.launch(specimen.getLauncherArgs())); Msg.debug(this, " Done launching"); - TargetObject processContainer = findProcessContainer(); - assertNotNull(processContainer); - TargetProcess process = retryForProcessRunning(processContainer, specimen, this); + TargetProcess process = retryForProcessRunning(specimen, this); postLaunch(process); TargetBreakpointSpecContainer breakpointContainer = diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioStackTest.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioStackTest.java index e115213742..c6fc99288b 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioStackTest.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelScenarioStackTest.java @@ -122,8 +122,7 @@ public abstract class AbstractDebuggerModelScenarioStackTest extends AbstractDeb TargetLauncher launcher = findLauncher(); waitOn(launcher.launch(specimen.getLauncherArgs())); Msg.debug(this, " Done launching"); - TargetObject processContainer = findProcessContainer(); - TargetProcess process = retryForProcessRunning(processContainer, specimen, this); + TargetProcess process = retryForProcessRunning(specimen, this); postLaunch(process); TargetBreakpointSpecContainer breakpointContainer = @@ -157,7 +156,7 @@ public abstract class AbstractDebuggerModelScenarioStackTest extends AbstractDeb // Sort by path should present them innermost to outermost List frames = retry(() -> { List result = - List.copyOf(m.findAll(TargetStackFrame.class, stack.getPath()).values()); + List.copyOf(m.findAll(TargetStackFrame.class, stack.getPath(), true).values()); assertTrue("Fewer than 4 frames", result.size() > 4); return result; }, List.of(AssertionError.class)); diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelTest.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelTest.java index 5e49741721..c0a1dd50ee 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelTest.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractDebuggerModelTest.java @@ -85,19 +85,6 @@ public abstract class AbstractDebuggerModelTest extends AbstractGhidraHeadlessIn return m.find(TargetLauncher.class, seedPath()); } - /** - * Get the process container under test - * - *

- * This can be overridden to force a different object under the test. - * - * @return the process container - * @throws Throwable if anything goes wrong - */ - protected TargetObject findProcessContainer() throws Throwable { - return m.findContainer(TargetProcess.class, seedPath()); - } - /** * Get the breakpoint container of a target under test * @@ -285,9 +272,9 @@ public abstract class AbstractDebuggerModelTest extends AbstractGhidraHeadlessIn return waitOn(listener.trapped); } - protected void runTestDetach(TargetObject container, DebuggerTestSpecimen specimen) + protected void runTestDetach(DebuggerTestSpecimen specimen) throws Throwable { - TargetProcess process = retryForProcessRunning(container, specimen, this); + TargetProcess process = retryForProcessRunning(specimen, this); TargetDetachable detachable = m.suitable(TargetDetachable.class, process.getPath()); waitAcc(detachable); waitOn(detachable.detach()); @@ -295,9 +282,9 @@ public abstract class AbstractDebuggerModelTest extends AbstractGhidraHeadlessIn List.of(AssertionError.class)); } - protected void runTestKill(TargetObject container, DebuggerTestSpecimen specimen) + protected void runTestKill(DebuggerTestSpecimen specimen) throws Throwable { - TargetProcess process = retryForProcessRunning(container, specimen, this); + TargetProcess process = retryForProcessRunning(specimen, this); TargetKillable killable = m.suitable(TargetKillable.class, process.getPath()); waitAcc(killable); waitOn(killable.kill()); @@ -305,9 +292,8 @@ public abstract class AbstractDebuggerModelTest extends AbstractGhidraHeadlessIn List.of(AssertionError.class)); } - protected void runTestResumeTerminates(TargetObject container, DebuggerTestSpecimen specimen) - throws Throwable { - TargetProcess process = retryForProcessRunning(container, specimen, this); + protected void runTestResumeTerminates(DebuggerTestSpecimen specimen) throws Throwable { + TargetProcess process = retryForProcessRunning(specimen, this); TargetResumable resumable = m.suitable(TargetResumable.class, process.getPath()); AsyncState state = new AsyncState(m.suitable(TargetExecutionStateful.class, process.getPath())); @@ -318,9 +304,9 @@ public abstract class AbstractDebuggerModelTest extends AbstractGhidraHeadlessIn List.of(AssertionError.class)); } - protected void runTestResumeInterruptMany(TargetObject container, DebuggerTestSpecimen specimen, + protected void runTestResumeInterruptMany(DebuggerTestSpecimen specimen, int repetitions) throws Throwable { - TargetProcess process = retryForProcessRunning(container, specimen, this); + TargetProcess process = retryForProcessRunning(specimen, this); TargetResumable resumable = m.suitable(TargetResumable.class, process.getPath()); TargetInterruptible interruptible = m.suitable(TargetInterruptible.class, process.getPath()); @@ -342,6 +328,6 @@ public abstract class AbstractDebuggerModelTest extends AbstractGhidraHeadlessIn }, List.of(AssertionError.class)); } } - waitOn(container.getModel().ping("Are you still there?")); + waitOn(m.getModel().ping("Are you still there?")); } } diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractModelHost.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractModelHost.java index d6aeadff1c..c5ede2b091 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractModelHost.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/AbstractModelHost.java @@ -206,16 +206,20 @@ public abstract class AbstractModelHost implements ModelHost, DebuggerModelTestU @Override public NavigableMap, T> findAll(Class cls, - List seedPath) throws Throwable { + List seedPath, boolean atLeastOne) throws Throwable { PathMatcher matcher = model.getRootSchema().getSuccessorSchema(seedPath).searchFor(cls, seedPath, false); if (matcher.isEmpty()) { return new TreeMap<>(); } + + NavigableMap, ?> found = atLeastOne + ? waitOn(waiter.waitAtLeastOne(matcher)) + : matcher.getCachedValues(model.getModelRoot()); // NB. Outside of testing, an "unsafe" cast of the map should be fine. // During testing, we should expend the energy to verify the heap. NavigableMap, T> result = new TreeMap<>(PathComparator.KEYED); - for (Entry, ?> ent : waitOn(waiter.waitAtLeastOne(matcher)).entrySet()) { + for (Entry, ?> ent : found.entrySet()) { result.put(ent.getKey(), cls.cast(ent.getValue())); } return result; diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/ProvidesTargetViaAttachSpecimen.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/ProvidesTargetViaAttachSpecimen.java index 3399e3b740..3dc2b34a7c 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/ProvidesTargetViaAttachSpecimen.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/ProvidesTargetViaAttachSpecimen.java @@ -29,12 +29,11 @@ public interface ProvidesTargetViaAttachSpecimen extends RequiresTarget, Require @Override default TargetObject obtainTarget() throws Throwable { TargetAttacher attacher = getTest().findAttacher(); - TargetObject container = getTest().findProcessContainer(); DebuggerTestSpecimen specimen = getAttachSpecimen(); waitAcc(attacher); DummyProc dummy = specimen.runDummy(); setDummy(dummy); attacher.attach(dummy.pid); - return retryForProcessRunning(container, specimen, getTest()); + return retryForProcessRunning(specimen, getTest()); } } diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/ProvidesTargetViaLaunchSpecimen.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/ProvidesTargetViaLaunchSpecimen.java index 3dcdde7ef3..68f76fee3b 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/ProvidesTargetViaLaunchSpecimen.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/test/ProvidesTargetViaLaunchSpecimen.java @@ -15,7 +15,7 @@ */ package ghidra.dbg.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; import ghidra.dbg.target.TargetLauncher; import ghidra.dbg.target.TargetObject; @@ -34,11 +34,9 @@ public interface ProvidesTargetViaLaunchSpecimen extends RequiresTarget, Require default TargetObject obtainTarget() throws Throwable { TargetLauncher launcher = getTest().findLauncher(); assertNotNull("No launcher found", launcher); - TargetObject container = getTest().findProcessContainer(); - assertNotNull("No process container found", container); DebuggerTestSpecimen specimen = getLaunchSpecimen(); waitAcc(launcher); launcher.launch(specimen.getLauncherArgs()); - return retryForProcessRunning(container, specimen, getTest()); + return retryForProcessRunning(specimen, getTest()); } } diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/testutil/DebuggerModelTestUtils.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/testutil/DebuggerModelTestUtils.java index c601814d6c..01ce39fa5d 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/testutil/DebuggerModelTestUtils.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/testutil/DebuggerModelTestUtils.java @@ -31,6 +31,7 @@ import ghidra.dbg.target.*; import ghidra.dbg.target.TargetSteppable.TargetStepKind; import ghidra.dbg.test.AbstractDebuggerModelTest; import ghidra.dbg.test.AbstractDebuggerModelTest.DebuggerTestSpecimen; +import ghidra.dbg.util.PathUtils; import ghidra.util.NumericUtilities; public interface DebuggerModelTestUtils extends AsyncTestUtils { @@ -164,10 +165,9 @@ public interface DebuggerModelTestUtils extends AsyncTestUtils { }).findFirst().orElse(null); } - @SuppressWarnings({ "rawtypes", "unchecked" }) - default Collection fetchProcesses(TargetObject container) + default Collection fetchProcesses(AbstractDebuggerModelTest test) throws Throwable { - return (Collection) waitOn(container.fetchElements(true)).values(); + return test.m.findAll(TargetProcess.class, PathUtils.parse(""), false).values(); } @SuppressWarnings({ "rawtypes", "unchecked" }) @@ -176,32 +176,30 @@ public interface DebuggerModelTestUtils extends AsyncTestUtils { return (Collection) waitOn(container.fetchElements(true)).values(); } - default TargetProcess getProcessRunning(TargetObject container, - DebuggerTestSpecimen specimen, AbstractDebuggerModelTest test) throws Throwable { - return getProcessRunning(container, specimen, test, p -> true); + default TargetProcess getProcessRunning(DebuggerTestSpecimen specimen, + AbstractDebuggerModelTest test) throws Throwable { + return getProcessRunning(specimen, test, p -> true); } - default TargetProcess getProcessRunning(TargetObject container, - DebuggerTestSpecimen specimen, AbstractDebuggerModelTest test, - Predicate predicate) throws Throwable { - return getProcessRunning(fetchProcesses(container), specimen, test, predicate); + default TargetProcess getProcessRunning(DebuggerTestSpecimen specimen, + AbstractDebuggerModelTest test, Predicate predicate) throws Throwable { + return getProcessRunning(fetchProcesses(test), specimen, test, predicate); } - default TargetProcess retryForProcessRunning(TargetObject container, + default TargetProcess retryForProcessRunning( DebuggerTestSpecimen specimen, AbstractDebuggerModelTest test) throws Throwable { return retry(() -> { - TargetProcess process = getProcessRunning(container, specimen, test); + TargetProcess process = getProcessRunning(specimen, test); assertNotNull(process); return process; }, List.of(AssertionError.class)); } - default TargetProcess retryForOtherProcessRunning(TargetObject container, - DebuggerTestSpecimen specimen, AbstractDebuggerModelTest test, - Predicate predicate, long timeoutMs) + default TargetProcess retryForOtherProcessRunning(DebuggerTestSpecimen specimen, + AbstractDebuggerModelTest test, Predicate predicate, long timeoutMs) throws Throwable { return retry(timeoutMs, () -> { - TargetProcess process = getProcessRunning(container, specimen, test, predicate); + TargetProcess process = getProcessRunning(specimen, test, predicate); assertNotNull(process); return process; }, List.of(AssertionError.class)); diff --git a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/testutil/TestDebuggerModelProvider.java b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/testutil/TestDebuggerModelProvider.java index 71c03edf7f..67ecba40ff 100644 --- a/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/testutil/TestDebuggerModelProvider.java +++ b/Ghidra/Debug/Framework-Debugging/src/test/java/ghidra/dbg/testutil/TestDebuggerModelProvider.java @@ -73,8 +73,8 @@ public interface TestDebuggerModelProvider { T findAny(Class cls, List seedPath) throws Throwable; - Map, T> findAll(Class cls, List seedPath) - throws Throwable; + Map, T> findAll(Class cls, List seedPath, + boolean atLeastOne) throws Throwable; TargetObject findContainer(Class cls, List seedPath) throws Throwable;