GP-2295 - fixes and debug code for a history actions stack trace

This commit is contained in:
dragonmacher 2022-07-14 11:31:27 -04:00
parent b8425e804d
commit c8e15f0fe2
6 changed files with 133 additions and 95 deletions

View file

@ -90,7 +90,7 @@ public interface Navigatable {
* Return true if this Navigatable is part of the "dynamic analysis" or "debugger" user * Return true if this Navigatable is part of the "dynamic analysis" or "debugger" user
* interface. * interface.
* *
* @return tre if this Navigatable is "dynamic" * @return true if this Navigatable is "dynamic"
*/ */
default public boolean isDynamic() { default public boolean isDynamic() {
return false; return false;
@ -166,9 +166,9 @@ public interface Navigatable {
public void removeNavigatableListener(NavigatableRemovalListener listener); public void removeNavigatableListener(NavigatableRemovalListener listener);
/** /**
* Returns true if this navigatable is no longer valid, false if it is still good * Returns true if this navigatable is no longer valid
* *
* @return true if this navigatable is no longer valid, false if it is still good * @return true if this navigatable is no longer valid
*/ */
public boolean isDisposed(); public boolean isDisposed();

View file

@ -627,12 +627,18 @@ public class NavigationHistoryPlugin extends Plugin
} }
private Function getPreviousStartFunction(Navigatable navigatable) { private Function getPreviousStartFunction(Navigatable navigatable) {
ProgramLocation location = navigatable.getLocation(); ProgramLocation location = getProgramLocation(navigatable);
if (location == null) { if (location == null) {
return null; return null;
} }
Address currentAddress = location.getAddress(); Address currentAddress = location.getAddress();
Program program = location.getProgram();
FunctionManager functionManager = program.getFunctionManager();
return functionManager.getFunctionContaining(currentAddress);
}
private ProgramLocation getProgramLocation(Navigatable navigatable) {
// //
// The active component may still be showing the previously loaded function, instead // The active component may still be showing the previously loaded function, instead
@ -643,19 +649,49 @@ public class NavigationHistoryPlugin extends Plugin
// that the navigation actions will sometimes feel inconsistent, depending upon // that the navigation actions will sometimes feel inconsistent, depending upon
// what view is focused. // what view is focused.
// //
DockingWindowManager manager = DockingWindowManager.getActiveInstance(); DockingWindowManager dwm = DockingWindowManager.getActiveInstance();
ComponentProvider provider = manager.getActiveComponentProvider(); ComponentProvider activeProvider = dwm.getActiveComponentProvider();
if (provider instanceof Navigatable) { if (activeProvider instanceof Navigatable) {
LocationMemento memento = ((Navigatable) provider).getMemento(); Navigatable activeNavigatable = (Navigatable) activeProvider;
ProgramLocation otherLocation = memento.getProgramLocation(); LocationMemento memento = activeNavigatable.getMemento();
if (otherLocation != null) { ProgramLocation location =
currentAddress = otherLocation.getAddress(); validateProgramLocation(activeNavigatable, memento.getProgramLocation());
if (location != null) {
// prefer the active natigatable's location
return location;
} }
} }
ProgramLocation location = navigatable.getLocation();
return validateProgramLocation(navigatable, location);
}
private ProgramLocation validateProgramLocation(Navigatable navigatable,
ProgramLocation location) {
if (location == null) {
return null;
}
if (isClosedProgram(navigatable, location)) {
return null;
}
return location;
}
// TODO debug code that can go away if we find the source of the lingering program location
// being used that causes the program closed exception
private boolean isClosedProgram(Navigatable navigatable, ProgramLocation location) {
Program program = location.getProgram(); Program program = location.getProgram();
FunctionManager functionManager = program.getFunctionManager(); if (program.isClosed()) {
return functionManager.getFunctionContaining(currentAddress);
Msg.showError(this, null, "Closed Program",
"The Navigation History Plugin is using a closed program.\n" + "Program: " +
program.getName() + "Navigatable: " +
navigatable.getClass().getSimpleName() + "\n" + "Location: " +
location.getClass().getSimpleName() + " @ " + location.getAddress());
return true;
}
return false;
} }
void remove(LocationMemento location) { void remove(LocationMemento location) {

View file

@ -30,28 +30,17 @@ import ghidra.util.SystemUtilities;
/** /**
* Visible Plugin to show ByteBlock data in various formats. * Visible Plugin to show ByteBlock data in various formats.
*/ */
@PluginInfo( @PluginInfo(status = PluginStatus.RELEASED, packageName = CorePluginPackage.NAME, category = PluginCategoryNames.BYTE_VIEWER, shortDescription = "Displays bytes in memory", description = "Provides a component for showing the bytes in memory. " +
status = PluginStatus.RELEASED,
packageName = CorePluginPackage.NAME,
category = PluginCategoryNames.BYTE_VIEWER,
shortDescription = "Displays bytes in memory",
description = "Provides a component for showing the bytes in memory. " +
"Additional plugins provide capabilites for this plugin" + "Additional plugins provide capabilites for this plugin" +
" to show the bytes in various formats (e.g., hex, octal, decimal)." + " to show the bytes in various formats (e.g., hex, octal, decimal)." +
" The hex format plugin is loaded by default when this plugin is loaded.", " The hex format plugin is loaded by default when this plugin is loaded.", servicesRequired = {
servicesRequired = {
ProgramManager.class, GoToService.class, NavigationHistoryService.class, ProgramManager.class, GoToService.class, NavigationHistoryService.class,
ClipboardService.class, ClipboardService.class, }, eventsConsumed = { ProgramLocationPluginEvent.class,
}, ProgramActivatedPluginEvent.class, ProgramSelectionPluginEvent.class,
eventsConsumed = { ProgramHighlightPluginEvent.class, ProgramClosedPluginEvent.class,
ProgramLocationPluginEvent.class, ProgramActivatedPluginEvent.class, ByteBlockChangePluginEvent.class, }, eventsProduced = {
ProgramSelectionPluginEvent.class, ProgramHighlightPluginEvent.class,
ProgramClosedPluginEvent.class, ByteBlockChangePluginEvent.class,
},
eventsProduced = {
ProgramLocationPluginEvent.class, ProgramSelectionPluginEvent.class, ProgramLocationPluginEvent.class, ProgramSelectionPluginEvent.class,
ByteBlockChangePluginEvent.class, ByteBlockChangePluginEvent.class, })
})
public class ByteViewerPlugin extends AbstractByteViewerPlugin<ProgramByteViewerComponentProvider> { public class ByteViewerPlugin extends AbstractByteViewerPlugin<ProgramByteViewerComponentProvider> {
public ByteViewerPlugin(PluginTool tool) { public ByteViewerPlugin(PluginTool tool) {
@ -73,6 +62,7 @@ public class ByteViewerPlugin extends AbstractByteViewerPlugin<ProgramByteViewer
if (event instanceof ProgramActivatedPluginEvent) { if (event instanceof ProgramActivatedPluginEvent) {
currentProgram = ((ProgramActivatedPluginEvent) event).getActiveProgram(); currentProgram = ((ProgramActivatedPluginEvent) event).getActiveProgram();
currentLocation = null;
} }
else if (event instanceof ProgramLocationPluginEvent) { else if (event instanceof ProgramLocationPluginEvent) {
currentLocation = ((ProgramLocationPluginEvent) event).getLocation(); currentLocation = ((ProgramLocationPluginEvent) event).getLocation();
@ -131,8 +121,7 @@ public class ByteViewerPlugin extends AbstractByteViewerPlugin<ProgramByteViewer
} }
@Override @Override
public void highlightChanged(ByteViewerComponentProvider provider, public void highlightChanged(ByteViewerComponentProvider provider, ProgramSelection highlight) {
ProgramSelection highlight) {
if (provider == connectedProvider) { if (provider == connectedProvider) {
tool.firePluginEvent(new ProgramHighlightPluginEvent(getName(), highlight, tool.firePluginEvent(new ProgramHighlightPluginEvent(getName(), highlight,
connectedProvider.getProgram())); connectedProvider.getProgram()));

View file

@ -74,9 +74,15 @@ public class DecompilePlugin extends Plugin {
* or when switching program tabs. * or when switching program tabs.
*/ */
SwingUpdateManager delayedLocationUpdateMgr = new SwingUpdateManager(200, 200, () -> { SwingUpdateManager delayedLocationUpdateMgr = new SwingUpdateManager(200, 200, () -> {
if (currentLocation != null) { if (currentLocation == null) {
connectedProvider.setLocation(currentLocation, null); return;
} }
Program locationProgram = currentLocation.getProgram();
if (locationProgram.isClosed()) {
return; // not sure if this can happen
}
connectedProvider.setLocation(currentLocation, null);
}); });
public DecompilePlugin(PluginTool tool) { public DecompilePlugin(PluginTool tool) {

View file

@ -497,6 +497,13 @@ public class FGProvider extends VisualGraphComponentProvider<FGVertex, FGEdge, F
return; return;
} }
Program program = newLocation.getProgram();
if (program.isClosed()) {
// this method is called from an update manager, which means that the callback may
// happen after the notification that the program was closed
return;
}
setLocationNow(newLocation); setLocationNow(newLocation);
} }