GP-3857: Port most Debugger components to TraceRmi.

This commit is contained in:
Dan 2023-11-02 10:43:31 -04:00
parent 7e4d2bcfaa
commit fd4380c07a
222 changed files with 7241 additions and 3752 deletions

View file

@ -365,6 +365,10 @@ public class DBTraceObjectBreakpointLocation
return object;
}
public TraceObjectBreakpointSpec getOrCreateSpecification() {
return object.queryOrCreateCanonicalAncestorInterface(TraceObjectBreakpointSpec.class);
}
@Override
public TraceObjectBreakpointSpec getSpecification() {
try (LockHold hold = object.getTrace().lockRead()) {

View file

@ -46,7 +46,7 @@ public class DBTraceObjectBreakpointSpec
implements TraceObjectBreakpointSpec, DBTraceObjectInterface {
private final DBTraceObject object;
private TraceBreakpointKindSet kinds;
private TraceBreakpointKindSet kinds = TraceBreakpointKindSet.of();
public DBTraceObjectBreakpointSpec(DBTraceObject object) {
this.object = object;

View file

@ -312,7 +312,8 @@ public class DBTraceObjectMemoryRegion implements TraceObjectMemoryRegion, DBTra
public Set<TraceMemoryFlag> getFlags(long snap) {
EnumSet<TraceMemoryFlag> result = EnumSet.noneOf(TraceMemoryFlag.class);
for (TraceMemoryFlag flag : TraceMemoryFlag.values()) {
if (object.getValue(snap, keyForFlag(flag)) != null) {
TraceObjectValue value = object.getValue(snap, keyForFlag(flag));
if (value != null && value.getValue() == Boolean.TRUE) {
result.add(flag);
}
}

View file

@ -863,6 +863,22 @@ public class DBTraceObject extends DBAnnotatedObject implements TraceObject {
.map(p -> p.getSource(this).queryInterface(ifClass));
}
public TraceObject queryOrCreateCanonicalAncestorTargetInterface(
Class<? extends TargetObject> targetIf) {
PathMatcher matcher = getManager().getRootSchema().searchFor(targetIf, false);
return path.streamMatchingAncestry(matcher)
.limit(1)
.map(kp -> manager.createObject(kp))
.findAny()
.orElseThrow();
}
public <I extends TraceObjectInterface> I queryOrCreateCanonicalAncestorInterface(
Class<I> ifClass) {
return queryOrCreateCanonicalAncestorTargetInterface(
TraceObjectInterfaceUtils.toTargetIf(ifClass)).queryInterface(ifClass);
}
@Override
public Stream<? extends TraceObject> queryCanonicalAncestorsTargetInterface(
Class<? extends TargetObject> targetIf) {

View file

@ -37,6 +37,7 @@ import ghidra.program.model.address.*;
import ghidra.program.model.lang.Language;
import ghidra.trace.database.DBTrace;
import ghidra.trace.database.DBTraceManager;
import ghidra.trace.database.breakpoint.DBTraceObjectBreakpointLocation;
import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMap;
import ghidra.trace.database.map.DBTraceAddressSnapRangePropertyMapTree.TraceAddressSnapRangeQuery;
import ghidra.trace.database.module.TraceObjectSection;
@ -45,8 +46,7 @@ import ghidra.trace.database.target.visitors.SuccessorsRelativeVisitor;
import ghidra.trace.database.thread.DBTraceObjectThread;
import ghidra.trace.model.*;
import ghidra.trace.model.Trace.TraceObjectChangeType;
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
import ghidra.trace.model.breakpoint.TraceObjectBreakpointLocation;
import ghidra.trace.model.breakpoint.*;
import ghidra.trace.model.memory.*;
import ghidra.trace.model.modules.TraceObjectModule;
import ghidra.trace.model.stack.TraceObjectStack;
@ -599,14 +599,17 @@ public class DBTraceObjectManager implements TraceObjectManager, DBTraceManager
"breakpoint specification on the given path.");
}
try (LockHold hold = trace.lockWrite()) {
TraceObjectBreakpointLocation loc =
doAddWithInterface(path, TraceObjectBreakpointLocation.class);
DBTraceObjectBreakpointLocation loc =
(DBTraceObjectBreakpointLocation) doAddWithInterface(path,
TraceObjectBreakpointLocation.class);
loc.setName(lifespan, path);
loc.setRange(lifespan, range);
// NB. Ignore threads. I'd like to deprecate that field, anyway.
loc.setKinds(lifespan, kinds);
loc.setEnabled(lifespan, enabled);
loc.setComment(lifespan, comment);
TraceObjectBreakpointSpec spec = loc.getOrCreateSpecification();
// NB. Ignore threads. I'd like to deprecate that field, anyway.
spec.setKinds(lifespan, kinds);
loc.getObject().insert(lifespan, ConflictResolution.DENY);
return loc;
}

View file

@ -89,7 +89,8 @@ public class CanonicalSuccessorsRelativeVisitor implements Visitor {
Stream<TraceObjectValue> restStream = nextKeys.stream()
.filter(k -> !"".equals(k) && !"[]".equals(k))
.map(k -> getCanonicalValue(object, k));
.map(k -> getCanonicalValue(object, k))
.filter(v -> v != null);
return Stream.concat(Stream.concat(attrStream, elemStream), restStream);
}

View file

@ -15,6 +15,7 @@
*/
package ghidra.trace.database.target.visitors;
import java.util.Objects;
import java.util.stream.Stream;
import ghidra.trace.model.Lifespan;
@ -180,6 +181,7 @@ public enum TreeTraversal {
*/
public Stream<? extends TraceObjectValPath> walkValue(Visitor visitor,
TraceObjectValue value, Lifespan span, TraceObjectValPath path) {
Objects.requireNonNull(value);
Lifespan compSpan = visitor.composeSpan(span, value);
if (compSpan == null) {
return Stream.empty();

View file

@ -52,7 +52,7 @@ public interface TraceMemoryManager extends TraceMemoryOperations {
* <p>
* NOTE: We are also moving away from (space, thread, frame) triples to uniquely identify
* register storage. Instead, that will be encoded into the address space itself. Register
* overlays will overlay register space as be named after the register container object, which
* overlays will overlay register space and be named after the register container object, which
* subsumes thread and frame when applicable.
*
* @param name the name of the new address space

View file

@ -26,7 +26,6 @@ import ghidra.dbg.util.PathPattern;
import ghidra.dbg.util.PathPredicates;
import ghidra.trace.model.*;
import ghidra.trace.model.Lifespan.LifeSet;
import ghidra.trace.model.target.TraceObject.ConflictResolution;
/**
* The trace record of an observed {@link TargetObject}

View file

@ -32,6 +32,7 @@ import db.DBHandle;
import db.Transaction;
import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.plugin.processors.sleigh.SleighLanguage;
import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState;
import ghidra.dbg.util.PathPredicates;
import ghidra.pcode.exec.*;
import ghidra.pcode.exec.trace.TraceSleighUtils;
@ -49,12 +50,15 @@ import ghidra.trace.database.bookmark.*;
import ghidra.trace.database.listing.*;
import ghidra.trace.database.memory.DBTraceMemoryManager;
import ghidra.trace.database.symbol.DBTraceReference;
import ghidra.trace.database.target.DBTraceObjectManager;
import ghidra.trace.database.thread.DBTraceThreadManager;
import ghidra.trace.model.*;
import ghidra.trace.model.guest.TraceGuestPlatform;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.symbol.TraceReferenceManager;
import ghidra.trace.model.target.*;
import ghidra.trace.model.target.TraceObject.ConflictResolution;
import ghidra.trace.model.thread.TraceObjectThread;
import ghidra.trace.model.thread.TraceThread;
import ghidra.util.Msg;
import ghidra.util.database.DBOpenMode;
@ -754,6 +758,33 @@ public class ToyDBTraceBuilder implements AutoCloseable {
return getLanguage(langID).getCompilerSpecByID(new CompilerSpecID(compID));
}
public void createObjectsProcessAndThreads() {
DBTraceObjectManager objs = trace.getObjectManager();
TraceObjectKeyPath pathProc1 = TraceObjectKeyPath.parse("Processes[1]");
TraceObject proc1 = objs.createObject(pathProc1);
Lifespan zeroOn = Lifespan.nowOn(0);
proc1.insert(zeroOn, ConflictResolution.DENY);
TraceObject t1 = objs.createObject(pathProc1.key("Threads").index(1));
t1.insert(zeroOn, ConflictResolution.DENY);
TraceObject t2 = objs.createObject(pathProc1.key("Threads").index(2));
t2.insert(zeroOn, ConflictResolution.DENY);
proc1.setAttribute(zeroOn, "_state", TargetExecutionState.STOPPED.name());
}
public void createObjectsFramesAndRegs(TraceObjectThread thread, Lifespan lifespan,
TracePlatform platform, int n) {
DBTraceObjectManager objs = trace.getObjectManager();
TraceObjectKeyPath pathThread = thread.getObject().getCanonicalPath();
for (int i = 0; i < n; i++) {
TraceObjectKeyPath pathContainer = pathThread.key("Stack").index(i).key("Registers");
for (Register reg : platform.getLanguage().getRegisters()) {
TraceObject regObj = objs.createObject(pathContainer.index(reg.getName()));
regObj.insert(lifespan, ConflictResolution.DENY);
}
}
}
/**
* Get an object by its canonical path
*
@ -765,7 +796,6 @@ public class ToyDBTraceBuilder implements AutoCloseable {
.getObjectByCanonicalPath(TraceObjectKeyPath.parse(canonicalPath));
}
/**
* Get an object by its path pattern
*
@ -775,8 +805,10 @@ public class ToyDBTraceBuilder implements AutoCloseable {
public TraceObject objAny(String pat) {
return objAny(pat, Lifespan.at(0));
}
public TraceObject objAny(String path, Lifespan span) {
return trace.getObjectManager().getObjectsByPath(span, TraceObjectKeyPath.parse(path))
return trace.getObjectManager()
.getObjectsByPath(span, TraceObjectKeyPath.parse(path))
.findFirst()
.orElse(null);
}
@ -795,7 +827,7 @@ public class ToyDBTraceBuilder implements AutoCloseable {
}
/**
* List all values matching the given pattern at the given stnap.
* List all values matching the given pattern at the given snap.
*
* @param snap the snap
* @param pattern the pattern