Merge remote-tracking branch 'origin/GP-6439_ghidra_red_breakpoint_panel_bug'

This commit is contained in:
Ryan Kurtz
2026-09-02 09:41:11 -04:00
4 changed files with 101 additions and 10 deletions

View File

@@ -851,9 +851,6 @@ public class DebuggerBreakpointsProvider extends ComponentProviderAdapter
} }
private void locationDeleted(TraceBreakpointLocation location) { private void locationDeleted(TraceBreakpointLocation location) {
if (!isVisible(location)) {
return;
}
breakpointLocationRemoved(location); breakpointLocationRemoved(location);
} }

View File

@@ -104,7 +104,7 @@ public record PlaceEmuBreakpointActionItem(Trace trace, long snap, Address addre
try (Transaction tx = trace.openTransaction("Place Emulated Breakpoint")) { try (Transaction tx = trace.openTransaction("Place Emulated Breakpoint")) {
// Defaults with emuEnable=true // Defaults with emuEnable=true
TraceBreakpointLocation loc = trace.getBreakpointManager() TraceBreakpointLocation loc = trace.getBreakpointManager()
.addBreakpoint(computePath(), Lifespan.at(snap), .addBreakpoint(computePath(), Lifespan.ALL,
BreakpointActionItem.range(address, length), Set.of(), kinds, false, null); BreakpointActionItem.range(address, length), Set.of(), kinds, false, null);
loc.setName(snap, createName(address)); loc.setName(snap, createName(address));
loc.setEmuSleigh(snap, emuSleigh); loc.setEmuSleigh(snap, emuSleigh);

View File

@@ -99,6 +99,9 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
protected abstract void handleToggleBreakpointInvocation( protected abstract void handleToggleBreakpointInvocation(
TraceBreakpointLocation expectedBreakpoint, boolean expectedEnabled) throws Throwable; TraceBreakpointLocation expectedBreakpoint, boolean expectedEnabled) throws Throwable;
protected abstract void handleDeleteBreakpointInvocation(T target,
TraceBreakpointLocation expectedLoc) throws Throwable;
protected void addStaticMemoryAndBreakpoint() throws LockException, DuplicateNameException, protected void addStaticMemoryAndBreakpoint() throws LockException, DuplicateNameException,
MemoryConflictException, AddressOverflowException, CancelledException { MemoryConflictException, AddressOverflowException, CancelledException {
try (Transaction tx = program.openTransaction("Add bookmark break")) { try (Transaction tx = program.openTransaction("Add bookmark break")) {
@@ -121,6 +124,7 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
protected void assertProviderEmpty() { protected void assertProviderEmpty() {
assertTrue(breakpointsProvider.breakpointTableModel.getModelData().isEmpty()); assertTrue(breakpointsProvider.breakpointTableModel.getModelData().isEmpty());
assertTrue(breakpointsProvider.locationTableModel.getModelData().isEmpty());
} }
@Before @Before
@@ -454,10 +458,23 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
} }
@Test @Test
public void testActionClearSelectedBreakpoints() throws Exception { public void testActionClearSelectedBreakpoints() throws Throwable {
createProgram(); T target = createTarget1();
Trace trace = getTrace(target);
createProgramFromTrace(trace);
intoProject(trace);
intoProject(program);
addMapping(trace, program);
addLiveMemoryAndBreakpoint(getProcess1(), target);
programManager.openProgram(program); programManager.openProgram(program);
waitForSwing(); traceManager.openTrace(trace);
traceManager.activateTrace(trace);
waitForPass(() -> {
LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints());
assertEquals(program, lb.getProgram());
assertEquals(Set.of(trace), lb.getParticipatingTraces());
assertEquals(State.ENABLED, lb.computeState());
});
assertFalse(breakpointsProvider.actionClearSelectedBreakpoints.isEnabled()); assertFalse(breakpointsProvider.actionClearSelectedBreakpoints.isEnabled());
@@ -466,6 +483,7 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
assertFalse(breakpointsProvider.actionClearSelectedBreakpoints.isEnabled()); assertFalse(breakpointsProvider.actionClearSelectedBreakpoints.isEnabled());
LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints());
LogicalBreakpointRow row = LogicalBreakpointRow row =
Unique.assertOne(breakpointsProvider.breakpointTableModel.getModelData()); Unique.assertOne(breakpointsProvider.breakpointTableModel.getModelData());
breakpointsProvider.breakpointFilterPanel.setSelectedItem(row); breakpointsProvider.breakpointFilterPanel.setSelectedItem(row);
@@ -485,29 +503,91 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
performAction(breakpointsProvider.actionClearSelectedBreakpoints); performAction(breakpointsProvider.actionClearSelectedBreakpoints);
TraceBreakpointLocation brk = Unique.assertOne(lb.getTraceBreakpoints(tb.trace));
lb.delete();
handleDeleteBreakpointInvocation(target, brk);
assertProviderEmpty(); assertProviderEmpty();
assertFalse(breakpointsProvider.actionClearSelectedBreakpoints.isEnabled()); assertFalse(breakpointsProvider.actionClearSelectedBreakpoints.isEnabled());
} }
@Test @Test
public void testActionClearAllBreakpoints() throws Exception { public void testActionClearAllBreakpoints() throws Throwable {
createProgram(); T target = createTarget1();
Trace trace = getTrace(target);
createProgramFromTrace(trace);
intoProject(trace);
intoProject(program);
programManager.openProgram(program); programManager.openProgram(program);
waitForSwing(); traceManager.openTrace(trace);
traceManager.activateTrace(trace);
assertFalse(breakpointsProvider.actionClearAllBreakpoints.isEnabled()); assertFalse(breakpointsProvider.actionClearAllBreakpoints.isEnabled());
addMapping(trace, program);
addLiveMemoryAndBreakpoint(getProcess1(), target);
waitForPass(() -> {
LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints());
assertEquals(program, lb.getProgram());
assertEquals(Set.of(trace), lb.getParticipatingTraces());
assertEquals(State.ENABLED, lb.computeState());
});
addStaticMemoryAndBreakpoint(); addStaticMemoryAndBreakpoint();
waitForDomainObject(program); waitForDomainObject(program);
assertTrue(breakpointsProvider.actionClearAllBreakpoints.isEnabled()); assertTrue(breakpointsProvider.actionClearAllBreakpoints.isEnabled());
performAction(breakpointsProvider.actionClearAllBreakpoints); performAction(breakpointsProvider.actionClearAllBreakpoints);
for (LogicalBreakpoint lb : breakpointService.getAllBreakpoints()) {
TraceBreakpointLocation brk = Unique.assertOne(lb.getTraceBreakpoints(tb.trace));
lb.delete();
handleDeleteBreakpointInvocation(target, brk);
}
assertProviderEmpty(); assertProviderEmpty();
assertFalse(breakpointsProvider.actionClearAllBreakpoints.isEnabled()); assertFalse(breakpointsProvider.actionClearAllBreakpoints.isEnabled());
} }
@Test
public void testClearEmuBreakpoint() throws Throwable {
DebuggerControlService controlService = addPlugin(tool,
DebuggerControlServicePlugin.class);
T target = createTarget1();
Trace trace = getTrace(target);
controlService.setCurrentMode(trace, ControlMode.RW_EMULATOR);
createProgramFromTrace(trace);
intoProject(trace);
intoProject(program);
addMapping(trace, program);
addStaticMemoryAndBreakpoint();
addLiveMemory(getProcess1());
programManager.openProgram(program);
traceManager.openTrace(trace);
traceManager.activateTrace(trace);
LogicalBreakpointRow row = waitForPass(() -> {
LogicalBreakpointRow newRow =
Unique.assertOne(breakpointsProvider.breakpointTableModel.getModelData());
LogicalBreakpoint lb = newRow.getLogicalBreakpoint();
assertEquals(program, lb.getProgram());
assertEquals(Set.of(trace), lb.getMappedTraces());
assertEquals(Set.of(), lb.getParticipatingTraces());
assertEquals(State.INEFFECTIVE_ENABLED, newRow.getState());
return newRow;
});
row.setEnabled(true);
breakpointsProvider.breakpointFilterPanel.setSelectedItem(row);
waitForSwing();
performAction(breakpointsProvider.actionClearSelectedBreakpoints);
waitForSwing();
assertProviderEmpty();
}
@Test @Test
public void testActionMakeBreakpointsEffective() throws Throwable { public void testActionMakeBreakpointsEffective() throws Throwable {
DebuggerConsolePlugin consolePlugin = addPlugin(tool, DebuggerConsolePlugin.class); DebuggerConsolePlugin consolePlugin = addPlugin(tool, DebuggerConsolePlugin.class);

View File

@@ -139,6 +139,20 @@ public class DebuggerRmiBreakpointsProviderTest
} }
} }
@Override
protected void handleDeleteBreakpointInvocation(TraceRmiTarget target,
TraceBreakpointLocation expectedLoc) throws Throwable {
Map<String, Object> args = rmiMethodDeleteBreak.expect();
try (Transaction tx = tb.startTransaction()) {
expectedLoc.getObject().removeTree(Lifespan.nowOn(target.getSnap()));
}
waitForDomainObject(tb.trace);
rmiMethodDeleteBreak.result(null);
assertEquals(
Map.ofEntries(Map.entry("breakpoint", expectedLoc.getSpecification().getObject())),
args);
}
@Override @Override
protected void handleToggleBreakpointInvocation(TraceBreakpointLocation expectedLoc, protected void handleToggleBreakpointInvocation(TraceBreakpointLocation expectedLoc,
boolean expectedEn) throws Throwable { boolean expectedEn) throws Throwable {