mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-506: Implemented trace management actions for "Debugger" menu.
This commit is contained in:
parent
8201baef2b
commit
077192c301
8 changed files with 257 additions and 30 deletions
|
@ -1174,13 +1174,100 @@ public interface DebuggerResources {
|
||||||
|
|
||||||
static ToggleActionBuilder builder(Plugin owner) {
|
static ToggleActionBuilder builder(Plugin owner) {
|
||||||
String ownerName = owner.getName();
|
String ownerName = owner.getName();
|
||||||
return new ToggleActionBuilder(NAME, ownerName).description(DESCRIPTION)
|
return new ToggleActionBuilder(NAME, ownerName)
|
||||||
|
.description(DESCRIPTION)
|
||||||
.toolBarGroup(GROUP)
|
.toolBarGroup(GROUP)
|
||||||
.toolBarIcon(ICON)
|
.toolBarIcon(ICON)
|
||||||
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface OpenTraceAction {
|
||||||
|
String NAME = "Open Trace";
|
||||||
|
String DESCRIPTION = "Open a trace from the project";
|
||||||
|
String GROUP = GROUP_TRACE;
|
||||||
|
Icon ICON = ICON_TRACE;
|
||||||
|
String HELP_ANCHOR = "open_trace";
|
||||||
|
|
||||||
|
static ActionBuilder builder(Plugin owner) {
|
||||||
|
String ownerName = owner.getName();
|
||||||
|
return new ActionBuilder(NAME, ownerName)
|
||||||
|
.description(DESCRIPTION)
|
||||||
|
.menuGroup(GROUP)
|
||||||
|
.menuIcon(ICON)
|
||||||
|
.menuPath(DebuggerPluginPackage.NAME, NAME)
|
||||||
|
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CloseTraceAction {
|
||||||
|
String NAME_PREFIX = "Close ";
|
||||||
|
String DESCRIPTION = "Close the current trace";
|
||||||
|
String GROUP = GROUP_TRACE;
|
||||||
|
Icon ICON = ICON_CLOSE;
|
||||||
|
String HELP_ANCHOR = "close_trace";
|
||||||
|
|
||||||
|
static ActionBuilder builder(Plugin owner) {
|
||||||
|
String ownerName = owner.getName();
|
||||||
|
return new ActionBuilder(NAME_PREFIX, ownerName)
|
||||||
|
.description(DESCRIPTION)
|
||||||
|
.menuGroup(GROUP)
|
||||||
|
.menuIcon(ICON)
|
||||||
|
.menuPath(DebuggerPluginPackage.NAME, NAME_PREFIX + "...")
|
||||||
|
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CloseAllTracesAction extends CloseTraceAction {
|
||||||
|
String NAME = NAME_PREFIX + " All Traces";
|
||||||
|
String DESCRIPTION = "Close all traces";
|
||||||
|
String HELP_ANCHOR = "close_all_traces";
|
||||||
|
|
||||||
|
static ActionBuilder builder(Plugin owner) {
|
||||||
|
String ownerName = owner.getName();
|
||||||
|
return new ActionBuilder(NAME, ownerName)
|
||||||
|
.description(DESCRIPTION)
|
||||||
|
.menuGroup(GROUP)
|
||||||
|
.menuIcon(ICON)
|
||||||
|
.menuPath(DebuggerPluginPackage.NAME, NAME)
|
||||||
|
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CloseOtherTracesAction extends CloseTraceAction {
|
||||||
|
String NAME = NAME_PREFIX + " Other Traces";
|
||||||
|
String DESCRIPTION = "Close all traces except the current one";
|
||||||
|
String HELP_ANCHOR = "close_other_traces";
|
||||||
|
|
||||||
|
static ActionBuilder builder(Plugin owner) {
|
||||||
|
String ownerName = owner.getName();
|
||||||
|
return new ActionBuilder(NAME, ownerName)
|
||||||
|
.description(DESCRIPTION)
|
||||||
|
.menuGroup(GROUP)
|
||||||
|
.menuIcon(ICON)
|
||||||
|
.menuPath(DebuggerPluginPackage.NAME, NAME)
|
||||||
|
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CloseDeadTracesAction extends CloseTraceAction {
|
||||||
|
String NAME = NAME_PREFIX + " Dead Traces";
|
||||||
|
String DESCRIPTION = "Close all traces not being recorded";
|
||||||
|
String HELP_ANCHOR = "close_dead_traces";
|
||||||
|
|
||||||
|
static ActionBuilder builder(Plugin owner) {
|
||||||
|
String ownerName = owner.getName();
|
||||||
|
return new ActionBuilder(NAME, ownerName)
|
||||||
|
.description(DESCRIPTION)
|
||||||
|
.menuGroup(GROUP)
|
||||||
|
.menuIcon(ICON)
|
||||||
|
.menuPath(DebuggerPluginPackage.NAME, NAME)
|
||||||
|
.helpLocation(new HelpLocation(ownerName, HELP_ANCHOR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class AbstractDebuggerConnectionsNode extends GTreeNode {
|
public abstract class AbstractDebuggerConnectionsNode extends GTreeNode {
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
|
|
@ -221,7 +221,7 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter implements
|
||||||
ExportAsFactsAction exportAsFactsAction;
|
ExportAsFactsAction exportAsFactsAction;
|
||||||
ImportFromXMLAction importFromXMLAction;
|
ImportFromXMLAction importFromXMLAction;
|
||||||
ImportFromFactsAction importFromFactsAction;
|
ImportFromFactsAction importFromFactsAction;
|
||||||
OpenTraceAction openTraceAction;
|
OpenWinDbgTraceAction openTraceAction;
|
||||||
|
|
||||||
private ToggleDockingAction actionToggleSubscribe;
|
private ToggleDockingAction actionToggleSubscribe;
|
||||||
private ToggleDockingAction actionToggleAutoRecord;
|
private ToggleDockingAction actionToggleAutoRecord;
|
||||||
|
@ -1166,7 +1166,7 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter implements
|
||||||
exportAsFactsAction = new ExportAsFactsAction(tool, plugin.getName(), this);
|
exportAsFactsAction = new ExportAsFactsAction(tool, plugin.getName(), this);
|
||||||
importFromXMLAction = new ImportFromXMLAction(tool, plugin.getName(), this);
|
importFromXMLAction = new ImportFromXMLAction(tool, plugin.getName(), this);
|
||||||
importFromFactsAction = new ImportFromFactsAction(tool, plugin.getName(), this);
|
importFromFactsAction = new ImportFromFactsAction(tool, plugin.getName(), this);
|
||||||
openTraceAction = new OpenTraceAction(tool, plugin.getName(), this);
|
openTraceAction = new OpenWinDbgTraceAction(tool, plugin.getName(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
|
@ -40,12 +40,12 @@ import ghidra.framework.plugintool.PluginTool;
|
||||||
import ghidra.util.HelpLocation;
|
import ghidra.util.HelpLocation;
|
||||||
import resources.ResourceManager;
|
import resources.ResourceManager;
|
||||||
|
|
||||||
public class OpenTraceAction extends ImportExportAsAction {
|
public class OpenWinDbgTraceAction extends ImportExportAsAction {
|
||||||
|
|
||||||
protected ImageIcon ICON_TRACE = ResourceManager.loadImage("images/text-xml.png");
|
protected ImageIcon ICON_TRACE = ResourceManager.loadImage("images/text-xml.png");
|
||||||
private ActionContext context;
|
private ActionContext context;
|
||||||
|
|
||||||
public OpenTraceAction(PluginTool tool, String owner, DebuggerObjectsProvider provider) {
|
public OpenWinDbgTraceAction(PluginTool tool, String owner, DebuggerObjectsProvider provider) {
|
||||||
super("OpenTrace", tool, owner, provider);
|
super("OpenTrace", tool, owner, provider);
|
||||||
fileExt = ".run";
|
fileExt = ".run";
|
||||||
fileMode = GhidraFileChooserMode.FILES_AND_DIRECTORIES;
|
fileMode = GhidraFileChooserMode.FILES_AND_DIRECTORIES;
|
|
@ -561,23 +561,12 @@ public class DebuggerThreadsProvider extends ComponentProviderAdapter {
|
||||||
JMenuItem closeOthers =
|
JMenuItem closeOthers =
|
||||||
new JMenuItem("Close Others", DebuggerResources.ICON_CLOSE);
|
new JMenuItem("Close Others", DebuggerResources.ICON_CLOSE);
|
||||||
closeOthers.addActionListener(evt -> {
|
closeOthers.addActionListener(evt -> {
|
||||||
for (Trace t : List.copyOf(traceManager.getOpenTraces())) {
|
traceManager.closeOtherTraces(trace);
|
||||||
if (trace == t) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
traceManager.closeTrace(t);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
JMenuItem closeDead =
|
JMenuItem closeDead =
|
||||||
new JMenuItem("Close Dead", DebuggerResources.ICON_CLOSE);
|
new JMenuItem("Close Dead", DebuggerResources.ICON_CLOSE);
|
||||||
closeDead.addActionListener(evt -> {
|
closeDead.addActionListener(evt -> {
|
||||||
for (Trace t : List.copyOf(traceManager.getOpenTraces())) {
|
traceManager.closeDeadTraces();
|
||||||
TraceRecorder recorder = modelService.getRecorder(t);
|
|
||||||
if (recorder != null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
traceManager.closeTrace(t);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
JMenuItem closeAll =
|
JMenuItem closeAll =
|
||||||
new JMenuItem("Close All", DebuggerResources.ICON_CLOSE);
|
new JMenuItem("Close All", DebuggerResources.ICON_CLOSE);
|
||||||
|
|
|
@ -21,10 +21,13 @@ import java.net.ConnectException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import docking.ActionContext;
|
||||||
|
import docking.action.DockingAction;
|
||||||
import ghidra.app.plugin.PluginCategoryNames;
|
import ghidra.app.plugin.PluginCategoryNames;
|
||||||
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
|
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
|
||||||
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
|
import ghidra.app.plugin.core.debug.DebuggerPluginPackage;
|
||||||
import ghidra.app.plugin.core.debug.event.*;
|
import ghidra.app.plugin.core.debug.event.*;
|
||||||
|
import ghidra.app.plugin.core.debug.gui.DebuggerResources.*;
|
||||||
import ghidra.app.plugin.core.debug.utils.ProgramLocationUtils;
|
import ghidra.app.plugin.core.debug.utils.ProgramLocationUtils;
|
||||||
import ghidra.app.services.*;
|
import ghidra.app.services.*;
|
||||||
import ghidra.async.AsyncConfigFieldCodec.BooleanAsyncConfigFieldCodec;
|
import ghidra.async.AsyncConfigFieldCodec.BooleanAsyncConfigFieldCodec;
|
||||||
|
@ -34,6 +37,7 @@ import ghidra.dbg.target.TargetStackFrame;
|
||||||
import ghidra.dbg.target.TargetThread;
|
import ghidra.dbg.target.TargetThread;
|
||||||
import ghidra.framework.client.ClientUtil;
|
import ghidra.framework.client.ClientUtil;
|
||||||
import ghidra.framework.client.NotConnectedException;
|
import ghidra.framework.client.NotConnectedException;
|
||||||
|
import ghidra.framework.main.DataTreeDialog;
|
||||||
import ghidra.framework.model.*;
|
import ghidra.framework.model.*;
|
||||||
import ghidra.framework.options.SaveState;
|
import ghidra.framework.options.SaveState;
|
||||||
import ghidra.framework.plugintool.*;
|
import ghidra.framework.plugintool.*;
|
||||||
|
@ -151,12 +155,133 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private final AutoService.Wiring autoServiceWiring;
|
private final AutoService.Wiring autoServiceWiring;
|
||||||
|
|
||||||
|
private DataTreeDialog traceChooserDialog;
|
||||||
|
|
||||||
|
DockingAction actionCloseTrace;
|
||||||
|
DockingAction actionCloseAllTraces;
|
||||||
|
DockingAction actionCloseOtherTraces;
|
||||||
|
DockingAction actionCloseDeadTraces;
|
||||||
|
DockingAction actionOpenTrace;
|
||||||
|
|
||||||
public DebuggerTraceManagerServicePlugin(PluginTool plugintool) {
|
public DebuggerTraceManagerServicePlugin(PluginTool plugintool) {
|
||||||
super(plugintool);
|
super(plugintool);
|
||||||
// NOTE: Plugin should be recognized as its own service provider
|
// NOTE: Plugin should be recognized as its own service provider
|
||||||
autoServiceWiring = AutoService.wireServicesProvidedAndConsumed(this);
|
autoServiceWiring = AutoService.wireServicesProvidedAndConsumed(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
super.init();
|
||||||
|
createActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void createActions() {
|
||||||
|
actionOpenTrace = OpenTraceAction.builder(this)
|
||||||
|
.enabledWhen(ctx -> true)
|
||||||
|
.onAction(this::activatedOpenTrace)
|
||||||
|
.buildAndInstall(tool);
|
||||||
|
actionCloseTrace = CloseTraceAction.builder(this)
|
||||||
|
.enabledWhen(ctx -> current.getTrace() != null)
|
||||||
|
.onAction(this::activatedCloseTrace)
|
||||||
|
.buildAndInstall(tool);
|
||||||
|
actionCloseAllTraces = CloseAllTracesAction.builder(this)
|
||||||
|
.enabledWhen(ctx -> !tracesView.isEmpty())
|
||||||
|
.onAction(this::activatedCloseAllTraces)
|
||||||
|
.buildAndInstall(tool);
|
||||||
|
actionCloseOtherTraces = CloseOtherTracesAction.builder(this)
|
||||||
|
.enabledWhen(ctx -> tracesView.size() > 1 && current.getTrace() != null)
|
||||||
|
.onAction(this::activatedCloseOtherTraces)
|
||||||
|
.buildAndInstall(tool);
|
||||||
|
actionCloseDeadTraces = CloseDeadTracesAction.builder(this)
|
||||||
|
.enabledWhen(ctx -> !tracesView.isEmpty() && modelService != null)
|
||||||
|
.onAction(this::activatedCloseDeadTraces)
|
||||||
|
.buildAndInstall(tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void activatedOpenTrace(ActionContext ctx) {
|
||||||
|
DomainFile df = askTrace(current.getTrace());
|
||||||
|
if (df != null) {
|
||||||
|
Trace trace = openTrace(df, DomainFile.DEFAULT_VERSION); // TODO: Permit opening a previous revision?
|
||||||
|
activateTrace(trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void activatedCloseTrace(ActionContext ctx) {
|
||||||
|
Trace trace = current.getTrace();
|
||||||
|
if (trace == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
closeTrace(trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void activatedCloseAllTraces(ActionContext ctx) {
|
||||||
|
closeAllTraces();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void activatedCloseOtherTraces(ActionContext ctx) {
|
||||||
|
Trace trace = current.getTrace();
|
||||||
|
if (trace == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
closeOtherTraces(trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void activatedCloseDeadTraces(ActionContext ctx) {
|
||||||
|
closeDeadTraces();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected DataTreeDialog getTraceChooserDialog() {
|
||||||
|
if (traceChooserDialog != null) {
|
||||||
|
return traceChooserDialog;
|
||||||
|
}
|
||||||
|
DomainFileFilter filter = df -> Trace.class.isAssignableFrom(df.getDomainObjectClass());
|
||||||
|
return traceChooserDialog =
|
||||||
|
new DataTreeDialog(null, OpenTraceAction.NAME, DataTreeDialog.OPEN, filter) {
|
||||||
|
{ // TODO/HACK: Why the NPE if I don't do this?
|
||||||
|
dialogShown();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public DomainFile askTrace(Trace trace) {
|
||||||
|
getTraceChooserDialog();
|
||||||
|
if (trace != null) {
|
||||||
|
traceChooserDialog.selectDomainFile(trace.getDomainFile());
|
||||||
|
}
|
||||||
|
tool.showDialog(traceChooserDialog);
|
||||||
|
return traceChooserDialog.getDomainFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeAllTraces() {
|
||||||
|
for (Trace trace : getOpenTraces()) {
|
||||||
|
closeTrace(trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeOtherTraces(Trace keep) {
|
||||||
|
for (Trace trace : getOpenTraces()) {
|
||||||
|
if (trace != keep) {
|
||||||
|
closeTrace(trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeDeadTraces() {
|
||||||
|
if (modelService == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (Trace trace : getOpenTraces()) {
|
||||||
|
TraceRecorder recorder = modelService.getRecorder(trace);
|
||||||
|
if (recorder == null) {
|
||||||
|
closeTrace(trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@AutoServiceConsumed
|
@AutoServiceConsumed
|
||||||
private void setModelService(DebuggerModelService modelService) {
|
private void setModelService(DebuggerModelService modelService) {
|
||||||
if (this.modelService != null) {
|
if (this.modelService != null) {
|
||||||
|
@ -308,6 +433,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
current = resolved;
|
current = resolved;
|
||||||
|
contextChanged();
|
||||||
if (current.getTrace() != null && current.getThread() != null) {
|
if (current.getTrace() != null && current.getThread() != null) {
|
||||||
threadFocusByTrace.put(current.getTrace(), current.getThread());
|
threadFocusByTrace.put(current.getTrace(), current.getThread());
|
||||||
}
|
}
|
||||||
|
@ -315,6 +441,13 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void contextChanged() {
|
||||||
|
Trace trace = current.getTrace();
|
||||||
|
String name = trace == null ? "..." : trace.getName();
|
||||||
|
actionCloseTrace.getMenuBarData().setMenuItemName(CloseTraceAction.NAME_PREFIX + name);
|
||||||
|
tool.contextChanged(null);
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean doModelObjectFocused(TargetObjectRef ref, boolean requirePresent) {
|
protected boolean doModelObjectFocused(TargetObjectRef ref, boolean requirePresent) {
|
||||||
curRef = ref;
|
curRef = ref;
|
||||||
if (!synchronizeFocus.get()) {
|
if (!synchronizeFocus.get()) {
|
||||||
|
@ -410,8 +543,8 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Trace> getOpenTraces() {
|
public synchronized Collection<Trace> getOpenTraces() {
|
||||||
return tracesView;
|
return Set.copyOf(tracesView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -471,6 +604,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||||
listenersByTrace.put(trace, listener);
|
listenersByTrace.put(trace, listener);
|
||||||
trace.addListener(listener);
|
trace.addListener(listener);
|
||||||
}
|
}
|
||||||
|
contextChanged();
|
||||||
firePluginEvent(new TraceOpenedPluginEvent(getName(), trace));
|
firePluginEvent(new TraceOpenedPluginEvent(getName(), trace));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,6 +782,9 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||||
if (current.getTrace() == trace) {
|
if (current.getTrace() == trace) {
|
||||||
activate(DebuggerCoordinates.NOWHERE);
|
activate(DebuggerCoordinates.NOWHERE);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
contextChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -88,7 +88,7 @@ public interface DebuggerTraceManagerService {
|
||||||
Collection<Trace> openTraces(Collection<DomainFile> files);
|
Collection<Trace> openTraces(Collection<DomainFile> files);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the trace to the root folder of the project
|
* Save the trace to the "New Traces" folder of the project
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* If a different domain file of the trace's name already exists, an incrementing integer is
|
* If a different domain file of the trace's name already exists, an incrementing integer is
|
||||||
|
@ -103,6 +103,19 @@ public interface DebuggerTraceManagerService {
|
||||||
|
|
||||||
void closeTrace(Trace trace);
|
void closeTrace(Trace trace);
|
||||||
|
|
||||||
|
void closeAllTraces();
|
||||||
|
|
||||||
|
void closeOtherTraces(Trace keep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close all traces which are not the destination of a live recording
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Operation of this method depends on the model service. If that service is not present, this
|
||||||
|
* method performs no operation at all.
|
||||||
|
*/
|
||||||
|
void closeDeadTraces();
|
||||||
|
|
||||||
void activate(DebuggerCoordinates coordinates);
|
void activate(DebuggerCoordinates coordinates);
|
||||||
|
|
||||||
void activateTrace(Trace trace);
|
void activateTrace(Trace trace);
|
||||||
|
@ -179,5 +192,4 @@ public interface DebuggerTraceManagerService {
|
||||||
* @return the complete resolved coordinates
|
* @return the complete resolved coordinates
|
||||||
*/
|
*/
|
||||||
DebuggerCoordinates resolveCoordinates(DebuggerCoordinates coords);
|
DebuggerCoordinates resolveCoordinates(DebuggerCoordinates coords);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,7 +233,7 @@ public class DebuggerThreadsProviderTest extends AbstractGhidraHeadedDebuggerGUI
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
waitForPass(() -> {
|
waitForPass(() -> {
|
||||||
assertEquals(Set.of(), Set.copyOf(traceManager.getOpenTraces()));
|
assertEquals(Set.of(), traceManager.getOpenTraces());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,17 +46,17 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetOpenTraces() throws Exception {
|
public void testGetOpenTraces() throws Exception {
|
||||||
assertEquals(Set.of(), Set.copyOf(traceManager.getOpenTraces()));
|
assertEquals(Set.of(), traceManager.getOpenTraces());
|
||||||
|
|
||||||
createAndOpenTrace();
|
createAndOpenTrace();
|
||||||
waitForDomainObject(tb.trace);
|
waitForDomainObject(tb.trace);
|
||||||
|
|
||||||
assertEquals(Set.of(tb.trace), Set.copyOf(traceManager.getOpenTraces()));
|
assertEquals(Set.of(tb.trace), traceManager.getOpenTraces());
|
||||||
|
|
||||||
traceManager.closeTrace(tb.trace);
|
traceManager.closeTrace(tb.trace);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
|
||||||
assertEquals(Set.of(), Set.copyOf(traceManager.getOpenTraces()));
|
assertEquals(Set.of(), traceManager.getOpenTraces());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -204,8 +204,8 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||||
createTrace();
|
createTrace();
|
||||||
waitForDomainObject(tb.trace);
|
waitForDomainObject(tb.trace);
|
||||||
|
|
||||||
assertEquals(Set.of(), Set.copyOf(traceManager.getOpenTraces()));
|
assertEquals(Set.of(), traceManager.getOpenTraces());
|
||||||
assertEquals(Set.of(tb), Set.copyOf(tb.trace.getConsumerList()));
|
assertEquals(Set.of(tb), tb.trace.getConsumerList());
|
||||||
|
|
||||||
traceManager.openTrace(tb.trace);
|
traceManager.openTrace(tb.trace);
|
||||||
waitForSwing();
|
waitForSwing();
|
||||||
|
@ -213,12 +213,14 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||||
assertEquals(Set.of(tb, traceManager), Set.copyOf(tb.trace.getConsumerList()));
|
assertEquals(Set.of(tb, traceManager), Set.copyOf(tb.trace.getConsumerList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Test the other close methods: all, others, dead
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOpenTraceDomainFile() throws Exception {
|
public void testOpenTraceDomainFile() throws Exception {
|
||||||
createTrace();
|
createTrace();
|
||||||
waitForDomainObject(tb.trace);
|
waitForDomainObject(tb.trace);
|
||||||
|
|
||||||
assertEquals(Set.of(), Set.copyOf(traceManager.getOpenTraces()));
|
assertEquals(Set.of(), traceManager.getOpenTraces());
|
||||||
assertEquals(Set.of(tb), Set.copyOf(tb.trace.getConsumerList()));
|
assertEquals(Set.of(tb), Set.copyOf(tb.trace.getConsumerList()));
|
||||||
|
|
||||||
traceManager.openTrace(tb.trace.getDomainFile(), DomainFile.DEFAULT_VERSION);
|
traceManager.openTrace(tb.trace.getDomainFile(), DomainFile.DEFAULT_VERSION);
|
||||||
|
@ -232,7 +234,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||||
createProgram();
|
createProgram();
|
||||||
waitForDomainObject(program);
|
waitForDomainObject(program);
|
||||||
|
|
||||||
assertEquals(Set.of(), Set.copyOf(traceManager.getOpenTraces()));
|
assertEquals(Set.of(), traceManager.getOpenTraces());
|
||||||
assertEquals(Set.of(this), Set.copyOf(program.getConsumerList()));
|
assertEquals(Set.of(this), Set.copyOf(program.getConsumerList()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue