Merge remote-tracking branch 'origin/GP-4156_Dan_providerSubpanelToggles--SQUASHED'

This commit is contained in:
Ryan Kurtz
2024-01-02 10:31:35 -05:00
16 changed files with 766 additions and 159 deletions

View File

@@ -139,6 +139,9 @@ src/main/resources/images/steplast.png||GHIDRA||||END|
src/main/resources/images/stepout.png||GHIDRA||||END|
src/main/resources/images/stepover.png||GHIDRA||||END|
src/main/resources/images/system-switch-user.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
src/main/resources/images/table-a.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/table-e.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/table-s.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/thread.png||GHIDRA||||END|
src/main/resources/images/time.png||FAMFAMFAM Icons - CC 2.5||||END|
src/main/resources/images/write-emulator.png||GHIDRA||||END|
@@ -189,6 +192,9 @@ src/main/svg/stepinto.svg||GHIDRA||||END|
src/main/svg/steplast.svg||GHIDRA||||END|
src/main/svg/stepout.svg||GHIDRA||||END|
src/main/svg/stepover.svg||GHIDRA||||END|
src/main/svg/table-a.svg||FAMFAMFAM Icons - CC 2.5||||END|
src/main/svg/table-e.svg||FAMFAMFAM Icons - CC 2.5||||END|
src/main/svg/table-s.svg||FAMFAMFAM Icons - CC 2.5||||END|
src/main/svg/thread.svg||GHIDRA||||END|
src/main/svg/write-disabled.svg||GHIDRA||||END|
src/main/svg/write-emulator.svg||GHIDRA||||END|

View File

@@ -63,6 +63,12 @@ color.debugger.plugin.resources.breakpoint.marker.enabled.ineffective = color.pa
color.debugger.plugin.resources.breakpoint.marker.disabled.ineffective = color.debugger.plugin.resources.breakpoint.marker.enabled.ineffective
icon.debugger.model.tree.objects = function_graph.png
icon.debugger.model.table.elements = table-e.png
icon.debugger.model.table.attributes = table-a.png
icon.debugger.modules.table.sections = table-s.png
icon.debugger.object.populated = object-populated.png
icon.debugger.object.unpopulated = object-unpopulated.png

View File

