mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-2295 - fixes and debug code for a history actions stack trace
This commit is contained in:
parent
b8425e804d
commit
c8e15f0fe2
6 changed files with 133 additions and 95 deletions
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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,
|
"Additional plugins provide capabilites for this plugin" +
|
||||||
packageName = CorePluginPackage.NAME,
|
" to show the bytes in various formats (e.g., hex, octal, decimal)." +
|
||||||
category = PluginCategoryNames.BYTE_VIEWER,
|
" The hex format plugin is loaded by default when this plugin is loaded.", servicesRequired = {
|
||||||
shortDescription = "Displays bytes in memory",
|
|
||||||
description = "Provides a component for showing the bytes in memory. " +
|
|
||||||
"Additional plugins provide capabilites for this plugin" +
|
|
||||||
" 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.",
|
|
||||||
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,
|
ProgramLocationPluginEvent.class, ProgramSelectionPluginEvent.class,
|
||||||
ProgramClosedPluginEvent.class, ByteBlockChangePluginEvent.class,
|
ByteBlockChangePluginEvent.class, })
|
||||||
},
|
|
||||||
eventsProduced = {
|
|
||||||
ProgramLocationPluginEvent.class, ProgramSelectionPluginEvent.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()));
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue