Merge remote-tracking branch 'origin/GP-5364_Dan_funcGraphPlusBptMarginBugs--SQUASHED'

This commit is contained in:
Ryan Kurtz
2025-04-18 13:47:46 -04:00
2 changed files with 76 additions and 16 deletions
@@ -25,9 +25,7 @@ import javax.swing.Icon;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import docking.ActionContext; import docking.ActionContext;
import docking.Tool;
import docking.action.*; import docking.action.*;
import docking.actions.PopupActionProvider;
import generic.theme.GColor; import generic.theme.GColor;
import ghidra.app.context.ProgramLocationActionContext; import ghidra.app.context.ProgramLocationActionContext;
import ghidra.app.decompiler.*; import ghidra.app.decompiler.*;
@@ -88,8 +86,7 @@ import ghidra.util.Msg;
DebuggerLogicalBreakpointService.class, DebuggerLogicalBreakpointService.class,
MarkerService.class, MarkerService.class,
}) })
public class DebuggerBreakpointMarkerPlugin extends Plugin public class DebuggerBreakpointMarkerPlugin extends Plugin {
implements PopupActionProvider {
private static final Color COLOR_BREAKPOINT_ENABLED_MARKER = private static final Color COLOR_BREAKPOINT_ENABLED_MARKER =
new GColor("color.debugger.plugin.resources.breakpoint.marker.enabled"); new GColor("color.debugger.plugin.resources.breakpoint.marker.enabled");
@@ -818,8 +815,6 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin
this.autoOptionsWiring = AutoOptions.wireOptions(this); this.autoOptionsWiring = AutoOptions.wireOptions(this);
updateDebouncer.addListener(__ -> SwingUtilities.invokeLater(() -> updateAllMarks())); updateDebouncer.addListener(__ -> SwingUtilities.invokeLater(() -> updateAllMarks()));
tool.addPopupActionProvider(this);
} }
@Override @Override
@@ -828,6 +823,14 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin
createActions(); createActions();
} }
@Override
protected void dispose() {
super.dispose();
if (markerService != null) {
markerService.setMarkerClickedListener(null);
}
}
@AutoOptionConsumed( @AutoOptionConsumed(
name = DebuggerResources.OPTION_NAME_COLORS_ENABLED_BREAKPOINT_COLORING_BACKGROUND) name = DebuggerResources.OPTION_NAME_COLORS_ENABLED_BREAKPOINT_COLORING_BACKGROUND)
private void setEnabledBreakpointMarkerBackground(boolean breakpointColoringBackground) { private void setEnabledBreakpointMarkerBackground(boolean breakpointColoringBackground) {
@@ -1041,7 +1044,7 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin
} }
this.breakpointService = breakpointService; this.breakpointService = breakpointService;
if (this.breakpointService != null) { if (this.breakpointService != null) {
breakpointService.addChangeListener(updateMarksListener); this.breakpointService.addChangeListener(updateMarksListener);
updateAllMarks(); updateAllMarks();
} }
} }
@@ -1089,11 +1092,6 @@ public class DebuggerBreakpointMarkerPlugin extends Plugin
tool.setMenuGroup(new String[] { SetBreakpointAction.NAME }, SetBreakpointAction.GROUP); tool.setMenuGroup(new String[] { SetBreakpointAction.NAME }, SetBreakpointAction.GROUP);
} }
@Override
public List<DockingActionIf> getPopupActions(Tool __, ActionContext context) {
return List.of(); // TODO: Actions by individual breakpoint?
}
@Override @Override
public void processEvent(PluginEvent event) { public void processEvent(PluginEvent event) {
if (event instanceof ProgramOpenedPluginEvent) { if (event instanceof ProgramOpenedPluginEvent) {
@@ -19,9 +19,8 @@ import static org.junit.Assert.*;
import java.awt.*; import java.awt.*;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.*;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -47,6 +46,8 @@ import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils; import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingUtils;
import ghidra.app.plugin.core.decompile.DecompilePlugin; import ghidra.app.plugin.core.decompile.DecompilePlugin;
import ghidra.app.plugin.core.decompile.DecompilerProvider; import ghidra.app.plugin.core.decompile.DecompilerProvider;
import ghidra.app.plugin.core.functiongraph.FGProvider;
import ghidra.app.plugin.core.functiongraph.FunctionGraphPlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.viewer.listingpanel.ListingPanel; import ghidra.app.util.viewer.listingpanel.ListingPanel;
import ghidra.debug.api.breakpoint.LogicalBreakpoint; import ghidra.debug.api.breakpoint.LogicalBreakpoint;
@@ -88,6 +89,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
protected DebuggerBreakpointMarkerPlugin breakpointMarkerPlugin; protected DebuggerBreakpointMarkerPlugin breakpointMarkerPlugin;
protected DebuggerListingPlugin listingPlugin; protected DebuggerListingPlugin listingPlugin;
protected CodeBrowserPlugin codeBrowserPlugin; protected CodeBrowserPlugin codeBrowserPlugin;
protected FunctionGraphPlugin functionGraphPlugin; // Not initialized in setup
protected DebuggerLogicalBreakpointService breakpointService; protected DebuggerLogicalBreakpointService breakpointService;
protected DebuggerStaticMappingService mappingService; protected DebuggerStaticMappingService mappingService;
@@ -907,4 +909,64 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
} }
}); });
} }
@Test
public void testWithFunctionGraphPlugin() throws Throwable {
functionGraphPlugin = addPlugin(tool, FunctionGraphPlugin.class);
tool.removePlugins(List.of(breakpointMarkerPlugin));
breakpointMarkerPlugin = addPlugin(tool, DebuggerBreakpointMarkerPlugin.class);
tool.removePlugins(List.of(functionGraphPlugin));
}
protected void toggleInstallFunctionGraphPlugin() throws Throwable {
if (functionGraphPlugin == null) {
functionGraphPlugin = addPlugin(tool, FunctionGraphPlugin.class);
}
else {
tool.removePlugins(List.of(functionGraphPlugin));
functionGraphPlugin = null;
}
}
protected void toggleInstallBreakointMarkerPlugin() throws Throwable {
if (breakpointMarkerPlugin == null) {
breakpointMarkerPlugin = addPlugin(tool, DebuggerBreakpointMarkerPlugin.class);
}
else {
tool.removePlugins(List.of(breakpointMarkerPlugin));
breakpointMarkerPlugin = null;
}
}
@Test
public void testWithFunctionGraphPluginFrenetically() throws Throwable {
Random rnd = new Random();
for (int i = 0; i < 100; i++) {
if (rnd.nextBoolean()) {
toggleInstallFunctionGraphPlugin();
}
else {
toggleInstallBreakointMarkerPlugin();
}
}
}
@Test
public void testWithFunctionGraphPluginAndOpenProgram() throws Throwable {
functionGraphPlugin = addPlugin(tool, FunctionGraphPlugin.class);
tool.removePlugins(List.of(breakpointMarkerPlugin));
FGProvider functionGraphProvider = waitForComponentProvider(FGProvider.class);
prepareDecompiler(); // Just to get a minimally meaningful program
functionGraphProvider.setVisible(true);
breakpointMarkerPlugin = addPlugin(tool, DebuggerBreakpointMarkerPlugin.class);
tool.removePlugins(List.of(functionGraphPlugin));
breakpointMarkerPlugin = addPlugin(tool, DebuggerBreakpointMarkerPlugin.class);
tool.removePlugins(List.of(functionGraphPlugin));
breakpointMarkerPlugin = addPlugin(tool, DebuggerBreakpointMarkerPlugin.class);
tool.removePlugins(List.of(functionGraphPlugin));
}
} }