@@ -167,6 +167,12 @@
<P>This action is offered to resolve a "missing module" console message. It is equivalent to <A
href="#map_module_to">Map Module To</A> on the missing module.</P>
<H3><A name="show_sections_table"></A>Show Sections Table</H3>
<P>This actions is always available. By default the sections table (bottom) is showing. Some
debuggers do not offer section information, and even for those that do, it can be expensive to
retrieve it. The visibility of the section table is controlled by toggling this action.</P>
<H3><A name="filter_by_module"></A>Filter Sections by Module</H3>
<P>This action is always available. By default the bottom table displays all sections in the

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -813,40 +813,6 @@ public interface DebuggerResources {
}
}
interface ImportMissingModuleAction {
String NAME = "Import Missing Module";
String DESCRIPTION = "Import the missing module from disk";
Icon ICON = ICON_IMPORT;
String HELP_ANCHOR = "import_missing_module";
static ActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.toolBarIcon(ICON)
.popupMenuIcon(ICON)
.popupMenuPath(NAME)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface MapMissingModuleAction {
String NAME = "Map Missing Module";
String DESCRIPTION = "Map the missing module to an existing import";
Icon ICON = ICON_MAP_MODULES;
String HELP_ANCHOR = "map_missing_module";
static ActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.toolBarIcon(ICON)
.popupMenuIcon(ICON)
.popupMenuPath(NAME)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface FollowsCurrentThreadAction {
String NAME = "Follows Selected Thread";
String DESCRIPTION = "Register tracking follows selected thread (and contents" +
@@ -1864,86 +1830,6 @@ public interface DebuggerResources {
}
}
interface LimitToCurrentSnapAction {
String NAME = "Limit to Current Snap";
String DESCRIPTION = "Choose whether displayed objects must be alive at the current snap";
String GROUP = GROUP_GENERAL;
String HELP_ANCHOR = "limit_to_current_snap";
static ToggleActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ToggleActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.menuPath(NAME)
.menuGroup(GROUP)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface ShowHiddenAction {
String NAME = "Show Hidden";
String DESCRIPTION = "Choose whether to display hidden children";
String GROUP = GROUP_GENERAL;
String HELP_ANCHOR = "show_hidden";
static ToggleActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ToggleActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.menuPath(NAME)
.menuGroup(GROUP)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface ShowPrimitivesInTreeAction {
String NAME = "Show Primitives in Tree";
String DESCRIPTION = "Choose whether to display primitive values in the tree";
String GROUP = GROUP_GENERAL;
String HELP_ANCHOR = "show_primitives";
static ToggleActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ToggleActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.menuPath(NAME)
.menuGroup(GROUP)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface ShowMethodsInTreeAction {
String NAME = "Show Methods in Tree";
String DESCRIPTION = "Choose whether to display methods in the tree";
String GROUP = GROUP_GENERAL;
String HELP_ANCHOR = "show_methods";
static ToggleActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ToggleActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.menuPath(NAME)
.menuGroup(GROUP)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface FollowLinkAction {
String NAME = "Follow Link";
String DESCRIPTION = "Navigate to the link target";
String GROUP = GROUP_GENERAL;
String HELP_ANCHOR = "follow_link";
static ActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.popupMenuPath(NAME)
.popupMenuGroup(GROUP)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
public abstract class AbstractDebuggerConnectionsNode extends GTreeNode {
@Override
public String getName() {

View File

@@ -20,6 +20,7 @@ import java.awt.event.*;
import java.lang.invoke.MethodHandles;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.swing.*;
@@ -27,12 +28,15 @@ import javax.swing.*;
import docking.*;
import docking.action.DockingAction;
import docking.action.ToggleDockingAction;
import docking.action.builder.ActionBuilder;
import docking.action.builder.ToggleActionBuilder;
import docking.widgets.table.RangeCursorTableHeaderRenderer.SeekListener;
import docking.widgets.tree.support.GTreeSelectionEvent.EventOrigin;
import generic.theme.GColor;
import generic.theme.GIcon;
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.*;
import ghidra.app.plugin.core.debug.gui.DebuggerResources.CloneWindowAction;
import ghidra.app.plugin.core.debug.gui.MultiProviderSaveBehavior.SaveableProvider;
import ghidra.app.plugin.core.debug.gui.model.AbstractQueryTablePanel.CellActivationListener;
import ghidra.app.plugin.core.debug.gui.model.ObjectTableModel.ObjectRow;
@@ -42,13 +46,13 @@ import ghidra.app.plugin.core.debug.gui.model.PathTableModel.PathRow;
import ghidra.app.services.DebuggerTraceManagerService;
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.AutoConfigState;
import ghidra.framework.plugintool.AutoService;
import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.annotation.AutoConfigStateField;
import ghidra.framework.plugintool.annotation.AutoServiceConsumed;
import ghidra.trace.model.Lifespan;
import ghidra.trace.model.Trace;
import ghidra.trace.model.target.*;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
public class DebuggerModelProvider extends ComponentProvider implements SaveableProvider {
@@ -59,10 +63,144 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
private static final String KEY_DEBUGGER_COORDINATES = "DebuggerCoordinates";
private static final String KEY_PATH = "Path";
interface ShowObjectsTreeAction {
String NAME = "Show Objects Tree";
Icon ICON = new GIcon("icon.debugger.model.tree.objects");
String DESCRIPTION = "Toggle display of the Objects Tree pane";
String GROUP = DebuggerResources.GROUP_VIEWS;
String ORDER = "1";
String HELP_ANCHOR = "show_objects_tree";
static ToggleActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ToggleActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.toolBarIcon(ICON)
.toolBarGroup(GROUP, ORDER)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface ShowElementsTableAction {
String NAME = "Show Elements Table";
Icon ICON = new GIcon("icon.debugger.model.table.elements");
String DESCRIPTION = "Toggle display of the Elements Table pane";
String GROUP = DebuggerResources.GROUP_VIEWS;
String ORDER = "2";
String HELP_ANCHOR = "show_elements_table";
static ToggleActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ToggleActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.toolBarIcon(ICON)
.toolBarGroup(GROUP, ORDER)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface ShowAttributesTableAction {
String NAME = "Show Attributes Table";
Icon ICON = new GIcon("icon.debugger.model.table.attributes");
String DESCRIPTION = "Toggle display of the Attributes Table pane";
String GROUP = DebuggerResources.GROUP_VIEWS;
String ORDER = "3";
String HELP_ANCHOR = "show_attributes_table";
static ToggleActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ToggleActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.toolBarIcon(ICON)
.toolBarGroup(GROUP, ORDER)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface LimitToCurrentSnapAction {
String NAME = "Limit to Current Snap";
String DESCRIPTION = "Choose whether displayed objects must be alive at the current snap";
String GROUP = DebuggerResources.GROUP_GENERAL;
String HELP_ANCHOR = "limit_to_current_snap";
static ToggleActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ToggleActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.menuPath(NAME)
.menuGroup(GROUP)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface ShowHiddenAction {
String NAME = "Show Hidden";
String DESCRIPTION = "Choose whether to display hidden children";
String GROUP = DebuggerResources.GROUP_GENERAL;
String HELP_ANCHOR = "show_hidden";
static ToggleActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ToggleActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.menuPath(NAME)
.menuGroup(GROUP)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface ShowPrimitivesInTreeAction {
String NAME = "Show Primitives in Tree";
String DESCRIPTION = "Choose whether to display primitive values in the tree";
String GROUP = DebuggerResources.GROUP_GENERAL;
String HELP_ANCHOR = "show_primitives";
static ToggleActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ToggleActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.menuPath(NAME)
.menuGroup(GROUP)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface ShowMethodsInTreeAction {
String NAME = "Show Methods in Tree";
String DESCRIPTION = "Choose whether to display methods in the tree";
String GROUP = DebuggerResources.GROUP_GENERAL;
String HELP_ANCHOR = "show_methods";
static ToggleActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ToggleActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.menuPath(NAME)
.menuGroup(GROUP)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface FollowLinkAction {
String NAME = "Follow Link";
String DESCRIPTION = "Navigate to the link target";
String GROUP = DebuggerResources.GROUP_GENERAL;
String HELP_ANCHOR = "follow_link";
static ActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.popupMenuPath(NAME)
.popupMenuGroup(GROUP)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
private final DebuggerModelPlugin plugin;
private final boolean isClone;
private JPanel mainPanel = new JPanel(new BorderLayout());
private JPanel mainPanel;
static class MyTextField extends JTextField {
// This one can be reflected for testing
@@ -74,6 +212,7 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
protected MyTextField pathField;
protected JButton goButton;
protected JPanel queryPanel;
protected ObjectsTreePanel objectsTreePanel;
protected ObjectsTablePanel elementsTablePanel;
protected PathsTablePanel attributesTablePanel;
@@ -86,6 +225,17 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
@SuppressWarnings("unused")
private final AutoService.Wiring autoServiceWiring;
@AutoConfigStateField
private boolean showObjectsTree = true;
@AutoConfigStateField
private boolean showElementsTable = true;
@AutoConfigStateField
private boolean showAttributesTable = true;
@AutoConfigStateField
private double lrResizeWeight = 0.2;
@AutoConfigStateField
private double tbResizeWeight = 0.7;
@AutoConfigStateField
private boolean limitToSnap = true;
@AutoConfigStateField
@@ -96,6 +246,9 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
private boolean showMethodsInTree = false;
DockingAction actionCloneWindow;
ToggleDockingAction actionShowObjectsTree;
ToggleDockingAction actionShowElementsTable;
ToggleDockingAction actionShowAttributesTable;
ToggleDockingAction actionLimitToCurrentSnap;
ToggleDockingAction actionShowHidden;
ToggleDockingAction actionShowPrimitivesInTree;
@@ -156,7 +309,117 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
super.removeFromTool();
}
protected static double computeResizeWeight(JSplitPane split) {
Function<Dimension, Integer> axis = switch (split.getOrientation()) {
case JSplitPane.HORIZONTAL_SPLIT -> (dim -> dim.width);
case JSplitPane.VERTICAL_SPLIT -> (dim -> dim.height);
default -> throw new AssertionError();
};
// This method is off by a little, and I don't know why, but I don't care.
Component lComp = split.getLeftComponent();
int lMin = axis.apply(lComp.getMinimumSize());
int lSize = axis.apply(lComp.getSize());
Component rComp = split.getRightComponent();
int rMin = axis.apply(rComp.getMinimumSize());
int rSize = axis.apply(rComp.getSize());
int totalExtra = lSize + rSize - lMin - rMin;
int lExtra = lSize - lMin;
return (double) lExtra / totalExtra;
}
protected JSplitPane createLrSplit() {
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
split.setResizeWeight(lrResizeWeight);
split.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, pce -> {
lrResizeWeight = computeResizeWeight(split);
});
return split;
}
protected JSplitPane createTbSplit() {
JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
split.setResizeWeight(tbResizeWeight);
split.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, pce -> {
tbResizeWeight = computeResizeWeight(split);
});
return split;
}
protected JPanel createLabeledElementsTable() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(elementsTablePanel);
panel.add(new JLabel("Elements"), BorderLayout.NORTH);
return panel;
}
protected JPanel createLabeledAttributesTable() {
JPanel panel = new JPanel(new BorderLayout());
panel.add(attributesTablePanel);
panel.add(new JLabel("Attributes"), BorderLayout.NORTH);
return panel;
}
protected void rebuildPanels() {
if (mainPanel == null) {
return;
}
try (ListenerSuppressor suppressor = objectsTreePanel.suppressShowingListener()) {
mainPanel.removeAll();
mainPanel.add(queryPanel, BorderLayout.NORTH);
if (showObjectsTree && showElementsTable && showAttributesTable) {
JSplitPane lrSplit = createLrSplit();
mainPanel.add(lrSplit, BorderLayout.CENTER);
JSplitPane tbSplit = createTbSplit();
lrSplit.setRightComponent(tbSplit);
lrSplit.setLeftComponent(objectsTreePanel);
tbSplit.setLeftComponent(createLabeledElementsTable());
tbSplit.setRightComponent(createLabeledAttributesTable());
}
else if (showObjectsTree && showElementsTable) {
JSplitPane lrSplit = createLrSplit();
mainPanel.add(lrSplit, BorderLayout.CENTER);
lrSplit.setLeftComponent(objectsTreePanel);
lrSplit.setRightComponent(elementsTablePanel);
}
else if (showObjectsTree && showAttributesTable) {
JSplitPane lrSplit = createLrSplit();
mainPanel.add(lrSplit, BorderLayout.CENTER);
lrSplit.setLeftComponent(objectsTreePanel);
lrSplit.setRightComponent(attributesTablePanel);
}
else if (showElementsTable && showAttributesTable) {
JSplitPane tbSplit = createTbSplit();
tbSplit.setLeftComponent(createLabeledElementsTable());
tbSplit.setRightComponent(createLabeledAttributesTable());
mainPanel.add(tbSplit, BorderLayout.CENTER);
}
else if (showObjectsTree) {
mainPanel.add(objectsTreePanel);
}
else if (showElementsTable) {
mainPanel.add(elementsTablePanel);
}
else if (showAttributesTable) {
mainPanel.add(attributesTablePanel);
}
else {
// The actions should not allow this, but in case it happens, help the user out.
mainPanel.add(new JLabel("""
<html>Well, you should probably enable at least one panel.
Use the local toolbar buttons."""));
}
}
mainPanel.revalidate();
}
protected void buildMainPanel() {
mainPanel = new JPanel(new BorderLayout());
pathField = new MyTextField();
pathField.setInputVerifier(new InputVerifier() {
@Override
@@ -207,27 +470,12 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
tbSplit.setResizeWeight(0.7);
lrSplit.setRightComponent(tbSplit);
JPanel queryPanel = new JPanel(new BorderLayout());
queryPanel = new JPanel(new BorderLayout());
queryPanel.add(new JLabel("Path: "), BorderLayout.WEST);
queryPanel.add(pathField, BorderLayout.CENTER);
queryPanel.add(goButton, BorderLayout.EAST);
JPanel labeledElementsTablePanel = new JPanel(new BorderLayout());
labeledElementsTablePanel.add(elementsTablePanel);
labeledElementsTablePanel.add(new JLabel("Elements"), BorderLayout.NORTH);
JPanel labeledAttributesTablePanel = new JPanel(new BorderLayout());
labeledAttributesTablePanel.add(attributesTablePanel);
labeledAttributesTablePanel.add(new JLabel("Attributes"), BorderLayout.NORTH);
lrSplit.setLeftComponent(objectsTreePanel);
tbSplit.setLeftComponent(labeledElementsTablePanel);
tbSplit.setRightComponent(labeledAttributesTablePanel);
mainPanel.add(queryPanel, BorderLayout.NORTH);
mainPanel.add(lrSplit, BorderLayout.CENTER);
objectsTreePanel.addTreeSelectionListener(evt -> {
Trace trace = current.getTrace();
if (trace == null) {
@@ -240,6 +488,7 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
if (!sel.isEmpty()) {
myActionContext = new DebuggerObjectActionContext(sel.stream()
.map(n -> n.getValue())
.filter(o -> o != null) // Root for no trace would return null
.collect(Collectors.toList()),
this, objectsTreePanel);
}
@@ -251,7 +500,8 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
return;
}
TraceObjectValue value = sel.get(0).getValue();
setPath(value.getCanonicalPath(), objectsTreePanel);
setPath(value == null ? TraceObjectKeyPath.of() : value.getCanonicalPath(),
objectsTreePanel);
});
objectsTreePanel.tree.addMouseListener(new MouseAdapter() {
@Override
@@ -320,6 +570,8 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
elementsTablePanel.addSeekListener(seekListener);
attributesTablePanel.addSeekListener(seekListener);
rebuildPanels();
}
private void activateObjectSelectedInTree() {
@@ -348,6 +600,18 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
.enabledWhen(c -> current.getTrace() != null)
.onAction(c -> activatedCloneWindow())
.buildAndInstallLocal(this);
actionShowObjectsTree = ShowObjectsTreeAction.builder(plugin)
.onAction(this::toggledShowObjectsTree)
.selected(showObjectsTree)
.buildAndInstallLocal(this);
actionShowElementsTable = ShowElementsTableAction.builder(plugin)
.onAction(this::toggledShowElementsTable)
.selected(showElementsTable)
.buildAndInstallLocal(this);
actionShowAttributesTable = ShowAttributesTableAction.builder(plugin)
.onAction(this::toggledShowAttributesTable)
.selected(showAttributesTable)
.buildAndInstallLocal(this);
actionLimitToCurrentSnap = LimitToCurrentSnapAction.builder(plugin)
.onAction(this::toggledLimitToCurrentSnap)
.buildAndInstallLocal(this);
@@ -404,6 +668,18 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
plugin.getTool().showComponentProvider(clone, true);
}
private void toggledShowObjectsTree(ActionContext ctx) {
setShowObjectsTree(actionShowObjectsTree.isSelected());
}
private void toggledShowElementsTable(ActionContext ctx) {
setShowElementsTable(actionShowElementsTable.isSelected());
}
private void toggledShowAttributesTable(ActionContext ctx) {
setShowAttributesTable(actionShowAttributesTable.isSelected());
}
private void toggledLimitToCurrentSnap(ActionContext ctx) {
setLimitToCurrentSnap(actionLimitToCurrentSnap.isSelected());
}
@@ -496,8 +772,6 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
elementsTablePanel.goToCoordinates(coords);
attributesTablePanel.goToCoordinates(coords);
checkPath();
if (isClone) {
return;
}
@@ -549,6 +823,7 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
traceManager.activateObject(object);
return;
}
plugin.getTool().setStatusInfo("No such object at path " + path, true);
}
}
@@ -566,27 +841,55 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
objectsTreePanel.repaint();
elementsTablePanel.setQuery(ModelQuery.elementsOf(path));
attributesTablePanel.setQuery(ModelQuery.attributesOf(path));
checkPath();
}
public void setPath(TraceObjectKeyPath path) {
setPath(path, null);
}
protected void checkPath() {
if (Trace.isLegacy(current.getTrace())) {
return;
}
if (objectsTreePanel.getNode(path) == null) {
plugin.getTool().setStatusInfo("No such object at path " + path, true);
}
}
public TraceObjectKeyPath getPath() {
return path;
}
protected void doSetShowObjectsTree(boolean showObjectsTree) {
this.showObjectsTree = showObjectsTree;
actionShowObjectsTree.setSelected(showObjectsTree);
rebuildPanels();
}
protected void doSetShowElementsTable(boolean showElementsTable) {
this.showElementsTable = showElementsTable;
actionShowElementsTable.setSelected(showElementsTable);
rebuildPanels();
}
protected void doSetShowAttributesTable(boolean showAttributesTable) {
this.showAttributesTable = showAttributesTable;
actionShowAttributesTable.setSelected(showAttributesTable);
rebuildPanels();
}
public void setShowObjectsTree(boolean showObjectsTree) {
if (this.showObjectsTree == showObjectsTree) {
return;
}
doSetShowObjectsTree(showObjectsTree);
}
public void setShowElementsTable(boolean showElementsTable) {
if (this.showElementsTable == showElementsTable) {
return;
}
doSetShowElementsTable(showElementsTable);
}
public void setShowAttributesTable(boolean showAttributesTable) {
if (this.showAttributesTable == showAttributesTable) {
return;
}
doSetShowAttributesTable(showAttributesTable);
}
protected void doSetLimitToCurrentSnap(boolean limitToSnap) {
this.limitToSnap = limitToSnap;
actionLimitToCurrentSnap.setSelected(limitToSnap);
@@ -680,6 +983,12 @@ public class DebuggerModelProvider extends ComponentProvider implements Saveable
@Override
public void readConfigState(SaveState saveState) {
CONFIG_STATE_HANDLER.readConfigState(this, saveState);
actionShowObjectsTree.setSelected(showObjectsTree);
actionShowElementsTable.setSelected(showElementsTable);
actionShowAttributesTable.setSelected(showAttributesTable);
rebuildPanels();
doSetLimitToCurrentSnap(limitToSnap);
doSetShowHidden(showHidden);
doSetShowPrimitivesInTree(showPrimitivesInTree);

View File

@@ -0,0 +1,21 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.core.debug.gui.model;
public interface ListenerSuppressor extends AutoCloseable {
@Override
void close();
}

View File

@@ -22,6 +22,8 @@ import java.util.stream.*;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.tree.TreePath;
import docking.widgets.tree.GTree;
@@ -95,10 +97,55 @@ public class ObjectsTreePanel extends JPanel {
}
}
protected class ListenerForShowing implements AncestorListener {
boolean showing = false;
@Override
public void ancestorRemoved(AncestorEvent event) {
updateShowing();
}
@Override
public void ancestorMoved(AncestorEvent event) {
updateShowing();
}
@Override
public void ancestorAdded(AncestorEvent event) {
updateShowing();
}
public void updateShowing() {
setShowing(ObjectsTreePanel.this.isShowing());
}
private void setShowing(boolean showing) {
if (this.showing == showing) {
return;
}
this.showing = showing;
showingChanged(showing);
}
}
protected class ListenerForShowingSuppressor implements ListenerSuppressor {
public ListenerForShowingSuppressor() {
removeAncestorListener(listenerForShowing);
}
@Override
public void close() {
addAncestorListener(listenerForShowing);
listenerForShowing.updateShowing();
}
}
protected final ObjectTreeModel treeModel;
protected final ObjectGTree tree;
protected boolean showing = false;
protected DebuggerCoordinates current = DebuggerCoordinates.NOWHERE;
protected DebuggerCoordinates previous = DebuggerCoordinates.NOWHERE;
protected boolean limitToSnap = true;
protected boolean showHidden = false;
protected boolean showPrimitives = false;
@@ -107,8 +154,13 @@ public class ObjectsTreePanel extends JPanel {
protected Color diffColor = DebuggerResources.COLOR_VALUE_CHANGED;
protected Color diffColorSel = DebuggerResources.COLOR_VALUE_CHANGED_SEL;
protected final ListenerForShowing listenerForShowing = new ListenerForShowing();
public ObjectsTreePanel() {
super(new BorderLayout());
addAncestorListener(listenerForShowing);
treeModel = createModel();
tree = new ObjectGTree(treeModel.getRoot());
@@ -116,6 +168,10 @@ public class ObjectsTreePanel extends JPanel {
add(tree, BorderLayout.CENTER);
}
public ListenerSuppressor suppressShowingListener() {
return new ListenerForShowingSuppressor();
}
protected ObjectTreeModel createModel() {
return new ObjectTreeModel();
}
@@ -124,6 +180,20 @@ public class ObjectsTreePanel extends JPanel {
return new KeepTreeState(tree);
}
protected void showingChanged(boolean showing) {
this.showing = showing;
updateTreeModelForCoordinates();
updateTreeModelForSpan();
updateTreeModelForShowHidden();
updateTreeModelForShowPrimitives();
updateTreeModelForShowMethods();
if (showing) {
// Not going to restore the actual selection
selectCurrent();
}
// Restore expansion? Nah.
}
protected Trace computeDiffTrace(Trace current, Trace previous) {
if (current == null) {
return null;
@@ -138,13 +208,22 @@ public class ObjectsTreePanel extends JPanel {
if (DebuggerCoordinates.equalsIgnoreRecorderAndView(current, coords)) {
return;
}
DebuggerCoordinates previous = current;
this.current = coords;
previous = current;
current = coords;
if (previous.getSnap() == current.getSnap() &&
previous.getTrace() == current.getTrace() &&
previous.getObject() == current.getObject()) {
return;
}
updateTreeModelForCoordinates();
}
protected void updateTreeModelForCoordinates() {
if (!showing) {
// Clear it out and have it remove its listeners
treeModel.setTrace(null);
return;
}
try (KeepTreeState keep = keepTreeState()) {
treeModel.setDiffTrace(computeDiffTrace(current.getTrace(), previous.getTrace()));
treeModel.setTrace(current.getTrace());
@@ -163,6 +242,13 @@ public class ObjectsTreePanel extends JPanel {
return;
}
this.limitToSnap = limitToSnap;
updateTreeModelForSpan();
}
protected void updateTreeModelForSpan() {
if (!showing) {
return;
}
try (KeepTreeState keep = keepTreeState()) {
treeModel.setSpan(limitToSnap ? Lifespan.at(current.getSnap()) : Lifespan.ALL);
}
@@ -177,6 +263,13 @@ public class ObjectsTreePanel extends JPanel {
return;
}
this.showHidden = showHidden;
updateTreeModelForShowHidden();
}
protected void updateTreeModelForShowHidden() {
if (!showing) {
return;
}
try (KeepTreeState keep = keepTreeState()) {
treeModel.setShowHidden(showHidden);
}
@@ -191,6 +284,13 @@ public class ObjectsTreePanel extends JPanel {
return;
}
this.showPrimitives = showPrimitives;
updateTreeModelForShowPrimitives();
}
protected void updateTreeModelForShowPrimitives() {
if (!showing) {
return;
}
try (KeepTreeState keep = keepTreeState()) {
treeModel.setShowPrimitives(showPrimitives);
}
@@ -205,6 +305,13 @@ public class ObjectsTreePanel extends JPanel {
return;
}
this.showMethods = showMethods;
updateTreeModelForShowMethods();
}
protected void updateTreeModelForShowMethods() {
if (!showing) {
return;
}
try (KeepTreeState keep = keepTreeState()) {
treeModel.setShowMethods(showMethods);
}

View File

@@ -28,12 +28,12 @@ import org.apache.commons.lang3.ArrayUtils;
import docking.*;
import docking.action.*;
import docking.action.builder.ActionBuilder;
import docking.action.builder.MultiStateActionBuilder;
import docking.action.builder.*;
import docking.menu.ActionState;
import docking.menu.MultiStateDockingAction;
import docking.widgets.EventTrigger;
import docking.widgets.filechooser.GhidraFileChooser;
import generic.theme.GIcon;
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
import ghidra.app.plugin.core.debug.gui.DebuggerBlockChooserDialog;
import ghidra.app.plugin.core.debug.gui.DebuggerResources;
@@ -217,6 +217,58 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
}
}
interface ImportMissingModuleAction {
String NAME = "Import Missing Module";
String DESCRIPTION = "Import the missing module from disk";
Icon ICON = DebuggerResources.ICON_IMPORT;
String HELP_ANCHOR = "import_missing_module";
static ActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.toolBarIcon(ICON)
.popupMenuIcon(ICON)
.popupMenuPath(NAME)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface MapMissingModuleAction {
String NAME = "Map Missing Module";
String DESCRIPTION = "Map the missing module to an existing import";
Icon ICON = DebuggerResources.ICON_MAP_MODULES;
String HELP_ANCHOR = "map_missing_module";
static ActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.toolBarIcon(ICON)
.popupMenuIcon(ICON)
.popupMenuPath(NAME)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
interface ShowSectionsTableAction {
String NAME = "Show Sections Table";
Icon ICON = new GIcon("icon.debugger.modules.table.sections");
String DESCRIPTION = "Toggle display fo the Sections Table pane";
String GROUP = DebuggerResources.FilterAction.GROUP;
String ORDER = "1";
String HELP_ANCHOR = "show_sections_table";
static ToggleActionBuilder builder(Plugin owner) {
String ownerName = owner.getName();
return new ToggleActionBuilder(NAME, ownerName)
.description(DESCRIPTION)
.toolBarIcon(ICON)
.toolBarGroup(GROUP, ORDER)
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
}
}
protected class ForMappingTraceListener extends TraceDomainObjectListener {
public ForMappingTraceListener(AutoMapSpec spec) {
for (TraceChangeType<?, ?> type : spec.getChangeTypes()) {
@@ -369,6 +421,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
private final AutoService.Wiring autoServiceWiring;
private final JSplitPane mainPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
private final int defaultDividerSize = mainPanel.getDividerSize();
DebuggerModulesPanel modulesPanel;
DebuggerLegacyModulesPanel legacyModulesPanel;
@@ -397,8 +450,14 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
MultiStateDockingAction<AutoMapSpec> actionAutoMap;
private final AutoMapSpec defaultAutoMapSpec =
AutoMapSpec.fromConfigName(ByModuleAutoMapSpec.CONFIG_NAME);
@AutoConfigStateField(codec = AutoMapSpecConfigFieldCodec.class)
AutoMapSpec autoMapSpec = defaultAutoMapSpec;
@AutoConfigStateField
boolean showSectionsTable = true;
@AutoConfigStateField
boolean filterSectionsByModules = false;
boolean cueAutoMap;
private ForMappingTraceListener forMappingListener;
@@ -407,6 +466,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
SelectAddressesAction actionSelectAddresses;
ImportFromFileSystemAction actionImportFromFileSystem;
ToggleDockingAction actionShowSectionsTable;
// TODO: Save the state of this toggle? Not really compelled.
ToggleDockingAction actionFilterSectionsByModules;
DockingAction actionSelectCurrent;
@@ -481,8 +541,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
}
protected boolean isFilterSectionsByModules() {
// TODO: Make this a proper field and save it to tool state
return actionFilterSectionsByModules.isSelected();
return filterSectionsByModules;
}
void modulesPanelContextChanged() {
@@ -576,6 +635,10 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
actionSelectAddresses = new SelectAddressesAction();
actionImportFromFileSystem = new ImportFromFileSystemAction();
actionShowSectionsTable = ShowSectionsTableAction.builder(plugin)
.onAction(this::toggledShowSectionsTable)
.selected(showSectionsTable)
.buildAndInstallLocal(this);
actionFilterSectionsByModules = FilterAction.builder(plugin)
.description("Filter sections to those in selected modules")
.helpLocation(new HelpLocation(plugin.getName(), "filter_by_module"))
@@ -714,10 +777,42 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
mapModuleTo(context.getModule());
}
private void toggledShowSectionsTable(ActionContext ignored) {
setShowSectionsTable(actionShowSectionsTable.isSelected());
}
public void setShowSectionsTable(boolean showSectionsTable) {
if (this.showSectionsTable == showSectionsTable) {
return;
}
doSetShowSectionsTable(showSectionsTable);
}
protected void doSetShowSectionsTable(boolean showSectionsTable) {
this.showSectionsTable = showSectionsTable;
actionShowSectionsTable.setSelected(showSectionsTable);
mainPanel.setDividerSize(showSectionsTable ? defaultDividerSize : 0);
sectionsPanel.setVisible(showSectionsTable);
legacySectionsPanel.setVisible(showSectionsTable);
mainPanel.resetToPreferredSizes();
}
private void toggledFilter(ActionContext ignored) {
boolean filtered = isFilterSectionsByModules();
sectionsPanel.setFilteredBySelectedModules(filtered);
legacySectionsPanel.setFilteredBySelectedModules(filtered);
setFilterSectionsByModules(actionFilterSectionsByModules.isSelected());
}
public void setFilterSectionsByModules(boolean filterSectionsByModules) {
if (this.filterSectionsByModules == filterSectionsByModules) {
return;
}
doSetFilterSectionsByModules(filterSectionsByModules);
}
protected void doSetFilterSectionsByModules(boolean filterSectionsByModules) {
this.filterSectionsByModules = filterSectionsByModules;
actionFilterSectionsByModules.setSelected(filterSectionsByModules);
sectionsPanel.setFilteredBySelectedModules(filterSectionsByModules);
legacySectionsPanel.setFilteredBySelectedModules(filterSectionsByModules);
}
private void activatedSelectCurrent(ActionContext ignored) {
@@ -1111,5 +1206,7 @@ public class DebuggerModulesProvider extends ComponentProviderAdapter {
public void readConfigState(SaveState saveState) {
CONFIG_STATE_HANDLER.readConfigState(this, saveState);
actionAutoMap.setCurrentActionStateByUserData(autoMapSpec);
doSetFilterSectionsByModules(filterSectionsByModules);
doSetShowSectionsTable(showSectionsTable);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 16 16"
height="16"
width="16"
id="svg2"
version="1.1">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6" />
<image
y="0"
x="0"
id="image10"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHk
m9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1z
ztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wG
hGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUH
YJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWl
uUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhN
TWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7n
HADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGF
rwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=
"
preserveAspectRatio="none"
height="16"
width="16" />
<text
id="text838"
y="11.888021"
x="3.8723958"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:10.66666698px"
y="11.888021"
x="3.8723958"
id="tspan836">A</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 16 16"
height="16"
width="16"
id="svg2"
version="1.1">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6" />
<image
y="0"
x="0"
id="image10"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHk
m9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1z
ztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wG
hGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUH
YJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWl
uUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhN
TWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7n
HADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGF
rwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=
"
preserveAspectRatio="none"
height="16"
width="16" />
<text
id="text838"
y="11.888021"
x="4.2578125"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:10.66666698px"
y="11.888021"
x="4.2578125"
id="tspan836">E</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 16 16"
height="16"
width="16"
id="svg2"
version="1.1">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6" />
<image
y="0"
x="0"
id="image10"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0
U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHISURBVDjLpVPNK0RRFP+9D98syMwUspHk
m9I0YkFZWBFKkZ0s7a3Ewh+ilChK7FgoZCJFKYlYKB8zk2+Z5t0P577He29kQU7dd+6575zf+d1z
ztWklPiPmOozt/U4SThjXIoyIQS4AJjSXO0lGGlvcXAm6Vzsz4xUhm0AIeX4QLig+C+ZpxbOG1wG
hGYHr1zMUmZGWRgs0ha3PE1nX/8mWmdgWTzLB+DUYbhm9FfZ35IEyrhXA3VXJfPbsV8B9LQUIeUH
YJ8ASobag1jcucNgW8g9W4reYSDi2YnnZDoDiwCokDANct6NwTB0LEdj0HRA/wxa2SN25JNBEdWl
uUhZ366gqmAaGvrCAXKOozccTGPgt8+vn8GYSGcgyTYp3dpBnBg42nbQPRBTo5bTvqYkmxL6AQhN
TWQGBXY3B7BxlEBXozcW64dxRKoKUZBju+P06gl5WaaviMJBM3TNDlbypemIZgHYOnlwASsCmW7n
HADGnBoQ3c76YmweJ9BR5zFYjsbRHwm4tmJg6PhWA7pCXXk+bu7fURHKweXtq/sWaksz7SC/CCGF
rwtyZ3r+rCnFRZ7qr1qc6mLZj4f9OEyPL8lVpbX/PucPv5QPKHB1TdEAAAAASUVORK5CYII=
"
preserveAspectRatio="none"
height="16"
width="16" />
<text
id="text838"
y="11.882812"
x="4.1666665"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
xml:space="preserve"><tspan
style="font-weight:bold;font-size:10.66666698px"
y="11.882812"
x="4.1666665"
id="tspan836">S</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -117,6 +117,7 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
public void setUpModelProviderTest() throws Exception {
modelPlugin = addPlugin(tool, DebuggerModelPlugin.class);
modelProvider = waitForComponentProvider(DebuggerModelProvider.class);
modelProvider.setLimitToCurrentSnap(false);
}
@After
@@ -343,12 +344,12 @@ public class DebuggerModelProviderTest extends AbstractGhidraHeadedDebuggerTest
}
@Test
public void testSetPathNoExist() throws Throwable {
public void testActivatePathNoExist() throws Throwable {
createTraceAndPopulateObjects();
traceManager.activateTrace(tb.trace);
waitForSwing();
modelProvider.setPath(TraceObjectKeyPath.parse("Processes[0].NoSuch"));
modelProvider.activatePath(TraceObjectKeyPath.parse("Processes[0].NoSuch"));
waitForTasks();
assertEquals("No such object at path Processes[0].NoSuch", tool.getStatusInfo());