mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-1329: Prevent disruptive error dialogs from automatic actions.
This commit is contained in:
parent
2c386e37fe
commit
17d608f797
23 changed files with 156 additions and 87 deletions
|
@ -274,9 +274,9 @@ public class DebuggerObjectsPlugin extends AbstractDebuggerPlugin
|
|||
providers.get(0).readConfigState(saveState);
|
||||
}
|
||||
|
||||
public void objectError(String title, String message) {
|
||||
public void objectError(String message) {
|
||||
if (consoleService == null) {
|
||||
Msg.showError(this, null, title, message);
|
||||
Msg.error(this, message);
|
||||
return;
|
||||
}
|
||||
consoleService.log(DebuggerResources.ICON_LOG_ERROR, message);
|
||||
|
|
|
@ -465,7 +465,7 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
|||
if (pane != null) {
|
||||
if (currentModel != null) {
|
||||
currentModel.fetchModelRoot().thenAccept(this::refresh).exceptionally(ex -> {
|
||||
plugin.objectError("Refresh", "Error refreshing model root");
|
||||
plugin.objectError("Error refreshing model root");
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
@ -668,7 +668,7 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
|||
table.setColumns();
|
||||
// TODO: What with attrs?
|
||||
}).exceptionally(ex -> {
|
||||
plugin.objectError("Build Table", "Failed to fetch attributes");
|
||||
plugin.objectError("Failed to fetch attributes");
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
@ -683,7 +683,7 @@ public class DebuggerObjectsProvider extends ComponentProviderAdapter
|
|||
public void addTargetToMap(ObjectContainer container) {
|
||||
DebuggerObjectsProvider provider = container.getProvider();
|
||||
if (!this.equals(provider)) {
|
||||
plugin.objectError("Add Target", "TargetMap corrupted");
|
||||
plugin.objectError("TargetMap corrupted");
|
||||
}
|
||||
TargetObject targetObject = container.getTargetObject();
|
||||
if (targetObject != null && !container.isLink()) {
|
||||
|
|
|
@ -34,7 +34,7 @@ public class ObjectElementRow {
|
|||
map = attributes;
|
||||
}).exceptionally(ex -> {
|
||||
DebuggerObjectsPlugin plugin = provider.getPlugin();
|
||||
plugin.objectError("Create Row", "Failed to fetch attributes");
|
||||
plugin.objectError("Failed to fetch attributes");
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ public interface DebuggerModelServiceInternal extends DebuggerModelService {
|
|||
/**
|
||||
* Force the set of factory instances to be that given
|
||||
*
|
||||
* <p>
|
||||
* This exists for testing the factory change listeners. A test depending on a controlled
|
||||
* collection of model factories must invoke this method before said test. Conventionally, it is
|
||||
* the responsibility of each test to ensure its own preconditions are met. For a test depending
|
||||
|
@ -51,6 +52,7 @@ public interface DebuggerModelServiceInternal extends DebuggerModelService {
|
|||
/**
|
||||
* Set the model factories back to those found on the classpath
|
||||
*
|
||||
* <p>
|
||||
* This exists for testing the factory change listeners. A test depending on
|
||||
* classpath-discovered factories must invoke this method. It must consider that a previous test
|
||||
* may have overridden the factories using {@link #setModelFactories(Collection)}.
|
||||
|
@ -65,6 +67,7 @@ public interface DebuggerModelServiceInternal extends DebuggerModelService {
|
|||
/**
|
||||
* Start and open a new trace on the given target
|
||||
*
|
||||
* <p>
|
||||
* Starts a new trace, and opens it in the tool
|
||||
*
|
||||
* @see #recordTarget(TargetObject)
|
||||
|
|
|
@ -314,8 +314,8 @@ public class DebuggerModelServicePlugin extends Plugin
|
|||
}
|
||||
|
||||
@Override
|
||||
public TraceRecorder recordTarget(TargetObject target, DebuggerTargetTraceMapper mapper)
|
||||
throws IOException {
|
||||
public TraceRecorder recordTarget(TargetObject target, DebuggerTargetTraceMapper mapper,
|
||||
ActionSource source) throws IOException {
|
||||
TraceRecorder recorder;
|
||||
// Cannot use computeIfAbsent here
|
||||
// Entry must be present before listeners invoked
|
||||
|
@ -328,7 +328,12 @@ public class DebuggerModelServicePlugin extends Plugin
|
|||
recorder = doBeginRecording(target, mapper);
|
||||
recorder.addListener(listenerOnRecorders);
|
||||
recorder.init().exceptionally(e -> {
|
||||
Msg.showError(this, null, "Record Trace", "Error initializing recorder", e);
|
||||
if (source == ActionSource.MANUAL) {
|
||||
Msg.showError(this, null, "Record Trace", "Error initializing recorder", e);
|
||||
}
|
||||
else {
|
||||
Msg.error(this, "Error initializing recorder", e);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
recordersByTarget.put(target, recorder);
|
||||
|
@ -356,7 +361,7 @@ public class DebuggerModelServicePlugin extends Plugin
|
|||
throw new NoSuchElementException("No mapper for target: " + target);
|
||||
}
|
||||
try {
|
||||
return recordTarget(target, mapper);
|
||||
return recordTarget(target, mapper, ActionSource.AUTOMATIC);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new AssertionError("Could not record target: " + target, e);
|
||||
|
@ -383,7 +388,7 @@ public class DebuggerModelServicePlugin extends Plugin
|
|||
assert selected != null;
|
||||
DebuggerTargetTraceMapper mapper = selected.take();
|
||||
try {
|
||||
return recordTarget(target, mapper);
|
||||
return recordTarget(target, mapper, ActionSource.MANUAL);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new AssertionError("Could not record target: " + target, e);
|
||||
|
@ -494,7 +499,7 @@ public class DebuggerModelServicePlugin extends Plugin
|
|||
public TraceRecorder recordTargetAndActivateTrace(TargetObject target,
|
||||
DebuggerTargetTraceMapper mapper, DebuggerTraceManagerService traceManager)
|
||||
throws IOException {
|
||||
TraceRecorder recorder = recordTarget(target, mapper);
|
||||
TraceRecorder recorder = recordTarget(target, mapper, ActionSource.AUTOMATIC);
|
||||
if (traceManager != null) {
|
||||
Trace trace = recorder.getTrace();
|
||||
traceManager.openTrace(trace);
|
||||
|
|
|
@ -63,14 +63,22 @@ import ghidra.util.datastruct.ListenerSet;
|
|||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
@PluginInfo(shortDescription = "Debugger models manager service (proxy to front-end)", description = "Manage debug sessions, connections, and trace recording", category = PluginCategoryNames.DEBUGGER, packageName = DebuggerPluginPackage.NAME, status = PluginStatus.RELEASED, eventsConsumed = {
|
||||
ProgramActivatedPluginEvent.class,
|
||||
ProgramClosedPluginEvent.class,
|
||||
}, servicesRequired = {
|
||||
DebuggerTraceManagerService.class,
|
||||
}, servicesProvided = {
|
||||
DebuggerModelService.class,
|
||||
})
|
||||
@PluginInfo(
|
||||
shortDescription = "Debugger models manager service (proxy to front-end)",
|
||||
description = "Manage debug sessions, connections, and trace recording",
|
||||
category = PluginCategoryNames.DEBUGGER,
|
||||
packageName = DebuggerPluginPackage.NAME,
|
||||
status = PluginStatus.RELEASED,
|
||||
eventsConsumed = {
|
||||
ProgramActivatedPluginEvent.class,
|
||||
ProgramClosedPluginEvent.class,
|
||||
},
|
||||
servicesRequired = {
|
||||
DebuggerTraceManagerService.class,
|
||||
},
|
||||
servicesProvided = {
|
||||
DebuggerModelService.class,
|
||||
})
|
||||
public class DebuggerModelServiceProxyPlugin extends Plugin
|
||||
implements DebuggerModelServiceInternal {
|
||||
|
||||
|
@ -499,9 +507,9 @@ public class DebuggerModelServiceProxyPlugin extends Plugin
|
|||
}
|
||||
|
||||
@Override
|
||||
public TraceRecorder recordTarget(TargetObject target, DebuggerTargetTraceMapper mapper)
|
||||
throws IOException {
|
||||
return delegate.recordTarget(target, mapper);
|
||||
public TraceRecorder recordTarget(TargetObject target, DebuggerTargetTraceMapper mapper,
|
||||
ActionSource source) throws IOException {
|
||||
return delegate.recordTarget(target, mapper, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -422,12 +422,14 @@ public class DefaultTraceRecorder implements TraceRecorder {
|
|||
}
|
||||
return focusScope.requestFocus(focus).thenApply(__ -> true).exceptionally(ex -> {
|
||||
ex = AsyncUtils.unwrapThrowable(ex);
|
||||
String msg = "Could not focus " + focus + ": " + ex.getMessage();
|
||||
plugin.getTool().setStatusInfo(msg);
|
||||
if (ex instanceof DebuggerModelAccessException) {
|
||||
String msg = "Could not focus " + focus + ": " + ex.getMessage();
|
||||
Msg.info(this, msg);
|
||||
plugin.getTool().setStatusInfo(msg);
|
||||
}
|
||||
Msg.showError(this, null, "Focus Sync", "Could not focus " + focus, ex);
|
||||
else {
|
||||
Msg.error(this, "Could not focus " + focus, ex);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/* ###
|
||||
* 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.services;
|
||||
|
||||
/**
|
||||
* Possible sources that drive actions or method invocations
|
||||
*
|
||||
* <p>
|
||||
* This is primarily used to determine where and how errors should be reported. Granted, this is
|
||||
* only one factor in determining how to deliver an error message. In general, actions which are
|
||||
* taken automatically should not cause disruptive error messages.
|
||||
*/
|
||||
public enum ActionSource {
|
||||
/**
|
||||
* The action was requested by the user, usually via a UI action. It is acceptable to display an
|
||||
* error message.
|
||||
*/
|
||||
MANUAL,
|
||||
/**
|
||||
* The action was requested automatically, usually by some background thread. Error messages
|
||||
* should probably be delivered to the log or Debug Console, since displaying an error pop-up
|
||||
* would seem to "come from nowhere."
|
||||
*/
|
||||
AUTOMATIC;
|
||||
}
|
|
@ -108,19 +108,21 @@ public interface DebuggerModelService {
|
|||
*
|
||||
* @param target a target to record
|
||||
* @param mapper a mapper between target and trace objects
|
||||
* @param source the source of the request
|
||||
* @return the destination trace
|
||||
* @throws IOException if a trace cannot be created
|
||||
* @see DebuggerMappingOpinion#getOffers(TargetObject)
|
||||
*/
|
||||
TraceRecorder recordTarget(TargetObject target, DebuggerTargetTraceMapper mapper)
|
||||
throws IOException;
|
||||
TraceRecorder recordTarget(TargetObject target, DebuggerTargetTraceMapper mapper,
|
||||
ActionSource source) throws IOException;
|
||||
|
||||
/**
|
||||
* Query mapping opinions and record the given target using the "best" offer
|
||||
*
|
||||
* <p>
|
||||
* If exactly one offer is given, this simply uses it. If multiple are given, this automatically
|
||||
* chooses the "best" one without prompting the user. If none are given, this fails.
|
||||
* chooses the "best" one without prompting the user. If none are given, this fails. This
|
||||
* invocation is assumed to come from an {@link ActionSource#AUTOMATIC} source.
|
||||
*
|
||||
* @see DebuggerMappingOpinion#queryOpinions(TargetObject)
|
||||
* @param target the target to record.
|
||||
|
@ -134,7 +136,8 @@ public interface DebuggerModelService {
|
|||
* <p>
|
||||
* Even if exactly one offer is given, the user is prompted to provide information about the new
|
||||
* recording, and to give the user an opportunity to cancel. If none are given, the prompt says
|
||||
* as much. If the user cancels, the returned future completes with {@code null}.
|
||||
* as much. If the user cancels, the returned future completes with {@code null}. The invocation
|
||||
* is assumed to come from a {@link ActionSource#MANUAL} source.
|
||||
*
|
||||
* <p>
|
||||
* TODO: Should the prompt allow the user to force an opinion which gave no offers?
|
||||
|
@ -149,7 +152,8 @@ public interface DebuggerModelService {
|
|||
* Start and open a new trace on the given target
|
||||
*
|
||||
* <p>
|
||||
* Starts a new trace, and opens it in the tool
|
||||
* Starts a new trace, and opens it in the tool. The invocation is assumed to come from an
|
||||
* {@link ActionSource#AUTOMATIC} source.
|
||||
*
|
||||
* @see #recordTarget(TargetObject)
|
||||
*/
|
||||
|
|
|
@ -116,9 +116,9 @@ public class DebuggerBreakpointsPluginScreenShots extends GhidraScreenShotGenera
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder1 = modelService.recordTarget(mb.testProcess1,
|
||||
new TestDebuggerTargetTraceMapper(mb.testProcess1));
|
||||
new TestDebuggerTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
TraceRecorder recorder3 = modelService.recordTarget(mb.testProcess3,
|
||||
new TestDebuggerTargetTraceMapper(mb.testProcess3));
|
||||
new TestDebuggerTargetTraceMapper(mb.testProcess3), ActionSource.AUTOMATIC);
|
||||
Trace trace1 = recorder1.getTrace();
|
||||
Trace trace3 = recorder3.getTrace();
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public class DebuggerCopyActionsPluginScreenShots extends GhidraScreenShotGenera
|
|||
mb.createTestModel();
|
||||
mb.createTestProcessesAndThreads();
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
new TestDebuggerTargetTraceMapper(mb.testProcess1));
|
||||
new TestDebuggerTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
tb = new ToyDBTraceBuilder(recorder.getTrace());
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,7 @@ import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
|
|||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest.TestDebuggerTargetTraceMapper;
|
||||
import ghidra.app.plugin.core.debug.service.model.DebuggerModelServiceProxyPlugin;
|
||||
import ghidra.app.plugin.core.debug.service.tracemgr.DebuggerTraceManagerServicePlugin;
|
||||
import ghidra.app.services.DebuggerTraceManagerService;
|
||||
import ghidra.app.services.TraceRecorder;
|
||||
import ghidra.app.services.*;
|
||||
import ghidra.dbg.model.*;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
|
@ -54,8 +53,8 @@ public class DebuggerThreadsPluginScreenShots extends GhidraScreenShotGenerator
|
|||
mb.createTestModel();
|
||||
TestTargetProcess process = mb.testModel.addProcess(1234);
|
||||
|
||||
TraceRecorder recorder =
|
||||
modelService.recordTarget(process, new TestDebuggerTargetTraceMapper(process));
|
||||
TraceRecorder recorder = modelService.recordTarget(process,
|
||||
new TestDebuggerTargetTraceMapper(process), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
|
||||
TestTargetThread mainThread = process.addThread(1);
|
||||
|
@ -96,10 +95,10 @@ public class DebuggerThreadsPluginScreenShots extends GhidraScreenShotGenerator
|
|||
|
||||
TestTargetProcess dummy1 = mb.testModel.addProcess(4321);
|
||||
TestTargetProcess dummy2 = mb.testModel.addProcess(5432);
|
||||
TraceRecorder recDummy1 =
|
||||
modelService.recordTarget(dummy1, new TestDebuggerTargetTraceMapper(dummy1));
|
||||
TraceRecorder recDummy2 =
|
||||
modelService.recordTarget(dummy2, new TestDebuggerTargetTraceMapper(dummy2));
|
||||
TraceRecorder recDummy1 = modelService.recordTarget(dummy1,
|
||||
new TestDebuggerTargetTraceMapper(dummy1), ActionSource.AUTOMATIC);
|
||||
TraceRecorder recDummy2 = modelService.recordTarget(dummy2,
|
||||
new TestDebuggerTargetTraceMapper(dummy2), ActionSource.AUTOMATIC);
|
||||
|
||||
traceManager.setAutoCloseOnTerminate(false);
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.debug.gui.breakpoint;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
@ -137,7 +138,7 @@ public class DebuggerBreakpointMarkerPluginTest extends AbstractGhidraHeadedDebu
|
|||
createTestModel();
|
||||
mb.createTestProcessesAndThreads();
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
createProgramFromTrace(trace);
|
||||
intoProject(trace);
|
||||
|
|
|
@ -121,7 +121,7 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
createTestModel();
|
||||
mb.createTestProcessesAndThreads();
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
|
||||
addLiveMemoryAndBreakpoint(mb.testProcess1, recorder);
|
||||
|
@ -145,7 +145,7 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
createTestModel();
|
||||
mb.createTestProcessesAndThreads();
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
|
||||
addLiveMemoryAndBreakpoint(mb.testProcess1, recorder);
|
||||
|
@ -210,7 +210,7 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
createTestModel();
|
||||
mb.createTestProcessesAndThreads();
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
createProgramFromTrace(trace);
|
||||
intoProject(trace);
|
||||
|
@ -471,7 +471,7 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
createTestModel();
|
||||
mb.createTestProcessesAndThreads();
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
createProgramFromTrace(trace);
|
||||
intoProject(trace);
|
||||
|
@ -514,11 +514,11 @@ public class DebuggerBreakpointsProviderTest extends AbstractGhidraHeadedDebugge
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder1 = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace1 = recorder1.getTrace();
|
||||
|
||||
TraceRecorder recorder3 = modelService.recordTarget(mb.testProcess3,
|
||||
createTargetTraceMapper(mb.testProcess3));
|
||||
createTargetTraceMapper(mb.testProcess3), ActionSource.AUTOMATIC);
|
||||
Trace trace3 = recorder3.getTrace();
|
||||
|
||||
createProgramFromTrace(trace1);
|
||||
|
|
|
@ -36,6 +36,7 @@ import ghidra.app.plugin.core.debug.gui.copying.DebuggerCopyIntoProgramDialog.Ra
|
|||
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
|
||||
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingProvider;
|
||||
import ghidra.app.plugin.core.debug.service.modules.DebuggerStaticMappingServicePlugin;
|
||||
import ghidra.app.services.ActionSource;
|
||||
import ghidra.app.services.DebuggerStaticMappingService;
|
||||
import ghidra.dbg.DebuggerModelListener;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
|
@ -456,7 +457,8 @@ public class DebuggerCopyActionsPluginTest extends AbstractGhidraHeadedDebuggerG
|
|||
mb.testModel.addModelListener(listener);
|
||||
|
||||
mb.createTestProcessesAndThreads();
|
||||
modelService.recordTarget(mb.testProcess1, createTargetTraceMapper(mb.testProcess1));
|
||||
modelService.recordTarget(mb.testProcess1, createTargetTraceMapper(mb.testProcess1),
|
||||
ActionSource.AUTOMATIC);
|
||||
mb.testProcess1.memory.addRegion(".text", mb.rng(0x55550000, 0x5555ffff), "rx");
|
||||
mb.testProcess1.memory.setMemory(mb.addr(0x55550000), mb.arr(1, 2, 3, 4, 5, 6, 7, 8));
|
||||
waitForPass(() -> {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package ghidra.app.plugin.core.debug.gui.register;
|
||||
|
||||
import static ghidra.lifecycle.Unfinished.*;
|
||||
import static ghidra.lifecycle.Unfinished.TODO;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
@ -33,6 +33,7 @@ import ghidra.app.plugin.core.debug.gui.action.LocationTrackingSpec;
|
|||
import ghidra.app.plugin.core.debug.gui.action.NoneLocationTrackingSpec;
|
||||
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
|
||||
import ghidra.app.plugin.core.debug.gui.register.DebuggerRegistersProvider.RegisterTableColumns;
|
||||
import ghidra.app.services.ActionSource;
|
||||
import ghidra.app.services.TraceRecorder;
|
||||
import ghidra.async.AsyncTestUtils;
|
||||
import ghidra.program.model.data.*;
|
||||
|
@ -146,7 +147,7 @@ public class DebuggerRegistersProviderTest extends AbstractGhidraHeadedDebuggerG
|
|||
Register::isBaseRegister);
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
|
||||
waitFor(() -> {
|
||||
TraceThread thread = recorder.getTraceThread(mb.testThread1);
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.junit.*;
|
|||
import generic.Unique;
|
||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
|
||||
import ghidra.app.plugin.core.debug.gui.listing.DebuggerListingPlugin;
|
||||
import ghidra.app.services.ActionSource;
|
||||
import ghidra.app.services.TraceRecorder;
|
||||
import ghidra.async.AsyncTestUtils;
|
||||
import ghidra.dbg.model.TestTargetRegisterBankInThread;
|
||||
|
@ -208,7 +209,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
|
|||
mb.testProcess1.memory.writeMemory(mb.addr(0x00400000), tb.arr(1, 2, 3, 4));
|
||||
|
||||
recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
|
||||
|
||||
|
@ -348,7 +349,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerGUI
|
|||
mb.testProcess1.addRegion(".text", mb.rng(0x00400000, 0x00401000), "rx");
|
||||
|
||||
recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
|
||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
|
||||
import ghidra.app.services.ActionSource;
|
||||
import ghidra.app.services.TraceRecorder;
|
||||
import ghidra.dbg.model.TestTargetRegister;
|
||||
import ghidra.dbg.target.*;
|
||||
|
@ -63,8 +64,8 @@ public class LargestSubDebuggerRegisterMapperTest extends AbstractGhidraHeadedDe
|
|||
protected DebuggerRegisterMapper getRegisterMapperBase() throws Throwable {
|
||||
mb.testProcess1.regs.addRegistersFromLanguage(getSLEIGH_X86_64_LANGUAGE(), r -> true);
|
||||
|
||||
TraceRecorder recorder =
|
||||
modelService.recordTarget(mb.testProcess1, new TestTargetMapper(mb.testProcess1));
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
new TestTargetMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
TraceThread thread1 = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
|
||||
DebuggerRegisterMapper rm = waitForValue(() -> recorder.getRegisterMapper(thread1));
|
||||
waitForValue(() -> rm.getTargetRegister("rax"));
|
||||
|
@ -75,8 +76,8 @@ public class LargestSubDebuggerRegisterMapperTest extends AbstractGhidraHeadedDe
|
|||
protected DebuggerRegisterMapper getRegisterMapperSub() throws Throwable {
|
||||
mb.testProcess1.regs.addRegistersFromLanguage(getSLEIGH_X86_LANGUAGE(), r -> true);
|
||||
|
||||
TraceRecorder recorder =
|
||||
modelService.recordTarget(mb.testProcess1, new TestTargetMapper(mb.testProcess1));
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
new TestTargetMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
TraceThread thread1 = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
|
||||
DebuggerRegisterMapper rm = waitForValue(() -> recorder.getRegisterMapper(thread1));
|
||||
waitForValue(() -> rm.getTargetRegister("eax"));
|
||||
|
|
|
@ -166,12 +166,12 @@ public class DebuggerLogicalBreakpointServiceTest extends AbstractGhidraHeadedDe
|
|||
|
||||
public void startRecorder1() throws Throwable {
|
||||
recorder1 = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
}
|
||||
|
||||
public void startRecorder3() throws Throwable {
|
||||
recorder3 = modelService.recordTarget(mb.testProcess3,
|
||||
createTargetTraceMapper(mb.testProcess3));
|
||||
createTargetTraceMapper(mb.testProcess3), ActionSource.AUTOMATIC);
|
||||
}
|
||||
|
||||
@After
|
||||
|
|
|
@ -37,6 +37,7 @@ import ghidra.app.plugin.core.debug.gui.DebuggerResources.AbstractConnectAction;
|
|||
import ghidra.app.plugin.core.debug.service.model.DebuggerConnectDialog.FactoryEntry;
|
||||
import ghidra.app.plugin.core.debug.service.model.TestDebuggerProgramLaunchOpinion.TestDebuggerProgramLaunchOffer;
|
||||
import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer;
|
||||
import ghidra.app.services.ActionSource;
|
||||
import ghidra.app.services.TraceRecorder;
|
||||
import ghidra.async.AsyncPairingQueue;
|
||||
import ghidra.dbg.DebuggerModelFactory;
|
||||
|
@ -213,7 +214,7 @@ public class DebuggerModelServiceTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
|
||||
assertEquals(Set.of(), Set.copyOf(modelService.getTraceRecorders()));
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
|
||||
assertEquals(Set.of(recorder), Set.copyOf(modelService.getTraceRecorders()));
|
||||
}
|
||||
|
@ -228,7 +229,7 @@ public class DebuggerModelServiceTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
new CollectionChangeDelegateWrapper<>(recorderChangeListener);
|
||||
modelService.addTraceRecordersChangedListener(wrapper);
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
|
||||
new VerificationsInOrder() {
|
||||
{
|
||||
|
@ -243,7 +244,7 @@ public class DebuggerModelServiceTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
// Strong ref
|
||||
CollectionChangeDelegateWrapper<TraceRecorder> wrapper =
|
||||
new CollectionChangeDelegateWrapper<>(recorderChangeListener);
|
||||
|
@ -265,7 +266,7 @@ public class DebuggerModelServiceTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
assertNotNull(recorder);
|
||||
waitOn(recorder.init()); // Already initializing, just wait for it to complete
|
||||
|
||||
|
@ -300,7 +301,7 @@ public class DebuggerModelServiceTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
|
||||
assertEquals(recorder, modelService.getRecorder(mb.testProcess1));
|
||||
}
|
||||
|
@ -311,7 +312,7 @@ public class DebuggerModelServiceTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
|
||||
assertEquals(recorder, modelService.getRecorder(recorder.getTrace()));
|
||||
}
|
||||
|
@ -322,7 +323,7 @@ public class DebuggerModelServiceTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
|
||||
assertEquals(mb.testProcess1, modelService.getTarget(recorder.getTrace()));
|
||||
}
|
||||
|
@ -333,7 +334,7 @@ public class DebuggerModelServiceTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
|
||||
assertEquals(recorder.getTrace(), modelService.getTrace(mb.testProcess1));
|
||||
}
|
||||
|
@ -344,7 +345,7 @@ public class DebuggerModelServiceTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
|
||||
// The most complicated case, lest I want another dimension in a cross product
|
||||
mb.createTestThreadStacksAndFramesHaveRegisterBanks();
|
||||
|
@ -372,8 +373,8 @@ public class DebuggerModelServiceTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
|
||||
preRec.run();
|
||||
|
||||
modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
modelService.recordTarget(mb.testProcess1, createTargetTraceMapper(mb.testProcess1),
|
||||
ActionSource.AUTOMATIC);
|
||||
|
||||
postRec.run();
|
||||
|
||||
|
@ -419,8 +420,8 @@ public class DebuggerModelServiceTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
createTestModel();
|
||||
mb.createTestProcessesAndThreads();
|
||||
|
||||
modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
modelService.recordTarget(mb.testProcess1, createTargetTraceMapper(mb.testProcess1),
|
||||
ActionSource.AUTOMATIC);
|
||||
|
||||
// The most complicated case, lest I want another dimension in a cross product
|
||||
mb.createTestThreadStacksAndFramesHaveRegisterBanks();
|
||||
|
@ -439,9 +440,9 @@ public class DebuggerModelServiceTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
|
||||
// NOTE: getTargetFocus assumes the target is being recorded
|
||||
modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
modelService.recordTarget(mb.testProcess3,
|
||||
createTargetTraceMapper(mb.testProcess3));
|
||||
createTargetTraceMapper(mb.testProcess3), ActionSource.AUTOMATIC);
|
||||
|
||||
assertNull(modelService.getTargetFocus(mb.testProcess1));
|
||||
assertNull(modelService.getTargetFocus(mb.testProcess3));
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.google.common.collect.Range;
|
|||
|
||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
|
||||
import ghidra.app.plugin.core.debug.mapping.DebuggerRegisterMapper;
|
||||
import ghidra.app.services.ActionSource;
|
||||
import ghidra.app.services.TraceRecorder;
|
||||
import ghidra.dbg.model.TestTargetMemoryRegion;
|
||||
import ghidra.dbg.model.TestTargetRegisterBankInThread;
|
||||
|
@ -48,7 +49,7 @@ public class DefaultTraceRecorderTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
waitForPass(() -> {
|
||||
assertNotNull(recorder.getTraceThread(mb.testThread1));
|
||||
assertNotNull(recorder.getTraceThread(mb.testThread2));
|
||||
|
@ -61,7 +62,7 @@ public class DefaultTraceRecorderTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
|
||||
TestTargetMemoryRegion targetRegion =
|
||||
|
@ -97,7 +98,7 @@ public class DefaultTraceRecorderTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
Language lang = trace.getBaseLanguage();
|
||||
Register r0 = lang.getRegister("r0");
|
||||
|
@ -131,7 +132,7 @@ public class DefaultTraceRecorderTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
Language lang = trace.getBaseLanguage();
|
||||
Register pc = lang.getRegister("pc");
|
||||
|
@ -180,7 +181,7 @@ public class DefaultTraceRecorderTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
Language lang = trace.getBaseLanguage();
|
||||
Register pc = lang.getRegister("pc");
|
||||
|
@ -229,7 +230,7 @@ public class DefaultTraceRecorderTest extends AbstractGhidraHeadedDebuggerGUITes
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
Language lang = trace.getBaseLanguage();
|
||||
Register pc = lang.getRegister("pc");
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.junit.experimental.categories.Category;
|
|||
import generic.test.category.NightlyCategory;
|
||||
import ghidra.app.plugin.core.debug.DebuggerCoordinates;
|
||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
|
||||
import ghidra.app.services.ActionSource;
|
||||
import ghidra.app.services.TraceRecorder;
|
||||
import ghidra.dbg.model.TestTargetStack;
|
||||
import ghidra.dbg.model.TestTargetStackFrameHasRegisterBank;
|
||||
|
@ -296,7 +297,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
|
||||
traceManager.openTrace(trace);
|
||||
|
@ -337,7 +338,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
|
||||
waitForValue(() -> modelService.getTarget(trace));
|
||||
|
@ -399,7 +400,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
|||
mb.createTestProcessesAndThreads();
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
Trace trace = recorder.getTrace();
|
||||
|
||||
traceManager.openTrace(trace);
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.junit.Test;
|
|||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
|
||||
import ghidra.app.plugin.core.debug.mapping.DebuggerRegisterMapper;
|
||||
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
|
||||
import ghidra.app.services.ActionSource;
|
||||
import ghidra.app.services.TraceRecorder;
|
||||
import ghidra.dbg.model.TestTargetRegisterBankInThread;
|
||||
import ghidra.dbg.testutil.DebuggerModelTestUtils;
|
||||
|
@ -50,7 +51,7 @@ public class TraceRecorderAsyncPcodeExecTest extends AbstractGhidraHeadedDebugge
|
|||
"r1", new byte[] { 6 })));
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
|
||||
TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
|
||||
Trace trace = recorder.getTrace();
|
||||
|
@ -93,7 +94,7 @@ public class TraceRecorderAsyncPcodeExecTest extends AbstractGhidraHeadedDebugge
|
|||
"r1", new byte[] { 6 })));
|
||||
|
||||
TraceRecorder recorder = modelService.recordTarget(mb.testProcess1,
|
||||
createTargetTraceMapper(mb.testProcess1));
|
||||
createTargetTraceMapper(mb.testProcess1), ActionSource.AUTOMATIC);
|
||||
|
||||
TraceThread thread = waitForValue(() -> recorder.getTraceThread(mb.testThread1));
|
||||
Trace trace = recorder.getTrace();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue