mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-1978: Port tests to TraceRmi and delete more stuff.
This commit is contained in:
parent
dadfc465df
commit
5813548a84
110 changed files with 1762 additions and 17529 deletions
|
@ -664,7 +664,7 @@ public abstract class AbstractTraceRmiLaunchOffer implements TraceRmiLaunchOffer
|
|||
trace = connection.waitForTrace(getTimeoutMillis());
|
||||
traceManager.openTrace(trace);
|
||||
traceManager.activate(traceManager.resolveTrace(trace),
|
||||
ActivationCause.START_RECORDING);
|
||||
ActivationCause.TARGET_UPDATED);
|
||||
monitor.increment();
|
||||
|
||||
waitForModuleMapping(monitor, connection, trace);
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/* ###
|
||||
* 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.service.tracermi;
|
||||
|
||||
import ghidra.app.services.DebuggerControlService;
|
||||
import ghidra.app.services.DebuggerTraceManagerService;
|
||||
import ghidra.app.services.DebuggerTraceManagerService.ActivationCause;
|
||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||
import ghidra.debug.api.tracermi.TraceRmiConnection;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.time.TraceSnapshot;
|
||||
import ghidra.util.Swing;
|
||||
|
||||
public abstract class AbstractTraceRmiConnection implements TraceRmiConnection {
|
||||
|
||||
protected abstract DebuggerTraceManagerService getTraceManager();
|
||||
|
||||
protected abstract DebuggerControlService getControlService();
|
||||
|
||||
protected abstract boolean ownsTrace(Trace trace);
|
||||
|
||||
protected boolean followsPresent(Trace trace) {
|
||||
DebuggerControlService controlService = getControlService();
|
||||
if (controlService == null) {
|
||||
return true;
|
||||
}
|
||||
return controlService.getCurrentMode(trace).followsPresent();
|
||||
}
|
||||
|
||||
protected void doActivate(TraceObject object, Trace trace, TraceSnapshot snapshot) {
|
||||
DebuggerCoordinates coords = getTraceManager().getCurrent();
|
||||
if (coords.getTrace() != trace) {
|
||||
coords = DebuggerCoordinates.NOWHERE;
|
||||
}
|
||||
if (snapshot != null && followsPresent(trace)) {
|
||||
coords = coords.snap(snapshot.getKey());
|
||||
}
|
||||
DebuggerCoordinates finalCoords = object == null ? coords : coords.object(object);
|
||||
Swing.runLater(() -> {
|
||||
DebuggerTraceManagerService traceManager = getTraceManager();
|
||||
if (traceManager == null) {
|
||||
// Can happen during tear down.
|
||||
return;
|
||||
}
|
||||
if (!traceManager.getOpenTraces().contains(trace)) {
|
||||
traceManager.openTrace(trace);
|
||||
traceManager.activate(finalCoords, ActivationCause.SYNC_MODEL);
|
||||
}
|
||||
else {
|
||||
Trace currentTrace = traceManager.getCurrentTrace();
|
||||
if (currentTrace == null || ownsTrace(currentTrace)) {
|
||||
traceManager.activate(finalCoords, ActivationCause.SYNC_MODEL);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -35,7 +35,6 @@ import ghidra.app.plugin.core.debug.disassemble.DebuggerDisassemblerPlugin;
|
|||
import ghidra.app.plugin.core.debug.disassemble.TraceDisassembleCommand;
|
||||
import ghidra.app.services.DebuggerControlService;
|
||||
import ghidra.app.services.DebuggerTraceManagerService;
|
||||
import ghidra.app.services.DebuggerTraceManagerService.ActivationCause;
|
||||
import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName;
|
||||
import ghidra.dbg.target.schema.XmlSchemaContext;
|
||||
import ghidra.dbg.util.PathPattern;
|
||||
|
@ -43,7 +42,6 @@ import ghidra.dbg.util.PathUtils;
|
|||
import ghidra.debug.api.progress.CloseableTaskMonitor;
|
||||
import ghidra.debug.api.target.ActionName;
|
||||
import ghidra.debug.api.target.Target;
|
||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||
import ghidra.debug.api.tracermi.*;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.model.*;
|
||||
|
@ -67,7 +65,7 @@ import ghidra.util.*;
|
|||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.DuplicateFileException;
|
||||
|
||||
public class TraceRmiHandler implements TraceRmiConnection {
|
||||
public class TraceRmiHandler extends AbstractTraceRmiConnection {
|
||||
public static final String VERSION = "11.2";
|
||||
|
||||
protected static class VersionMismatchError extends TraceRmiError {
|
||||
|
@ -817,42 +815,25 @@ public class TraceRmiHandler implements TraceRmiConnection {
|
|||
return makeArgument(ent.getKey(), ent.getValue());
|
||||
}
|
||||
|
||||
protected boolean followsPresent(Trace trace) {
|
||||
DebuggerControlService controlService = this.controlService;
|
||||
if (controlService == null) {
|
||||
return true;
|
||||
}
|
||||
return controlService.getCurrentMode(trace).followsPresent();
|
||||
@Override
|
||||
protected DebuggerTraceManagerService getTraceManager() {
|
||||
return this.traceManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DebuggerControlService getControlService() {
|
||||
return this.controlService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean ownsTrace(Trace trace) {
|
||||
return openTraces.getByTrace(trace) != null;
|
||||
}
|
||||
|
||||
protected ReplyActivate handleActivate(RequestActivate req) {
|
||||
OpenTrace open = requireOpenTrace(req.getOid());
|
||||
TraceObject object = open.getObject(req.getObject(), false);
|
||||
DebuggerCoordinates coords = traceManager.getCurrent();
|
||||
if (coords.getTrace() != open.trace) {
|
||||
coords = DebuggerCoordinates.NOWHERE;
|
||||
}
|
||||
if (open.lastSnapshot != null && followsPresent(open.trace)) {
|
||||
coords = coords.snap(open.lastSnapshot.getKey());
|
||||
}
|
||||
DebuggerCoordinates finalCoords = object == null ? coords : coords.object(object);
|
||||
Swing.runLater(() -> {
|
||||
DebuggerTraceManagerService traceManager = this.traceManager;
|
||||
if (traceManager == null) {
|
||||
// Can happen during tear down.
|
||||
return;
|
||||
}
|
||||
if (!traceManager.getOpenTraces().contains(open.trace)) {
|
||||
traceManager.openTrace(open.trace);
|
||||
traceManager.activate(finalCoords, ActivationCause.SYNC_MODEL);
|
||||
}
|
||||
else {
|
||||
Trace currentTrace = traceManager.getCurrentTrace();
|
||||
if (currentTrace == null || openTraces.getByTrace(currentTrace) != null) {
|
||||
traceManager.activate(finalCoords, ActivationCause.SYNC_MODEL);
|
||||
}
|
||||
}
|
||||
});
|
||||
doActivate(object, open.trace, open.lastSnapshot);
|
||||
return ReplyActivate.getDefaultInstance();
|
||||
}
|
||||
|
||||
|
|
|
@ -334,10 +334,12 @@ public class TraceRmiTarget extends AbstractTarget {
|
|||
ActionName.STEP_OUT.equals(name) ||
|
||||
ActionName.STEP_OVER.equals(name) ||
|
||||
ActionName.STEP_SKIP.equals(name)) {
|
||||
return () -> whenState(obj, state -> state != null && (state.isStopped() || state.isUnknown()));
|
||||
return () -> whenState(obj,
|
||||
state -> state != null && (state.isStopped() || state.isUnknown()));
|
||||
}
|
||||
else if (ActionName.INTERRUPT.equals(name)) {
|
||||
return () -> whenState(obj, state -> state == null || state.isRunning() || state.isUnknown());
|
||||
return () -> whenState(obj,
|
||||
state -> state == null || state.isRunning() || state.isUnknown());
|
||||
}
|
||||
else if (ActionName.KILL.equals(name)) {
|
||||
return () -> whenState(obj, state -> state == null || !state.isTerminated());
|
||||
|
@ -1211,13 +1213,13 @@ public class TraceRmiTarget extends AbstractTarget {
|
|||
.thenApply(__ -> null);
|
||||
}
|
||||
|
||||
protected boolean isMemorySpaceValid(AddressSpace space) {
|
||||
return trace.getBaseAddressFactory().getAddressSpace(space.getSpaceID()) == space;
|
||||
protected boolean isMemorySpaceValid(TracePlatform platform, AddressSpace space) {
|
||||
return platform.getAddressFactory().getAddressSpace(space.getSpaceID()) == space;
|
||||
}
|
||||
|
||||
protected boolean isRegisterValid(TracePlatform platform, TraceThread thread, int frame,
|
||||
Address address, int length) {
|
||||
if (!isMemorySpaceValid(address.getAddressSpace())) {
|
||||
if (!isMemorySpaceValid(platform, address.getAddressSpace())) {
|
||||
return false;
|
||||
}
|
||||
Register register =
|
||||
|
@ -1239,7 +1241,7 @@ public class TraceRmiTarget extends AbstractTarget {
|
|||
public boolean isVariableExists(TracePlatform platform, TraceThread thread, int frame,
|
||||
Address address, int length) {
|
||||
if (address.isMemoryAddress()) {
|
||||
return isMemorySpaceValid(address.getAddressSpace());
|
||||
return isMemorySpaceValid(platform, address.getAddressSpace());
|
||||
}
|
||||
if (address.isRegisterAddress()) {
|
||||
return isRegisterValid(platform, thread, frame, address, length);
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* 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.
|
||||
|
@ -24,9 +24,9 @@ import java.util.function.Function;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import db.Transaction;
|
||||
import ghidra.app.services.DebuggerTargetService;
|
||||
import ghidra.async.AsyncPairingQueue;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.async.*;
|
||||
import ghidra.dbg.target.schema.TargetObjectSchema;
|
||||
import ghidra.dbg.target.schema.TargetObjectSchema.SchemaName;
|
||||
import ghidra.debug.api.target.ActionName;
|
||||
|
@ -34,12 +34,14 @@ import ghidra.debug.api.target.Target;
|
|||
import ghidra.debug.api.tracermi.*;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.time.TraceSnapshot;
|
||||
|
||||
public class TestTraceRmiConnection implements TraceRmiConnection {
|
||||
public abstract class TestTraceRmiConnection extends AbstractTraceRmiConnection {
|
||||
|
||||
protected final TestRemoteMethodRegistry registry = new TestRemoteMethodRegistry();
|
||||
protected final CompletableFuture<Trace> firstTrace = new CompletableFuture<>();
|
||||
protected final Map<Trace, Long> snapshots = new HashMap<>();
|
||||
protected final Map<Trace, TraceSnapshot> snapshots = new HashMap<>();
|
||||
protected final CompletableFuture<Void> closed = new CompletableFuture<>();
|
||||
protected final Map<Trace, TraceRmiTarget> targets = new HashMap<>();
|
||||
|
||||
|
@ -88,8 +90,9 @@ public class TestTraceRmiConnection implements TraceRmiConnection {
|
|||
return result;
|
||||
}
|
||||
|
||||
public Map<String, Object> expect() throws InterruptedException, ExecutionException {
|
||||
return argQueue.take().get();
|
||||
public Map<String, Object> expect()
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
return argQueue.take().get(AsyncTestUtils.TIMEOUT_MS, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public void result(Object ret) {
|
||||
|
@ -98,8 +101,7 @@ public class TestTraceRmiConnection implements TraceRmiConnection {
|
|||
|
||||
public CompletableFuture<Map<String, Object>> expect(
|
||||
Function<Map<String, Object>, Object> impl) {
|
||||
record ArgsRet(Map<String, Object> args, Object ret) {
|
||||
}
|
||||
record ArgsRet(Map<String, Object> args, Object ret) {}
|
||||
var result = argQueue().take().thenApply(a -> new ArgsRet(a, impl.apply(a)));
|
||||
result.thenApply(ar -> ar.ret).handle(AsyncUtils.copyTo(retQueue().give()));
|
||||
return result.thenApply(ar -> ar.args);
|
||||
|
@ -149,6 +151,15 @@ public class TestTraceRmiConnection implements TraceRmiConnection {
|
|||
return target;
|
||||
}
|
||||
|
||||
public void withdrawTarget(PluginTool tool, Trace trace) {
|
||||
Target target;
|
||||
synchronized (targets) {
|
||||
target = targets.remove(trace);
|
||||
}
|
||||
DebuggerTargetService targetService = tool.getService(DebuggerTargetService.class);
|
||||
targetService.withdrawTarget(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trace waitForTrace(long timeoutMillis) throws TimeoutException {
|
||||
try {
|
||||
|
@ -159,17 +170,21 @@ public class TestTraceRmiConnection implements TraceRmiConnection {
|
|||
}
|
||||
}
|
||||
|
||||
public void setLastSnapshot(Trace trace, long snap) {
|
||||
public TraceSnapshot setLastSnapshot(Trace trace, long snap) {
|
||||
synchronized (snapshots) {
|
||||
snapshots.put(trace, snap);
|
||||
try (Transaction tx = trace.openTransaction("Add snapshot")) {
|
||||
TraceSnapshot snapshot = trace.getTimeManager().getSnapshot(snap, true);
|
||||
snapshots.put(trace, snapshot);
|
||||
return snapshot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastSnapshot(Trace trace) {
|
||||
synchronized (snapshots) {
|
||||
Long snap = snapshots.get(trace);
|
||||
return snap == null ? 0 : snap;
|
||||
TraceSnapshot snap = snapshots.get(trace);
|
||||
return snap == null ? 0 : snap.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,4 +240,14 @@ public class TestTraceRmiConnection implements TraceRmiConnection {
|
|||
public Collection<Target> getTargets() {
|
||||
return List.copyOf(targets.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean ownsTrace(Trace trace) {
|
||||
return targets.containsKey(trace);
|
||||
}
|
||||
|
||||
public void synthActivate(TraceObject object) {
|
||||
Trace trace = object.getTrace();
|
||||
doActivate(object, trace, snapshots.get(trace));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue