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) {
if (!isVisible(location)) {
return;
}
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")) {
// Defaults with emuEnable=true
TraceBreakpointLocation loc = trace.getBreakpointManager()
.addBreakpoint(computePath(), Lifespan.at(snap),
.addBreakpoint(computePath(), Lifespan.ALL,
BreakpointActionItem.range(address, length), Set.of(), kinds, false, null);
loc.setName(snap, createName(address));
loc.setEmuSleigh(snap, emuSleigh);

View File

@@ -99,6 +99,9 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
protected abstract void handleToggleBreakpointInvocation(
TraceBreakpointLocation expectedBreakpoint, boolean expectedEnabled) throws Throwable;
protected abstract void handleDeleteBreakpointInvocation(T target,
TraceBreakpointLocation expectedLoc) throws Throwable;
protected void addStaticMemoryAndBreakpoint() throws LockException, DuplicateNameException,
MemoryConflictException, AddressOverflowException, CancelledException {
try (Transaction tx = program.openTransaction("Add bookmark break")) {
@@ -121,6 +124,7 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
protected void assertProviderEmpty() {
assertTrue(breakpointsProvider.breakpointTableModel.getModelData().isEmpty());
assertTrue(breakpointsProvider.locationTableModel.getModelData().isEmpty());
}
@Before
@@ -454,10 +458,23 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
}
@Test
public void testActionClearSelectedBreakpoints() throws Exception {
createProgram();
public void testActionClearSelectedBreakpoints() throws Throwable {
T target = createTarget1();
Trace trace = getTrace(target);
createProgramFromTrace(trace);
intoProject(trace);
intoProject(program);
addMapping(trace, program);
addLiveMemoryAndBreakpoint(getProcess1(), target);
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());
@@ -466,6 +483,7 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
assertFalse(breakpointsProvider.actionClearSelectedBreakpoints.isEnabled());
LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints());
LogicalBreakpointRow row =
Unique.assertOne(breakpointsProvider.breakpointTableModel.getModelData());
breakpointsProvider.breakpointFilterPanel.setSelectedItem(row);
@@ -485,29 +503,91 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
performAction(breakpointsProvider.actionClearSelectedBreakpoints);
TraceBreakpointLocation brk = Unique.assertOne(lb.getTraceBreakpoints(tb.trace));
lb.delete();
handleDeleteBreakpointInvocation(target, brk);
assertProviderEmpty();
assertFalse(breakpointsProvider.actionClearSelectedBreakpoints.isEnabled());
}
@Test
public void testActionClearAllBreakpoints() throws Exception {
createProgram();
public void testActionClearAllBreakpoints() throws Throwable {
T target = createTarget1();
Trace trace = getTrace(target);
createProgramFromTrace(trace);
intoProject(trace);
intoProject(program);
programManager.openProgram(program);
waitForSwing();
traceManager.openTrace(trace);
traceManager.activateTrace(trace);
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();
waitForDomainObject(program);
assertTrue(breakpointsProvider.actionClearAllBreakpoints.isEnabled());
performAction(breakpointsProvider.actionClearAllBreakpoints);
for (LogicalBreakpoint lb : breakpointService.getAllBreakpoints()) {
TraceBreakpointLocation brk = Unique.assertOne(lb.getTraceBreakpoints(tb.trace));
lb.delete();
handleDeleteBreakpointInvocation(target, brk);
}
assertProviderEmpty();
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
public void testActionMakeBreakpointsEffective() throws Throwable {
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
protected void handleToggleBreakpointInvocation(TraceBreakpointLocation expectedLoc,
boolean expectedEn) throws Throwable {