diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServiceTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServiceTest.java index 01a0c05d9d..ba2cf033aa 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServiceTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/DebuggerControlServiceTest.java @@ -26,7 +26,7 @@ import org.junit.Test; import db.Transaction; import ghidra.app.plugin.assembler.*; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerTest; -import ghidra.app.services.*; +import ghidra.app.services.DebuggerControlService; import ghidra.app.services.DebuggerControlService.StateEditor; import ghidra.async.AsyncUtils.TemperamentalRunnable; import ghidra.dbg.target.TargetRegisterBank; @@ -73,15 +73,14 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerTest E expecting(Class cls, TemperamentalRunnable action) { try { action.run(); - fail("Expected exception type " + cls + ", but got no error."); } catch (Throwable e) { if (cls.isInstance(e)) { return cls.cast(e); } - fail("Expection exception type " + cls + ", but got " + e); + throw new AssertionError("Expection exception type " + cls + ", but got " + e, e); } - throw new AssertionError(); + throw new AssertionError("Expected exception type " + cls + ", but got no error."); } @Before @@ -518,6 +517,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerTest @Test public void testWriteReadOnlyMemoryErr() throws Throwable { createAndOpenTrace(); + targetService.publishTarget(new MockTarget(tb.trace)); activateTrace(); controlService.setCurrentMode(tb.trace, ControlMode.RO_TARGET); @@ -531,6 +531,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerTest @Test public void testWriteReadOnlyRegisterErr() throws Throwable { createAndOpenTrace(); + targetService.publishTarget(new MockTarget(tb.trace)); activateTrace(); controlService.setCurrentMode(tb.trace, ControlMode.RO_TARGET); diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/MockTarget.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/MockTarget.java new file mode 100644 index 0000000000..c2dd3952db --- /dev/null +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/service/control/MockTarget.java @@ -0,0 +1,254 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ghidra.app.plugin.core.debug.service.control; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CompletableFuture; + +import docking.ActionContext; +import ghidra.async.AsyncUtils; +import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; +import ghidra.debug.api.target.ActionName; +import ghidra.debug.api.target.Target; +import ghidra.debug.api.target.Target.ActionEntry; +import ghidra.debug.api.tracemgr.DebuggerCoordinates; +import ghidra.program.model.address.*; +import ghidra.program.model.lang.Register; +import ghidra.program.model.lang.RegisterValue; +import ghidra.trace.model.Trace; +import ghidra.trace.model.breakpoint.TraceBreakpoint; +import ghidra.trace.model.breakpoint.TraceBreakpointKind; +import ghidra.trace.model.guest.TracePlatform; +import ghidra.trace.model.stack.TraceStackFrame; +import ghidra.trace.model.target.TraceObjectKeyPath; +import ghidra.trace.model.thread.TraceThread; +import ghidra.util.exception.CancelledException; +import ghidra.util.task.TaskMonitor; + +class MockTarget implements Target { + private final Trace trace; + private long snap = 0; + + public MockTarget(Trace trace) { + this.trace = trace; + } + + @Override + public boolean isValid() { + return true; + } + + @Override + public Trace getTrace() { + return trace; + } + + public void setSnap(long snap) { + this.snap = snap; + } + + @Override + public long getSnap() { + return snap; + } + + @Override + public Map collectActions(ActionName name, ActionContext context) { + return Map.of(); + } + + @Override + public TraceThread getThreadForSuccessor(TraceObjectKeyPath path) { + return null; + } + + @Override + public TargetExecutionState getThreadExecutionState(TraceThread thread) { + return null; + } + + @Override + public TraceStackFrame getStackFrameForSuccessor(TraceObjectKeyPath path) { + return null; + } + + @Override + public boolean isSupportsFocus() { + return false; + } + + @Override + public TraceObjectKeyPath getFocus() { + return null; + } + + @Override + public CompletableFuture activateAsync(DebuggerCoordinates prev, + DebuggerCoordinates coords) { + return AsyncUtils.nil(); + } + + @Override + public void activate(DebuggerCoordinates prev, DebuggerCoordinates coords) { + } + + @Override + public CompletableFuture invalidateMemoryCachesAsync() { + return AsyncUtils.nil(); + } + + @Override + public void invalidateMemoryCaches() { + } + + @Override + public CompletableFuture readMemoryAsync(AddressSetView set, TaskMonitor monitor) { + return AsyncUtils.nil(); + } + + @Override + public void readMemory(AddressSetView set, TaskMonitor monitor) throws CancelledException { + } + + @Override + public CompletableFuture writeMemoryAsync(Address address, byte[] data) { + return AsyncUtils.nil(); + } + + @Override + public void writeMemory(Address address, byte[] data) { + } + + @Override + public CompletableFuture readRegistersAsync(TracePlatform platform, + TraceThread thread, int frame, Set registers) { + return AsyncUtils.nil(); + } + + @Override + public void readRegisters(TracePlatform platform, TraceThread thread, int frame, + Set registers) { + } + + @Override + public CompletableFuture readRegistersAsync(TracePlatform platform, + TraceThread thread, int frame, AddressSetView guestSet) { + return AsyncUtils.nil(); + } + + @Override + public void readRegisters(TracePlatform platform, TraceThread thread, int frame, + AddressSetView guestSet) { + } + + @Override + public CompletableFuture writeRegisterAsync(TracePlatform platform, + TraceThread thread, int frame, RegisterValue value) { + return AsyncUtils.nil(); + } + + @Override + public void writeRegister(TracePlatform platform, TraceThread thread, int frame, + RegisterValue value) { + } + + @Override + public CompletableFuture writeRegisterAsync(TracePlatform platform, + TraceThread thread, int frame, Address address, byte[] data) { + return AsyncUtils.nil(); + } + + @Override + public void writeRegister(TracePlatform platform, TraceThread thread, int frame, + Address address, byte[] data) { + } + + @Override + public boolean isVariableExists(TracePlatform platform, TraceThread thread, int frame, + Address address, int length) { + return false; + } + + @Override + public CompletableFuture writeVariableAsync(TracePlatform platform, + TraceThread thread, int frame, Address address, byte[] data) { + return AsyncUtils.nil(); + } + + @Override + public void writeVariable(TracePlatform platform, TraceThread thread, int frame, + Address address, byte[] data) { + } + + @Override + public Set getSupportedBreakpointKinds() { + return Set.of(); + } + + @Override + public CompletableFuture placeBreakpointAsync(AddressRange range, + Set kinds, String condition, String commands) { + return AsyncUtils.nil(); + } + + @Override + public void placeBreakpoint(AddressRange range, Set kinds, + String condition, String commands) { + } + + @Override + public boolean isBreakpointValid(TraceBreakpoint breakpoint) { + return false; + } + + @Override + public CompletableFuture deleteBreakpointAsync(TraceBreakpoint breakpoint) { + return AsyncUtils.nil(); + } + + @Override + public void deleteBreakpoint(TraceBreakpoint breakpoint) { + } + + @Override + public CompletableFuture toggleBreakpointAsync(TraceBreakpoint breakpoint, + boolean enabled) { + return AsyncUtils.nil(); + } + + @Override + public void toggleBreakpoint(TraceBreakpoint breakpoint, boolean enabled) { + } + + @Override + public CompletableFuture forceTerminateAsync() { + return AsyncUtils.nil(); + } + + @Override + public void forceTerminate() { + } + + @Override + public CompletableFuture disconnectAsync() { + return AsyncUtils.nil(); + } + + @Override + public void disconnect() { + } +} diff --git a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java index 534d1b1a4e..072a300117 100644 --- a/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java +++ b/Ghidra/Debug/Debugger/src/test/java/ghidra/app/plugin/core/debug/stack/StackUnwinderTest.java @@ -21,6 +21,8 @@ import java.io.IOException; import java.math.BigInteger; import java.nio.ByteBuffer; import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import org.junit.Test; @@ -28,8 +30,11 @@ import org.junit.Test; import db.Transaction; import docking.widgets.fieldpanel.Layout; import docking.widgets.fieldpanel.field.Field; +import docking.widgets.fieldpanel.listener.IndexMapper; +import docking.widgets.fieldpanel.listener.LayoutModelListener; import docking.widgets.fieldpanel.support.FieldLocation; import generic.Unique; +import generic.test.rule.Repeated; import ghidra.app.decompiler.*; import ghidra.app.decompiler.component.*; import ghidra.app.plugin.assembler.*; @@ -37,6 +42,7 @@ import ghidra.app.plugin.assembler.sleigh.sem.*; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.debug.disassemble.TraceDisassembleCommand; import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerTest; +import ghidra.app.plugin.core.debug.gui.action.NoneLocationTrackingSpec; import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin; import ghidra.app.plugin.core.debug.gui.stack.vars.*; import ghidra.app.plugin.core.debug.gui.stack.vars.VariableValueRow.*; @@ -80,6 +86,7 @@ import ghidra.trace.model.thread.TraceThread; import ghidra.trace.model.time.schedule.Scheduler; import ghidra.util.Msg; import ghidra.util.NumericUtilities; +import junit.framework.AssertionFailedError; public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @@ -882,8 +889,6 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { } protected Function runToTallestRecursionAndCreateFrames(int n) throws Throwable { - addPlugins(); - Function function = createFibonacciProgramX86_32(); Address entry = function.getEntryPoint(); @@ -932,8 +937,6 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { } protected Function runToRetSetGlobalAndCreateFrames() throws Throwable { - addPlugins(); - Function function = createSetGlobalProgramX86_32(); Address entry = function.getEntryPoint(); @@ -976,8 +979,6 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { } protected Function runToRetFillStructAndCreateFrames() throws Throwable { - addPlugins(); - Function function = createFillStructProgramX86_32(); Address entry = function.getEntryPoint(); @@ -1020,8 +1021,6 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { } protected Function runToRetFillStructArrayAndCreateFrames() throws Throwable { - addPlugins(); - Function function = createFillStructArrayProgramX86_32(); Address entry = function.getEntryPoint(); @@ -1065,6 +1064,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testCreateFramesTallestX86_32() throws Throwable { + addPlugins(); Function function = runToTallestRecursionAndCreateFrames(9); DebuggerCoordinates tallest = traceManager.getCurrent(); @@ -1174,6 +1174,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testStackVariableHover() throws Throwable { + addPlugins(); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); Function function = runToTallestRecursionAndCreateFrames(2); @@ -1195,6 +1196,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testRegisterVariableHover() throws Throwable { + addPlugins(); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); Function function = runToTallestRecursionAndCreateFrames(2); @@ -1215,6 +1217,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testReturnParameterHover() throws Throwable { + addPlugins(); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); Function function = runToTallestRecursionAndCreateFrames(2); @@ -1235,6 +1238,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testGlobalOperandHover() throws Throwable { + addPlugins(); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); runToRetSetGlobalAndCreateFrames(); @@ -1280,6 +1284,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testGlobalOperandInTraceHover() throws Throwable { + addPlugins(); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); runToRetSetGlobalAndCreateFrames(); @@ -1305,6 +1310,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testStackReferenceHover() throws Throwable { + addPlugins(); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); runToTallestRecursionAndCreateFrames(2); @@ -1327,6 +1333,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testRegisterReferenceHover() throws Throwable { + addPlugins(); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); runToTallestRecursionAndCreateFrames(2); @@ -1348,6 +1355,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testSavedRegisterReferenceHover() throws Throwable { + addPlugins(); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); // need 3 frames. 0 has already popped EBP, so not saved. 1 will save on behalf of 2. @@ -1369,6 +1377,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testRegisterReferenceInTraceHover() throws Throwable { + addPlugins(); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); runToTallestRecursionAndCreateFrames(2); @@ -1451,13 +1460,34 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { }); } - protected HoverLocation findTokenLocation(Function function, String tokText, String fieldText) { + protected HoverLocation findTokenLocation(Function function, String tokText, String fieldText) + throws Throwable { + CompletableFuture ready = new CompletableFuture<>(); + decompilerPanel.getLayoutController().addLayoutModelListener(new LayoutModelListener() { + @Override + public void modelSizeChanged(IndexMapper indexMapper) { + if (decompilerPanel.getCurrentLocation() != null) { + ready.complete(null); + } + } + + @Override + public void dataChanged(BigInteger start, BigInteger end) { + } + }); tool.showComponentProvider(decompilerProvider, true); - return findTokenLocation(decompilerPanel, function, tokText, fieldText); + ready.get(5, TimeUnit.SECONDS); + try { + return findTokenLocation(decompilerPanel, function, tokText, fieldText); + } + catch (AssertionFailedError e) { + throw e; + } } @Test public void testGlobalHighVarHover() throws Throwable { + addPlugins(); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); Function function = runToRetSetGlobalAndCreateFrames(); @@ -1480,6 +1510,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testStackHighVarHover() throws Throwable { + addPlugins(); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); Function function = runToTallestRecursionAndCreateFrames(2); @@ -1501,6 +1532,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testRegisterHighVarHover() throws Throwable { + addPlugins(); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); Function function = runToTallestRecursionAndCreateFrames(2); @@ -1522,6 +1554,9 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testStructureGlobalHighVarStruct() throws Throwable { + addPlugins(); + // PC Tracking interferes with goTo + listingPlugin.setTrackingSpec(NoneLocationTrackingSpec.INSTANCE); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); Function function = runToRetFillStructAndCreateFrames(); @@ -1544,6 +1579,9 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testStructureGlobalHighVarStructField() throws Throwable { + addPlugins(); + // PC Tracking interferes with goTo + listingPlugin.setTrackingSpec(NoneLocationTrackingSpec.INSTANCE); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); Function function = runToRetFillStructAndCreateFrames(); @@ -1565,6 +1603,9 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testStructureStackHighVarStruct() throws Throwable { + addPlugins(); + // PC Tracking interferes with goTo + listingPlugin.setTrackingSpec(NoneLocationTrackingSpec.INSTANCE); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); Function function = runToRetFillStructAndCreateFrames(); @@ -1588,6 +1629,9 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testStructureStackHighVarStructField() throws Throwable { + addPlugins(); + // PC Tracking interferes with goTo + listingPlugin.setTrackingSpec(NoneLocationTrackingSpec.INSTANCE); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); Function function = runToRetFillStructAndCreateFrames(); @@ -1610,6 +1654,9 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testStructurePointerRegisterHighVarStruct() throws Throwable { + addPlugins(); + // PC Tracking interferes with goTo + listingPlugin.setTrackingSpec(NoneLocationTrackingSpec.INSTANCE); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); runToRetFillStructAndCreateFrames(); @@ -1634,6 +1681,9 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testStructurePointerRegisterHighVarStructField() throws Throwable { + addPlugins(); + // PC Tracking interferes with goTo + listingPlugin.setTrackingSpec(NoneLocationTrackingSpec.INSTANCE); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); runToRetFillStructAndCreateFrames(); @@ -1656,6 +1706,9 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { @Test public void testArrayGlobalHighVarIndexedField() throws Throwable { + addPlugins(); + // PC Tracking interferes with goTo + listingPlugin.setTrackingSpec(NoneLocationTrackingSpec.INSTANCE); VariableValueHoverPlugin valuesPlugin = addPlugin(tool, VariableValueHoverPlugin.class); VariableValueHoverService valuesService = valuesPlugin.getHoverService(); runToRetFillStructArrayAndCreateFrames(); @@ -1680,7 +1733,7 @@ public class StackUnwinderTest extends AbstractGhidraHeadedDebuggerTest { /** * e.g., dstack._12_4_ */ - public void testOffcutPieceReference() throws Throwable { + public void testOffcutPieceReference() { Unfinished.TODO(); } diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/AbstractDebuggerBreakpointMarkerPluginTest.java b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/AbstractDebuggerBreakpointMarkerPluginTest.java index 2f8a2c21ea..19677ae117 100644 --- a/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/AbstractDebuggerBreakpointMarkerPluginTest.java +++ b/Ghidra/Test/DebuggerIntegrationTest/src/test/java/ghidra/app/plugin/core/debug/gui/breakpoint/AbstractDebuggerBreakpointMarkerPluginTest.java @@ -355,11 +355,11 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest })); escapePopupMenu(); - lb.disableForProgram(); - waitForDomainObject(program); - waitForPass( - () -> assertEquals(State.INCONSISTENT_DISABLED, - lb.computeStateForProgram(program))); + waitForPass(() -> { + lb.disableForProgram(); + waitForDomainObject(program); + assertEquals(State.INCONSISTENT_DISABLED, lb.computeStateForProgram(program)); + }); waitForPass(noExc(() -> { clickListing(codeBrowserPlugin.getListingPanel(), addr(program, 0x00400123), @@ -387,10 +387,11 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest })); escapePopupMenu(); - lb.enableForProgram(); - waitForDomainObject(program); - waitForPass( - () -> assertEquals(State.INCONSISTENT_ENABLED, lb.computeStateForProgram(program))); + waitForPass(() -> { + lb.enableForProgram(); + waitForDomainObject(program); + assertEquals(State.INCONSISTENT_ENABLED, lb.computeStateForProgram(program)); + }); waitForPass(noExc(() -> { clickListing(codeBrowserPlugin.getListingPanel(), addr(program, 0x00400123), @@ -424,10 +425,11 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest })); escapePopupMenu(); - lb.disableForProgram(); // Adds "enable", which will only affect bookmark - waitForDomainObject(program); - waitForPass( - () -> assertEquals(State.INCONSISTENT_ENABLED, lb.computeStateForTrace(trace))); + waitForPass(() -> { + lb.disableForProgram(); // Adds "enable", which will only affect bookmark + waitForDomainObject(program); + assertEquals(State.INCONSISTENT_ENABLED, lb.computeStateForTrace(trace)); + }); waitForPass(noExc(() -> { clickListing(listingPlugin.getListingPanel(), addr(trace, 0x55550123), @@ -455,10 +457,11 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest })); escapePopupMenu(); - lb.enableForProgram(); // This time, adds "disable", which will only affect bookmark - waitForDomainObject(program); - waitForPass( - () -> assertEquals(State.INCONSISTENT_DISABLED, lb.computeStateForTrace(trace))); + waitForPass(() -> { + lb.enableForProgram(); // This time, adds "disable", which will only affect bookmark + waitForDomainObject(program); + assertEquals(State.INCONSISTENT_DISABLED, lb.computeStateForTrace(trace)); + }); waitForPass(noExc(() -> { clickListing(listingPlugin.getListingPanel(), addr(trace, 0x55550123),