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
@@ -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|
@@ -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
@@ -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

@@ -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() {
@@ -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();
}
@@ -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);
}
@@ -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

@@ -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

@@ -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

@@ -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

@@ -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());