mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-31 17:07:41 +08:00
GP-5194: Remove Deprecated 'Legacy mode' for DBTrace.
This commit is contained in:
+12
-22
@@ -100,9 +100,10 @@ import ghidra.program.util.GhidraProgramUtilities;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.pty.*;
|
||||
import ghidra.test.TestEnv;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.modules.*;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
import ghidra.trace.model.modules.TraceSection;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.trace.model.time.schedule.*;
|
||||
import ghidra.util.InvalidNameException;
|
||||
@@ -322,16 +323,12 @@ public class TutorialDebuggerScreenShots extends GhidraScreenShotGenerator
|
||||
}
|
||||
|
||||
protected void waitBreakSpecExists(String expression) {
|
||||
long snap = flatDbg.getCurrentSnap();
|
||||
waitForCondition(() -> flatDbg.getAllBreakpoints()
|
||||
.stream()
|
||||
.flatMap(lb -> lb.getTraceBreakpoints().stream())
|
||||
.<TraceObjectBreakpointSpec> mapMulti((loc, down) -> {
|
||||
if (loc instanceof TraceObjectBreakpointLocation oloc) {
|
||||
down.accept(oloc.getSpecification());
|
||||
}
|
||||
})
|
||||
.distinct()
|
||||
.filter(l -> expression.equals(l.getExpression(flatDbg.getCurrentSnap())))
|
||||
.filter(l -> expression.equals(l.getSpecification().getExpression(snap)))
|
||||
.count() == 1);
|
||||
}
|
||||
|
||||
@@ -361,14 +358,9 @@ public class TutorialDebuggerScreenShots extends GhidraScreenShotGenerator
|
||||
|
||||
protected Address navigateToBreakpoint(String expression) {
|
||||
long snap = flatDbg.getCurrentSnap();
|
||||
TraceBreakpoint bp = flatDbg.getAllBreakpoints()
|
||||
TraceBreakpointLocation bp = flatDbg.getAllBreakpoints()
|
||||
.stream()
|
||||
.flatMap(l -> l.getTraceBreakpoints().stream())
|
||||
.<TraceObjectBreakpointLocation> mapMulti((loc, down) -> {
|
||||
if (loc instanceof TraceObjectBreakpointLocation oloc) {
|
||||
down.accept(oloc);
|
||||
}
|
||||
})
|
||||
.filter(l -> expression.equals(l.getSpecification().getExpression(snap)))
|
||||
.findAny()
|
||||
.get();
|
||||
@@ -642,10 +634,9 @@ public class TutorialDebuggerScreenShots extends GhidraScreenShotGenerator
|
||||
.getSnapshot(snapA, false)
|
||||
.setDescription("Initial snapshot");
|
||||
}
|
||||
TraceObjectModule modTermmines =
|
||||
(TraceObjectModule) Unique.assertOne(flatDbg.getCurrentTrace()
|
||||
.getModuleManager()
|
||||
.getModulesAt(snapA, pc));
|
||||
TraceModule modTermmines = Unique.assertOne(flatDbg.getCurrentTrace()
|
||||
.getModuleManager()
|
||||
.getModulesAt(snapA, pc));
|
||||
|
||||
RemoteMethod refreshSections = result.connection().getMethods().get("refresh_sections");
|
||||
refreshSections.invoke(Map.of("node", modTermmines.getObject()));
|
||||
@@ -679,10 +670,9 @@ public class TutorialDebuggerScreenShots extends GhidraScreenShotGenerator
|
||||
.getSnapshot(snapA, false)
|
||||
.setDescription("Initial snapshot");
|
||||
}
|
||||
TraceObjectModule modTermmines =
|
||||
(TraceObjectModule) Unique.assertOne(flatDbg.getCurrentTrace()
|
||||
.getModuleManager()
|
||||
.getModulesAt(snapA, pc));
|
||||
TraceModule modTermmines = Unique.assertOne(flatDbg.getCurrentTrace()
|
||||
.getModuleManager()
|
||||
.getModulesAt(snapA, pc));
|
||||
|
||||
RemoteMethod refreshSections = result.connection().getMethods().get("refresh_sections");
|
||||
refreshSections.invoke(Map.of("node", modTermmines.getObject()));
|
||||
|
||||
+2
-2
@@ -41,7 +41,7 @@ import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.memory.TraceMemoryState;
|
||||
import ghidra.trace.model.stack.TraceObjectStackFrame;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.TraceObject.ConflictResolution;
|
||||
import ghidra.trace.model.target.TraceObjectManager;
|
||||
@@ -417,7 +417,7 @@ public class AbstractGhidraHeadedDebuggerIntegrationTest
|
||||
args);
|
||||
}
|
||||
|
||||
protected void handleWriteRegInvocation(TraceObjectStackFrame frame, String name, long value)
|
||||
protected void handleWriteRegInvocation(TraceStackFrame frame, String name, long value)
|
||||
throws Throwable {
|
||||
Map<String, Object> args = rmiMethodWriteReg.expect();
|
||||
rmiMethodWriteReg.result(null);
|
||||
|
||||
+11
-12
@@ -23,7 +23,6 @@ import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.swing.MenuElement;
|
||||
import javax.swing.SwingUtilities;
|
||||
@@ -62,9 +61,9 @@ import ghidra.program.model.mem.MemoryConflictException;
|
||||
import ghidra.program.model.symbol.SourceType;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.program.TraceProgramView;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
@@ -77,7 +76,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
SystemUtilities.isInTestingBatchMode() ? 5000 : Long.MAX_VALUE;
|
||||
|
||||
protected static final Map<State, Color> COLOR_FOR_STATE =
|
||||
Stream.of(State.values()).collect(Collectors.toMap(s -> s, s -> new Color(s.ordinal())));
|
||||
State.VALUES.stream().collect(Collectors.toMap(s -> s, s -> new Color(s.ordinal())));
|
||||
|
||||
protected static final Set<String> POPUP_ACTIONS = Set.of(AbstractSetBreakpointAction.NAME,
|
||||
AbstractToggleBreakpointAction.NAME, AbstractEnableBreakpointAction.NAME,
|
||||
@@ -109,7 +108,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
*/
|
||||
protected void hackMarkerBackgroundColors(Program p) throws Exception {
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
for (State state : State.values()) {
|
||||
for (State state : State.VALUES) {
|
||||
if (state == State.NONE) {
|
||||
continue;
|
||||
}
|
||||
@@ -153,11 +152,11 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
protected abstract void handleSetBreakpointInvocation(Set<TraceBreakpointKind> expectedKinds,
|
||||
long dynOffset) throws Throwable;
|
||||
|
||||
protected abstract void handleToggleBreakpointInvocation(TraceBreakpoint expectedBreakpoint,
|
||||
boolean expectedEn) throws Throwable;
|
||||
protected abstract void handleToggleBreakpointInvocation(
|
||||
TraceBreakpointLocation expectedBreakpoint, boolean expectedEn) throws Throwable;
|
||||
|
||||
protected abstract void handleDeleteBreakpointInvocation(TraceBreakpoint expectedBreakpoint)
|
||||
throws Throwable;
|
||||
protected abstract void handleDeleteBreakpointInvocation(
|
||||
TraceBreakpointLocation expectedBreakpoint) throws Throwable;
|
||||
|
||||
@Before
|
||||
public void setUpBreakpointMarkerPluginTest() throws Exception {
|
||||
@@ -484,7 +483,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
throws Throwable {
|
||||
addMappedBreakpointOpenAndWait(); // wasteful, but whatever
|
||||
for (LogicalBreakpoint lb : List.copyOf(breakpointService.getAllBreakpoints())) {
|
||||
TraceBreakpoint brk = Unique.assertOne(lb.getTraceBreakpoints(tb.trace));
|
||||
TraceBreakpointLocation brk = Unique.assertOne(lb.getTraceBreakpoints(tb.trace));
|
||||
CompletableFuture<Void> delete = lb.delete();
|
||||
handleDeleteBreakpointInvocation(brk);
|
||||
waitOn(delete);
|
||||
@@ -523,7 +522,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
public void testActionToggleBreakpointProgramWithNoCurrentBreakpointOnData() throws Throwable {
|
||||
addMappedBreakpointOpenAndWait(); // wasteful, but whatever
|
||||
for (LogicalBreakpoint lb : List.copyOf(breakpointService.getAllBreakpoints())) {
|
||||
TraceBreakpoint brk = Unique.assertOne(lb.getTraceBreakpoints(tb.trace));
|
||||
TraceBreakpointLocation brk = Unique.assertOne(lb.getTraceBreakpoints(tb.trace));
|
||||
CompletableFuture<Void> delete = lb.delete();
|
||||
handleDeleteBreakpointInvocation(brk);
|
||||
waitOn(delete);
|
||||
@@ -806,7 +805,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
|
||||
ProgramLocationActionContext ctx = staticCtx(addr(program, 0x00400123));
|
||||
assertTrue(breakpointMarkerPlugin.actionClearBreakpoint.isAddToPopup(ctx));
|
||||
TraceBreakpoint brk = Unique.assertOne(lb.getTraceBreakpoints(trace));
|
||||
TraceBreakpointLocation brk = Unique.assertOne(lb.getTraceBreakpoints(trace));
|
||||
performAction(breakpointMarkerPlugin.actionClearBreakpoint, ctx, true);
|
||||
handleDeleteBreakpointInvocation(brk);
|
||||
|
||||
@@ -821,7 +820,7 @@ public abstract class AbstractDebuggerBreakpointMarkerPluginTest<T>
|
||||
|
||||
ProgramLocationActionContext ctx = dynamicCtx(trace, addr(trace, 0x55550123));
|
||||
assertTrue(breakpointMarkerPlugin.actionClearBreakpoint.isAddToPopup(ctx));
|
||||
TraceBreakpoint brk = Unique.assertOne(lb.getTraceBreakpoints(trace));
|
||||
TraceBreakpointLocation brk = Unique.assertOne(lb.getTraceBreakpoints(trace));
|
||||
performAction(breakpointMarkerPlugin.actionClearBreakpoint, ctx, true);
|
||||
handleDeleteBreakpointInvocation(brk);
|
||||
|
||||
|
||||
+11
-10
@@ -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.
|
||||
@@ -49,9 +49,9 @@ import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.MemoryConflictException;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpoint;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.time.TraceSnapshot;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
@@ -85,7 +85,7 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
|
||||
|
||||
protected abstract void addLiveBreakpoint(T target, long offset) throws Throwable;
|
||||
|
||||
protected abstract void assertNotLiveBreakpoint(T target, TraceBreakpoint breakpoint)
|
||||
protected abstract void assertNotLiveBreakpoint(T target, TraceBreakpointLocation breakpoint)
|
||||
throws Throwable;
|
||||
|
||||
protected void addLiveMemoryAndBreakpoint(P process, T target) throws Throwable {
|
||||
@@ -96,8 +96,8 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
|
||||
protected abstract void handleSetBreakpointInvocation(Set<TraceBreakpointKind> expectedKinds,
|
||||
long dynOffset) throws Throwable;
|
||||
|
||||
protected abstract void handleToggleBreakpointInvocation(TraceBreakpoint expectedBreakpoint,
|
||||
boolean expectedEnabled) throws Throwable;
|
||||
protected abstract void handleToggleBreakpointInvocation(
|
||||
TraceBreakpointLocation expectedBreakpoint, boolean expectedEnabled) throws Throwable;
|
||||
|
||||
protected void addStaticMemoryAndBreakpoint() throws LockException, DuplicateNameException,
|
||||
MemoryConflictException, AddressOverflowException, CancelledException {
|
||||
@@ -600,8 +600,8 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
|
||||
assertEquals(Set.of(trace1, trace3), lb2.getParticipatingTraces());
|
||||
|
||||
// Sanity check / experiment: Equal fields, but from different traces
|
||||
TraceBreakpoint bl1t1 = Unique.assertOne(lb1.getTraceBreakpoints(trace1));
|
||||
TraceBreakpoint bl1t3 = Unique.assertOne(lb1.getTraceBreakpoints(trace3));
|
||||
TraceBreakpointLocation bl1t1 = Unique.assertOne(lb1.getTraceBreakpoints(trace1));
|
||||
TraceBreakpointLocation bl1t3 = Unique.assertOne(lb1.getTraceBreakpoints(trace3));
|
||||
assertNotEquals(bl1t1, bl1t3);
|
||||
|
||||
// OK, back to work
|
||||
@@ -710,6 +710,7 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
|
||||
// Do our own launch, so that object mode is enabled during load (region creation)
|
||||
createTrace(program.getLanguageID().getIdAsString());
|
||||
try (Transaction startTransaction = tb.startTransaction()) {
|
||||
ProgramEmulationUtils.createObjects(tb.trace);
|
||||
TraceSnapshot initial = tb.trace.getTimeManager().getSnapshot(0, true);
|
||||
ProgramEmulationUtils.loadExecutable(initial, program, List.of());
|
||||
Address pc = program.getMinAddress();
|
||||
@@ -767,8 +768,8 @@ public abstract class AbstractDebuggerBreakpointsProviderTest<T, P>
|
||||
|
||||
controlService.setCurrentMode(trace, ControlMode.RW_EMULATOR);
|
||||
lbRow1.setEnabled(true);
|
||||
TraceBreakpoint emuBpt = waitForValue(
|
||||
() -> Unique.assertAtMostOne(trace.getBreakpointManager().getAllBreakpoints()));
|
||||
TraceBreakpointLocation emuBpt = waitForValue(
|
||||
() -> Unique.assertAtMostOne(trace.getBreakpointManager().getAllBreakpointLocations()));
|
||||
assertNotLiveBreakpoint(target, emuBpt);
|
||||
|
||||
LogicalBreakpointRow lbRow2 =
|
||||
|
||||
+10
-15
@@ -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.
|
||||
@@ -28,8 +28,9 @@ import ghidra.app.plugin.core.debug.service.tracermi.TraceRmiTarget;
|
||||
import ghidra.trace.database.target.DBTraceObjectManager;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
|
||||
@Category(NightlyCategory.class)
|
||||
public class DebuggerRmiBreakpointMarkerPluginTest
|
||||
@@ -135,33 +136,27 @@ public class DebuggerRmiBreakpointMarkerPluginTest
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleToggleBreakpointInvocation(TraceBreakpoint expectedBreakpoint,
|
||||
protected void handleToggleBreakpointInvocation(TraceBreakpointLocation expectedLoc,
|
||||
boolean expectedEn) throws Throwable {
|
||||
if (!(expectedBreakpoint instanceof TraceObjectBreakpointLocation loc)) {
|
||||
throw new AssertionError("Unexpected trace breakpoint type: " + expectedBreakpoint);
|
||||
}
|
||||
Map<String, Object> args = rmiMethodToggleBreak.expect();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
loc.setEnabled(Lifespan.nowOn(0), expectedEn);
|
||||
expectedLoc.setEnabled(Lifespan.nowOn(0), expectedEn);
|
||||
}
|
||||
rmiMethodToggleBreak.result(null);
|
||||
assertEquals(Map.ofEntries(
|
||||
Map.entry("breakpoint", loc.getSpecification().getObject()),
|
||||
Map.entry("breakpoint", expectedLoc.getSpecification().getObject()),
|
||||
Map.entry("enabled", expectedEn)), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleDeleteBreakpointInvocation(TraceBreakpoint expectedBreakpoint)
|
||||
protected void handleDeleteBreakpointInvocation(TraceBreakpointLocation expectedLoc)
|
||||
throws Throwable {
|
||||
if (!(expectedBreakpoint instanceof TraceObjectBreakpointLocation loc)) {
|
||||
throw new AssertionError("Unexpected trace breakpoint type: " + expectedBreakpoint);
|
||||
}
|
||||
Map<String, Object> args = rmiMethodDeleteBreak.expect();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
loc.getObject().remove(Lifespan.nowOn(0));
|
||||
expectedLoc.getObject().remove(Lifespan.nowOn(0));
|
||||
}
|
||||
rmiMethodDeleteBreak.result(null);
|
||||
assertEquals(Map.ofEntries(
|
||||
Map.entry("breakpoint", loc.getSpecification().getObject())), args);
|
||||
Map.entry("breakpoint", expectedLoc.getSpecification().getObject())), args);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-11
@@ -27,9 +27,10 @@ import ghidra.app.plugin.core.debug.service.tracermi.TraceRmiTarget;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
|
||||
public class DebuggerRmiBreakpointsProviderTest
|
||||
extends AbstractDebuggerBreakpointsProviderTest<TraceRmiTarget, Trace> {
|
||||
@@ -107,7 +108,7 @@ public class DebuggerRmiBreakpointsProviderTest
|
||||
try (Transaction tx = trace.openTransaction("Add .text")) {
|
||||
Objects.requireNonNull(addMemoryRegion(trace.getObjectManager(), Lifespan.nowOn(0),
|
||||
tb.range(0x55550000, 0x55550fff), "bin:.text", "rx")
|
||||
.queryInterface(TraceObjectMemoryRegion.class));
|
||||
.queryInterface(TraceMemoryRegion.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,24 +140,21 @@ public class DebuggerRmiBreakpointsProviderTest
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleToggleBreakpointInvocation(TraceBreakpoint expectedBreakpoint,
|
||||
protected void handleToggleBreakpointInvocation(TraceBreakpointLocation expectedLoc,
|
||||
boolean expectedEn) throws Throwable {
|
||||
if (!(expectedBreakpoint instanceof TraceObjectBreakpointLocation loc)) {
|
||||
throw new AssertionError("Unexpected trace breakpoint type: " + expectedBreakpoint);
|
||||
}
|
||||
Map<String, Object> args = rmiMethodToggleBreak.expect();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
loc.setEnabled(Lifespan.nowOn(0), expectedEn);
|
||||
expectedLoc.setEnabled(Lifespan.nowOn(0), expectedEn);
|
||||
}
|
||||
rmiMethodToggleBreak.result(null);
|
||||
assertEquals(Map.ofEntries(
|
||||
Map.entry("breakpoint", loc.getSpecification().getObject()),
|
||||
Map.entry("breakpoint", expectedLoc.getSpecification().getObject()),
|
||||
Map.entry("enabled", expectedEn)), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertNotLiveBreakpoint(TraceRmiTarget target, TraceBreakpoint breakpoint)
|
||||
protected void assertNotLiveBreakpoint(TraceRmiTarget target, TraceBreakpointLocation loc)
|
||||
throws Throwable {
|
||||
// TODO: Not sure there's anything to do here
|
||||
// NOTE: Not sure there's anything to do here
|
||||
}
|
||||
}
|
||||
|
||||
+24
-6
@@ -54,11 +54,13 @@ import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.data.ShortDataType;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder.ToySchemaBuilder;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.TraceExecutionState;
|
||||
import ghidra.trace.model.memory.TraceMemoryFlag;
|
||||
import ghidra.trace.model.program.TraceVariableSnapProgramView;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.schema.SchemaContext;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.time.schedule.Scheduler;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule;
|
||||
@@ -247,17 +249,26 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerInteg
|
||||
() -> rmiMethodStepOut);
|
||||
}
|
||||
|
||||
SchemaContext buildContext() {
|
||||
return new ToySchemaBuilder()
|
||||
.noRegisterGroups()
|
||||
.useRegistersPerFrame()
|
||||
.build();
|
||||
}
|
||||
|
||||
TraceThread createToyLoopTrace() throws Throwable {
|
||||
createAndOpenTrace();
|
||||
|
||||
Address start = tb.addr(0x00400000);
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
Assembler asm = Assemblers.getAssembler(tb.language);
|
||||
AssemblyBuffer buf = new AssemblyBuffer(asm, start);
|
||||
buf.assemble("br 0x" + start);
|
||||
|
||||
thread = tb.getOrAddThread("Threads[0]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
tb.exec(0, thread, 0, "pc = 0x" + start + ";");
|
||||
tb.trace.getMemoryManager().putBytes(0, start, ByteBuffer.wrap(buf.getBytes()));
|
||||
}
|
||||
@@ -282,8 +293,10 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerInteg
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the UI so it does not error when the user presses resume after already stepped into a
|
||||
* pcode instruction.
|
||||
* Tests the UI so it does not error when the user presses resume after already stepping into a
|
||||
* p-code instruction.
|
||||
*
|
||||
* @throws Throwable because
|
||||
*/
|
||||
@Test
|
||||
public void testEmulateResumeActionAfterPcodeStep() throws Throwable {
|
||||
@@ -291,7 +304,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerInteg
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
traceManager.activateThread(thread);
|
||||
traceManager.activateTime(TraceSchedule.parse("0:.t0-2"));
|
||||
traceManager.activateTime(TraceSchedule.parse("0:.t%d-2".formatted(thread.getKey())));
|
||||
waitForSwing();
|
||||
|
||||
performEnabledAction(null, controlPlugin.actionEmulateResume, true);
|
||||
@@ -335,7 +348,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerInteg
|
||||
|
||||
assertFalse(controlPlugin.actionEmulateStepBack.isEnabled());
|
||||
|
||||
traceManager.activateTime(TraceSchedule.parse("0:t0-1"));
|
||||
traceManager.activateTime(TraceSchedule.parse("0:t%d-1".formatted(thread.getKey())));
|
||||
waitForSwing();
|
||||
|
||||
performEnabledAction(null, controlPlugin.actionEmulateStepBack, true);
|
||||
@@ -354,7 +367,8 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerInteg
|
||||
|
||||
performEnabledAction(null, controlPlugin.actionEmulateStepInto, true);
|
||||
|
||||
assertEquals(TraceSchedule.parse("0:t0-1"), traceManager.getCurrent().getTime());
|
||||
assertEquals(TraceSchedule.parse("0:t%d-1".formatted(thread.getKey())),
|
||||
traceManager.getCurrent().getTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -367,7 +381,8 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerInteg
|
||||
|
||||
performEnabledAction(null, controlPlugin.actionEmulateSkipOver, true);
|
||||
|
||||
assertEquals(TraceSchedule.parse("0:t0-s1"), traceManager.getCurrent().getTime());
|
||||
assertEquals(TraceSchedule.parse("0:t%d-s1".formatted(thread.getKey())),
|
||||
traceManager.getCurrent().getTime());
|
||||
}
|
||||
|
||||
protected void create2SnapTrace() throws Throwable {
|
||||
@@ -419,6 +434,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerInteg
|
||||
createAndOpenTrace();
|
||||
TraceVariableSnapProgramView view = tb.trace.getProgramView();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject("Target");
|
||||
tb.getOrAddThread("Threads[0]", 0);
|
||||
tb.trace.getMemoryManager()
|
||||
.createRegion("Memory[bin:.text]", 0, tb.range(0x00400000, 0x00401000),
|
||||
@@ -471,6 +487,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerInteg
|
||||
createAndOpenTrace();
|
||||
TraceVariableSnapProgramView view = tb.trace.getProgramView();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject("Target");
|
||||
tb.getOrAddThread("Threads[0]", 0);
|
||||
tb.trace.getMemoryManager()
|
||||
.createRegion("Memory[bin:.text]", 0, tb.range(0x00400000, 0x00401000),
|
||||
@@ -527,6 +544,7 @@ public class DebuggerControlPluginTest extends AbstractGhidraHeadedDebuggerInteg
|
||||
createAndOpenTrace();
|
||||
TraceVariableSnapProgramView view = tb.trace.getProgramView();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject("Target");
|
||||
tb.getOrAddThread("Threads[0]", 0);
|
||||
tb.trace.getMemoryManager()
|
||||
.createRegion("Memory[bin:.text]", 0, tb.range(0x00400000, 0x00401000),
|
||||
|
||||
+25
-10
@@ -39,10 +39,12 @@ import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.MemoryBlock;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.test.ToyProgramBuilder;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder.ToySchemaBuilder;
|
||||
import ghidra.trace.database.memory.DBTraceMemoryManager;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.memory.TraceMemoryFlag;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.schema.SchemaContext;
|
||||
|
||||
@Category(NightlyCategory.class)
|
||||
public class DebuggerCopyActionsPluginTest extends AbstractGhidraHeadedDebuggerIntegrationTest {
|
||||
@@ -78,6 +80,13 @@ public class DebuggerCopyActionsPluginTest extends AbstractGhidraHeadedDebuggerI
|
||||
select(listingProvider, set);
|
||||
}
|
||||
|
||||
protected SchemaContext buildContext() {
|
||||
return new ToySchemaBuilder()
|
||||
.noRegisterGroups()
|
||||
.useRegistersPerFrame()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionCopyIntoCurrentProgramWithoutRelocationCreateBlocks() throws Throwable {
|
||||
assertDisabled(copyActionsPlugin.actionCopyIntoCurrentProgram);
|
||||
@@ -89,8 +98,9 @@ public class DebuggerCopyActionsPluginTest extends AbstractGhidraHeadedDebuggerI
|
||||
|
||||
createAndOpenTrace();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
tb.trace.getMemoryManager()
|
||||
.createRegion(".text", 0, tb.range(0x00400000, 0x0040ffff),
|
||||
.createRegion("Memory[.text]", 0, tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
}
|
||||
traceManager.activateTrace(tb.trace);
|
||||
@@ -139,18 +149,19 @@ public class DebuggerCopyActionsPluginTest extends AbstractGhidraHeadedDebuggerI
|
||||
}
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager mm = tb.trace.getMemoryManager();
|
||||
mm.createRegion(".text", 0, tb.range(0x00400000, 0x0040ffff), TraceMemoryFlag.READ,
|
||||
TraceMemoryFlag.EXECUTE);
|
||||
mm.createRegion("Memory[.text]", 0, tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
mm.putBytes(0, tb.addr(0x00401234), tb.buf(1, 2, 3, 4));
|
||||
|
||||
// This region should be excluded, since it cannot be mapped identically into 32-bits
|
||||
mm.createRegion("lib:.text", 0, tb.range(0x7fff00400000L, 0x7fff0040ffffL),
|
||||
mm.createRegion("Memory[lib:.text]", 0, tb.range(0x7fff00400000L, 0x7fff0040ffffL),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
|
||||
// This region should be partially excluded, because 32-bits
|
||||
// This is not likely to ever happen in practice, but be prepared
|
||||
mm.createRegion(".straddle", 0, tb.range(0xfffff000L, 0x100000fffL),
|
||||
mm.createRegion("Memory[.straddle]", 0, tb.range(0xfffff000L, 0x100000fffL),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
|
||||
}
|
||||
|
||||
@@ -211,8 +222,9 @@ public class DebuggerCopyActionsPluginTest extends AbstractGhidraHeadedDebuggerI
|
||||
intoProject(tb.trace);
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
tb.trace.getMemoryManager()
|
||||
.createRegion(".text", 0, tb.range(0x55550000, 0x5555ffff),
|
||||
.createRegion("Memory[.text]", 0, tb.range(0x55550000, 0x5555ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
}
|
||||
traceManager.activateTrace(tb.trace);
|
||||
@@ -273,8 +285,9 @@ public class DebuggerCopyActionsPluginTest extends AbstractGhidraHeadedDebuggerI
|
||||
intoProject(tb.trace);
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
tb.trace.getMemoryManager()
|
||||
.createRegion(".text", 0, tb.range(0x55550000, 0x5555ffff),
|
||||
.createRegion("Memory[.text]", 0, tb.range(0x55550000, 0x5555ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
}
|
||||
traceManager.activateTrace(tb.trace);
|
||||
@@ -335,8 +348,9 @@ public class DebuggerCopyActionsPluginTest extends AbstractGhidraHeadedDebuggerI
|
||||
createAndOpenTrace();
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
tb.trace.getMemoryManager()
|
||||
.createRegion(".text", 0, tb.range(0x55550000, 0x5555ffff),
|
||||
.createRegion("Memory[.text]", 0, tb.range(0x55550000, 0x5555ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
}
|
||||
traceManager.activateTrace(tb.trace);
|
||||
@@ -377,11 +391,12 @@ public class DebuggerCopyActionsPluginTest extends AbstractGhidraHeadedDebuggerI
|
||||
createAndOpenTrace();
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
tb.trace.getMemoryManager()
|
||||
.createRegion(".text", 0, tb.range(0x55550000, 0x5555ffff),
|
||||
.createRegion("Memory[.text]", 0, tb.range(0x55550000, 0x5555ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
tb.trace.getMemoryManager()
|
||||
.createRegion(".data", 0, tb.range(0x55560000, 0x5556ffff),
|
||||
.createRegion("Memory[.data]", 0, tb.range(0x55560000, 0x5556ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
|
||||
}
|
||||
traceManager.activateTrace(tb.trace);
|
||||
|
||||
+157
-66
File diff suppressed because it is too large
Load Diff
+125
-64
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.debug.gui.memory;
|
||||
|
||||
import static ghidra.lifecycle.Unfinished.TODO;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.assumeFalse;
|
||||
|
||||
@@ -62,6 +61,7 @@ import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder.ToySchemaBuilder;
|
||||
import ghidra.trace.database.memory.DBTraceMemoryManager;
|
||||
import ghidra.trace.database.memory.DBTraceMemorySpace;
|
||||
import ghidra.trace.database.stack.DBTraceStackManager;
|
||||
@@ -71,6 +71,7 @@ import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.schema.SchemaContext;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.util.SystemUtilities;
|
||||
|
||||
@@ -112,13 +113,22 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
return data;
|
||||
}
|
||||
|
||||
protected SchemaContext buildContext() {
|
||||
return new ToySchemaBuilder()
|
||||
.noRegisterGroups()
|
||||
.useRegistersPerFrame()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBytesViewIsRegionsActivateThenAdd() throws Exception {
|
||||
createAndOpenTrace();
|
||||
traceManager.activateTrace(tb.trace);
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
@@ -133,8 +143,10 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
public void testBytesViewIsRegionsAddThenActivate() throws Exception {
|
||||
createAndOpenTrace();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
@@ -149,10 +161,13 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
public void testRegisterTrackingOnRegisterChange() throws Exception {
|
||||
createAndOpenTrace();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
TraceThread thread = tb.getOrAddThread("Thread1", 0);
|
||||
TraceThread thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
waitForDomainObject(tb.trace);
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing(); // Ensure the open/activate events are processed first
|
||||
@@ -175,10 +190,13 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
public void testRegisterTrackingOnSnapChange() throws Exception {
|
||||
createAndOpenTrace();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
TraceThread thread = tb.getOrAddThread("Thread1", 0);
|
||||
TraceThread thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
waitForDomainObject(tb.trace);
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing(); // Ensure the open/activate events are processed first
|
||||
@@ -209,11 +227,15 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
TraceThread thread1;
|
||||
TraceThread thread2;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
thread1 = tb.getOrAddThread("Thread1", 0);
|
||||
thread2 = tb.getOrAddThread("Thread2", 0);
|
||||
thread1 = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread1, Lifespan.nowOn(0), tb.host, 1);
|
||||
thread2 = tb.getOrAddThread("Threads[2]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread2, Lifespan.nowOn(0), tb.host, 1);
|
||||
|
||||
// NOTE: PC-tracking should be the default for the main bytes viewer
|
||||
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
|
||||
@@ -255,11 +277,15 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
true))
|
||||
.get();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
thread1 = tb.getOrAddThread("Thread1", 0);
|
||||
thread2 = tb.getOrAddThread("Thread2", 0);
|
||||
thread1 = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread1, Lifespan.nowOn(0), tb.host, 1);
|
||||
thread2 = tb.getOrAddThread("Threads[2]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread2, Lifespan.nowOn(0), tb.host, 1);
|
||||
|
||||
// NOTE: PC-tracking should be the default for the main bytes viewer
|
||||
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
|
||||
@@ -291,12 +317,15 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
public void testRegisterTrackingOnTrackingSpecChange() throws Exception {
|
||||
createAndOpenTrace();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
memory.addRegion("[stack]", Lifespan.nowOn(0), tb.range(0x01000000, 0x01ffffff),
|
||||
memory.addRegion("Memory[stack]", Lifespan.nowOn(0), tb.range(0x01000000, 0x01ffffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
|
||||
TraceThread thread = tb.getOrAddThread("Thread1", 0);
|
||||
TraceThread thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
waitForDomainObject(tb.trace);
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing(); // Ensure the open/activate events are processed first
|
||||
@@ -329,11 +358,14 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
TraceThread t1, t2;
|
||||
|
||||
try (Transaction tx = b1.startTransaction()) {
|
||||
b1.createRootObject(buildContext(), "Target");
|
||||
b1.trace.getTimeManager().createSnapshot("First snap");
|
||||
DBTraceMemoryManager memory = b1.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), b1.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
b1.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
t1 = b1.getOrAddThread("Thread1", 0);
|
||||
t1 = b1.getOrAddThread("Threads[1]", 0);
|
||||
b1.createObjectsFramesAndRegs(t1, Lifespan.nowOn(0), b1.host, 1);
|
||||
|
||||
Register pc = b1.trace.getBaseLanguage().getProgramCounter();
|
||||
TraceMemorySpace regs = memory.getMemoryRegisterSpace(t1, true);
|
||||
@@ -341,11 +373,14 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
}
|
||||
waitForDomainObject(b1.trace);
|
||||
try (Transaction tx = b2.startTransaction()) {
|
||||
b2.createRootObject(buildContext(), "Target");
|
||||
b2.trace.getTimeManager().createSnapshot("First snap");
|
||||
DBTraceMemoryManager memory = b2.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), b2.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
b2.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
t2 = b2.getOrAddThread("Thread2", 0);
|
||||
t2 = b2.getOrAddThread("Threads[2]", 0);
|
||||
b2.createObjectsFramesAndRegs(t2, Lifespan.nowOn(0), b2.host, 1);
|
||||
|
||||
Register pc = b2.trace.getBaseLanguage().getProgramCounter();
|
||||
TraceMemorySpace regs = memory.getMemoryRegisterSpace(t2, true);
|
||||
@@ -380,11 +415,14 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
TraceThread t1, t2;
|
||||
|
||||
try (Transaction tx = b1.startTransaction()) {
|
||||
b1.createRootObject(buildContext(), "Target");
|
||||
b1.trace.getTimeManager().createSnapshot("First snap");
|
||||
DBTraceMemoryManager memory = b1.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), b1.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
b1.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
t1 = b1.getOrAddThread("Thread1", 0);
|
||||
t1 = b1.getOrAddThread("Threads[1]", 0);
|
||||
b1.createObjectsFramesAndRegs(t1, Lifespan.nowOn(0), b1.host, 1);
|
||||
|
||||
Register pc = b1.trace.getBaseLanguage().getProgramCounter();
|
||||
TraceMemorySpace regs = memory.getMemoryRegisterSpace(t1, true);
|
||||
@@ -392,11 +430,14 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
}
|
||||
waitForDomainObject(b1.trace);
|
||||
try (Transaction tx = b2.startTransaction()) {
|
||||
b2.createRootObject(buildContext(), "Target");
|
||||
b2.trace.getTimeManager().createSnapshot("First snap");
|
||||
DBTraceMemoryManager memory = b2.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), b2.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
b2.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
t2 = b2.getOrAddThread("Thread2", 0);
|
||||
t2 = b2.getOrAddThread("Threads[2]", 0);
|
||||
b2.createObjectsFramesAndRegs(t2, Lifespan.nowOn(0), b2.host, 1);
|
||||
|
||||
Register pc = b2.trace.getBaseLanguage().getProgramCounter();
|
||||
TraceMemorySpace regs = memory.getMemoryRegisterSpace(t2, true);
|
||||
@@ -412,7 +453,6 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
waitForSwing();
|
||||
|
||||
assertEquals(b1.trace.getProgramView(), memBytesProvider.getProgram());
|
||||
// TODO: Assert thread?
|
||||
|
||||
traceManager.activateThread(t2);
|
||||
waitForSwing();
|
||||
@@ -452,13 +492,16 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
// To keep gray out of the color equation
|
||||
memory.setState(0, tb.range(0x00401233, 0x00401235), TraceMemoryState.KNOWN);
|
||||
|
||||
thread = tb.getOrAddThread("Thread1", 0);
|
||||
thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
|
||||
TraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
|
||||
regs.setValue(0, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
|
||||
@@ -534,8 +577,10 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
waitForSwing();
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject("Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
memory.setState(0, tb.addr(0x00401234), TraceMemoryState.KNOWN);
|
||||
memory.setState(0, tb.addr(0x00401235), TraceMemoryState.ERROR);
|
||||
@@ -597,10 +642,12 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
createAndOpenTrace();
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager mm = tb.trace.getMemoryManager();
|
||||
mm.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
mm.addRegion("Memory[exe:.text]", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
thread = tb.getOrAddThread("Thread 1", 0);
|
||||
thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
|
||||
Register r0 = tb.language.getRegister("r0");
|
||||
regs.setValue(0, new RegisterValue(r0, new BigInteger("00401234", 16)));
|
||||
@@ -641,12 +688,14 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
createAndOpenTrace();
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager mm = tb.trace.getMemoryManager();
|
||||
mm.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
mm.addRegion("Memory[exe:.text]", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
mm.addRegion("[stack]", Lifespan.nowOn(0), tb.range(0x1f000000, 0x1fffffff),
|
||||
mm.addRegion("Memory[stack]", Lifespan.nowOn(0), tb.range(0x1f000000, 0x1fffffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
|
||||
thread = tb.getOrAddThread("Thread 1", 0);
|
||||
thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
|
||||
Register pc = tb.language.getProgramCounter();
|
||||
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
|
||||
@@ -681,24 +730,21 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
memBytesProvider.actionTrackLocation.getCurrentUserData());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Haven't specified this action, yet")
|
||||
public void testActionTrackOtherRegister() {
|
||||
// TODO: Actually, can we make this an arbitrary (pcode/sleigh?) expression.
|
||||
TODO();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testActionFollowsCurrentThread() throws Exception {
|
||||
createAndOpenTrace();
|
||||
TraceThread thread1;
|
||||
TraceThread thread2;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
thread1 = tb.getOrAddThread("Thread1", 0);
|
||||
thread2 = tb.getOrAddThread("Thread2", 0);
|
||||
thread1 = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread1, Lifespan.nowOn(0), tb.host, 1);
|
||||
thread2 = tb.getOrAddThread("Threads[2]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread2, Lifespan.nowOn(0), tb.host, 1);
|
||||
|
||||
// NOTE: PC-tracking should be the default for the main dynamic listing
|
||||
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
|
||||
@@ -821,26 +867,30 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
assertEquals("(nowhere)", memBytesProvider.locationLabel.getText());
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
tb.trace.getMemoryManager()
|
||||
.addRegion("test_region", Lifespan.nowOn(0), tb.range(0x55550000, 0x555502ff),
|
||||
.addRegion("Memory[test_region]", Lifespan.nowOn(0),
|
||||
tb.range(0x55550000, 0x555502ff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
// TODO: This initial goTo should not really be needed
|
||||
goToDyn(tb.addr(0x55550000));
|
||||
waitForPass(() -> assertEquals("test_region", memBytesProvider.locationLabel.getText()));
|
||||
waitForPass(
|
||||
() -> assertEquals("test_region", memBytesProvider.locationLabel.getText()));
|
||||
|
||||
TraceModule modExe;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
modExe = tb.trace.getModuleManager()
|
||||
.addModule("modExe", "modExe", tb.range(0x55550000, 0x555501ff),
|
||||
.addModule("Modules[modExe]", "modExe", tb.range(0x55550000, 0x555501ff),
|
||||
Lifespan.nowOn(0));
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
waitForPass(() -> assertEquals("modExe", memBytesProvider.locationLabel.getText()));
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
modExe.addSection(0, ".text", tb.range(0x55550000, 0x555500ff));
|
||||
modExe.addSection(0, "Modules[modExe].Sections[.text]",
|
||||
tb.range(0x55550000, 0x555500ff));
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
waitForPass(() -> assertEquals("modExe:.text", memBytesProvider.locationLabel.getText()));
|
||||
@@ -856,11 +906,15 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
TraceThread thread1;
|
||||
TraceThread thread2;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager mm = tb.trace.getMemoryManager();
|
||||
mm.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
mm.addRegion("Memory[exe:.text]", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
thread1 = tb.getOrAddThread("Thread 1", 0);
|
||||
thread2 = tb.getOrAddThread("Thread 2", 0);
|
||||
thread1 = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread1, Lifespan.nowOn(0), tb.host, 1);
|
||||
thread2 = tb.getOrAddThread("Threads[2]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread2, Lifespan.nowOn(0), tb.host, 1);
|
||||
|
||||
TraceMemorySpace regs1 = mm.getMemoryRegisterSpace(thread1, true);
|
||||
regs1.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
|
||||
TraceMemorySpace regs2 = mm.getMemoryRegisterSpace(thread2, true);
|
||||
@@ -887,10 +941,12 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
Register pc = tb.language.getProgramCounter();
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager mm = tb.trace.getMemoryManager();
|
||||
mm.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
mm.addRegion("Memory[exe:.text]", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
thread = tb.getOrAddThread("Thread 1", 0);
|
||||
thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
|
||||
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
|
||||
regs.setValue(1, new RegisterValue(pc, new BigInteger("00404321", 16)));
|
||||
@@ -915,10 +971,11 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
createAndOpenTrace();
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager mm = tb.trace.getMemoryManager();
|
||||
mm.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
mm.addRegion("Memory[exe:.text]", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
thread = tb.getOrAddThread("Thread 1", 0);
|
||||
thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
DBTraceStackManager sm = tb.trace.getStackManager();
|
||||
TraceStack stack = sm.getStack(thread, 0, true);
|
||||
stack.getFrame(0, 0, true).setProgramCounter(Lifespan.ALL, tb.addr(0x00401234));
|
||||
@@ -946,9 +1003,11 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
Register pc = tb.language.getProgramCounter();
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
mm.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
mm.addRegion("Memory[exe:.text]", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
thread = tb.getOrAddThread("Thread 1", 0);
|
||||
thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
|
||||
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
|
||||
}
|
||||
@@ -977,15 +1036,13 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
Register pc = tb.language.getProgramCounter();
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
mm.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
mm.addRegion("Memory[exe:.text]", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
thread = tb.getOrAddThread("Thread 1", 0);
|
||||
thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
TraceMemorySpace regs = mm.getMemoryRegisterSpace(thread, true);
|
||||
regs.setValue(0, new RegisterValue(pc, new BigInteger("00401234", 16)));
|
||||
|
||||
DBTraceStackManager sm = tb.trace.getStackManager();
|
||||
TraceStack stack = sm.getStack(thread, 0, true);
|
||||
stack.getFrame(0, 0, true);
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
traceManager.activate(DebuggerCoordinates.NOWHERE.thread(thread).snap(0));
|
||||
@@ -1011,10 +1068,12 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
DBTraceStackManager sm = tb.trace.getStackManager();
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager mm = tb.trace.getMemoryManager();
|
||||
mm.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
mm.addRegion("Memory[exe:.text]", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
thread = tb.getOrAddThread("Thread 1", 0);
|
||||
thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
TraceStack stack = sm.getStack(thread, 0, true);
|
||||
stack.getFrame(0, 0, true).setProgramCounter(Lifespan.ALL, tb.addr(0x00401234));
|
||||
}
|
||||
@@ -1190,6 +1249,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Enable manually")
|
||||
public void testPerformanceManuallyWithManyManySnaps() throws Exception {
|
||||
assumeFalse(SystemUtilities.isInTestingBatchMode());
|
||||
createAndOpenTrace();
|
||||
@@ -1197,6 +1257,7 @@ public class DebuggerMemoryBytesProviderTest extends AbstractGhidraHeadedDebugge
|
||||
// LATER (GP-5594): 100_000 without checkStateMapIntegrity will crash.
|
||||
final long snapCount = 100_000;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(SCHEMA_CTX);
|
||||
tb.trace.getMemoryManager()
|
||||
.addRegion("Processes[1].Memory[exe:.text]", Lifespan.nowOn(0L),
|
||||
tb.range(0x55550000, 0x5555ffff), TraceMemoryFlag.READ,
|
||||
|
||||
+14
-4
@@ -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.
|
||||
@@ -81,6 +81,11 @@ public abstract class AbstractDebuggerRegistersProviderTest
|
||||
waitForComponentProvider(DebuggerListingProvider.class).setAutoDisassemble(false);
|
||||
|
||||
createTrace();
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getObjectManager().createRootObject(SCHEMA_SESSION);
|
||||
}
|
||||
|
||||
r0 = tb.language.getRegister("r0");
|
||||
pc = tb.language.getProgramCounter();
|
||||
sp = tb.language.getDefaultCompilerSpec().getStackPointer();
|
||||
@@ -109,6 +114,9 @@ public abstract class AbstractDebuggerRegistersProviderTest
|
||||
controlService = addPlugin(tool, DebuggerControlServicePlugin.class);
|
||||
|
||||
createTrace();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getObjectManager().createRootObject(SCHEMA_SESSION);
|
||||
}
|
||||
createToyPlatform();
|
||||
|
||||
r0 = tb.reg(toy, "r0");
|
||||
@@ -134,12 +142,14 @@ public abstract class AbstractDebuggerRegistersProviderTest
|
||||
}
|
||||
|
||||
protected TraceThread addThread() throws DuplicateNameException {
|
||||
return addThread("Thread1");
|
||||
return addThread("Processes[1].Threads[1]");
|
||||
}
|
||||
|
||||
protected TraceThread addThread(String threadName) throws DuplicateNameException {
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
return tb.trace.getThreadManager().createThread(threadName, 0);
|
||||
TraceThread thread = tb.trace.getThreadManager().createThread(threadName, 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-7
@@ -26,21 +26,19 @@ import db.Transaction;
|
||||
import ghidra.debug.api.control.ControlMode;
|
||||
import ghidra.program.model.data.DoubleDataType;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.stack.TraceObjectStackFrame;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.thread.TraceObjectThread;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
|
||||
public class DebuggerRmiRegistersProviderTest extends AbstractDebuggerRegistersProviderTest {
|
||||
|
||||
protected TraceObject setUpRmiTarget() throws Throwable {
|
||||
createRmiConnection();
|
||||
addRegisterMethods();
|
||||
createTrace();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getObjectManager().createRootObject(SCHEMA_SESSION);
|
||||
tb.createObjectsProcessAndThreads();
|
||||
tb.createObjectsFramesAndRegs(
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceObjectThread.class),
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class),
|
||||
Lifespan.nowOn(0), tb.host, 2);
|
||||
}
|
||||
rmiCx.publishTarget(tool, tb.trace);
|
||||
@@ -71,7 +69,7 @@ public class DebuggerRmiRegistersProviderTest extends AbstractDebuggerRegistersP
|
||||
|
||||
setRowText(row, "1234");
|
||||
handleWriteRegInvocation(
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceObjectStackFrame.class),
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceStackFrame.class),
|
||||
"r0", 0x1234);
|
||||
}
|
||||
|
||||
@@ -93,7 +91,7 @@ public class DebuggerRmiRegistersProviderTest extends AbstractDebuggerRegistersP
|
||||
|
||||
setRowRepr(row, "1234");
|
||||
handleWriteRegInvocation(
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceObjectStackFrame.class),
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceStackFrame.class),
|
||||
"r0", encodeDouble(1234));
|
||||
}
|
||||
}
|
||||
|
||||
+8
-5
@@ -463,7 +463,7 @@ public class DebuggerTraceRegistersProviderTest extends AbstractDebuggerRegister
|
||||
assertFalse(registersProvider.actionCreateSnapshot.isEnabled());
|
||||
|
||||
TraceThread thread1 = addThread();
|
||||
TraceThread thread2 = addThread("Thread2");
|
||||
TraceThread thread2 = addThread("Processes[1].Threads[2]");
|
||||
addRegisterValues(thread1);
|
||||
addRegisterTypes(thread1);
|
||||
traceManager.openTrace(tb.trace);
|
||||
@@ -483,7 +483,7 @@ public class DebuggerTraceRegistersProviderTest extends AbstractDebuggerRegister
|
||||
DebuggerRegistersProvider cloned =
|
||||
(DebuggerRegistersProvider) tool.getActiveComponentProvider();
|
||||
assertEquals("[Registers]", cloned.getTitle());
|
||||
assertEquals("Thread1", cloned.getSubTitle());
|
||||
assertEquals("Processes[1].Threads[1]", cloned.getSubTitle());
|
||||
|
||||
activateThread(thread2);
|
||||
waitForSwing();
|
||||
@@ -518,7 +518,8 @@ public class DebuggerTraceRegistersProviderTest extends AbstractDebuggerRegister
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
// Unconventional start, to ensure goto PC is actually the cause, not just min of view
|
||||
tb.trace.getMemoryManager()
|
||||
.addRegion("bin:.text", Lifespan.nowOn(0), tb.range(0x00300000, 0x00500000),
|
||||
.addRegion("Processes[1].Memory[bin:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00300000, 0x00500000),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
}
|
||||
addRegisterValues(thread);
|
||||
@@ -589,7 +590,7 @@ public class DebuggerTraceRegistersProviderTest extends AbstractDebuggerRegister
|
||||
public void testTraceThreadActivation() throws Exception {
|
||||
traceManager.openTrace(tb.trace);
|
||||
TraceThread thread1 = addThread();
|
||||
TraceThread thread2 = addThread("Thread2");
|
||||
TraceThread thread2 = addThread("Processes[1].Threads[2]");
|
||||
addRegisterValues(thread1);
|
||||
activateThread(thread2);
|
||||
waitForSwing();
|
||||
@@ -625,7 +626,8 @@ public class DebuggerTraceRegistersProviderTest extends AbstractDebuggerRegister
|
||||
|
||||
TraceThread thread3;
|
||||
try (Transaction tx = ub.startTransaction()) {
|
||||
thread3 = ub.trace.getThreadManager().createThread("Thread3", 0);
|
||||
ub.createRootObject("Target"); // Different schema from first, because why not?
|
||||
thread3 = ub.trace.getThreadManager().createThread("Threads[3]", 0);
|
||||
}
|
||||
traceManager.activateTrace(ub.trace);
|
||||
waitForDomainObject(ub.trace);
|
||||
@@ -701,6 +703,7 @@ public class DebuggerTraceRegistersProviderTest extends AbstractDebuggerRegister
|
||||
assertR0RowTypePopulated();
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 2);
|
||||
TraceMemorySpace regVals =
|
||||
tb.trace.getMemoryManager().getMemoryRegisterSpace(thread, 1, true);
|
||||
regVals.putBytes(getPlatform(), 0, pc, tb.buf(0, 0, 0, 0, 0, 0x50, 0, 0));
|
||||
|
||||
+10
-10
@@ -53,9 +53,9 @@ import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.model.DefaultTraceLocation;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.stack.TraceObjectStackFrame;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.thread.TraceObjectThread;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.util.TraceRegisterUtils;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
@@ -79,7 +79,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerInt
|
||||
|
||||
protected Register r0;
|
||||
protected Register r1;
|
||||
protected TraceObjectThread thread;
|
||||
protected TraceThread thread;
|
||||
|
||||
@Before
|
||||
public void setUpWatchesProviderTest() throws Exception {
|
||||
@@ -100,7 +100,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerInt
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getObjectManager().createRootObject(SCHEMA_SESSION);
|
||||
tb.createObjectsProcessAndThreads();
|
||||
thread = tb.obj("Processes[1].Threads[1]").queryInterface(TraceObjectThread.class);
|
||||
thread = tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class);
|
||||
}
|
||||
|
||||
// TODO: This seems to hold up the task manager.
|
||||
@@ -117,7 +117,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerInt
|
||||
}
|
||||
}
|
||||
|
||||
private void setRegisterValues(TraceObjectThread thread) {
|
||||
private void setRegisterValues(TraceThread thread) {
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
TraceMemorySpace regVals =
|
||||
@@ -318,7 +318,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerInt
|
||||
tb.range(0x55550000, 0x5555ffff), TraceMemoryFlag.READ,
|
||||
TraceMemoryFlag.EXECUTE);
|
||||
tb.createObjectsFramesAndRegs(
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceObjectThread.class),
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class),
|
||||
Lifespan.nowOn(0), tb.host, 1);
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
@@ -566,7 +566,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerInt
|
||||
tb.range(0x55550000, 0x5555ffff), TraceMemoryFlag.READ,
|
||||
TraceMemoryFlag.EXECUTE);
|
||||
tb.createObjectsFramesAndRegs(
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceObjectThread.class),
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class),
|
||||
Lifespan.nowOn(0), tb.host, 1);
|
||||
|
||||
tb.obj("Processes[1].Threads[1].Stack[0].Registers[r1]").delete();
|
||||
@@ -606,7 +606,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerInt
|
||||
runSwing(() -> row.setRawValueString("0x1234"));
|
||||
|
||||
handleWriteRegInvocation(
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceObjectStackFrame.class),
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceStackFrame.class),
|
||||
"r0", 0x1234);
|
||||
|
||||
rmiCx.withdrawTarget(tool, tb.trace);
|
||||
@@ -661,7 +661,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerInt
|
||||
|
||||
protected void setupUnmappedDataSection() throws Throwable {
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
TraceMemoryOperations mem = tb.trace.getMemoryManager();
|
||||
TraceMemoryManager mem = tb.trace.getMemoryManager();
|
||||
mem.createRegion("Processes[1].Memory[bin:.data]", 0, tb.range(0x00600000, 0x0060ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
|
||||
}
|
||||
@@ -678,7 +678,7 @@ public class DebuggerWatchesProviderTest extends AbstractGhidraHeadedDebuggerInt
|
||||
intoProject(program);
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
TraceMemoryOperations mem = tb.trace.getMemoryManager();
|
||||
TraceMemoryManager mem = tb.trace.getMemoryManager();
|
||||
mem.createRegion("Processes[1].Memory[bin:.data]", 0, tb.range(0x55750000, 0x5575ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.WRITE);
|
||||
}
|
||||
|
||||
+44
-25
@@ -44,6 +44,8 @@ import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.memory.TraceMemoryFlag;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.target.TraceObject.ConflictResolution;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.SystemUtilities;
|
||||
|
||||
@@ -152,15 +154,14 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
|
||||
protected abstract void terminateTarget(T t);
|
||||
|
||||
protected abstract TraceBreakpoint findLoc(long snap, Set<TraceBreakpoint> locs, int index);
|
||||
protected abstract TraceBreakpointLocation findLoc(long snap, Set<TraceBreakpointLocation> locs,
|
||||
int index);
|
||||
|
||||
protected abstract void handleToggleBreakpointInvocation(T target,
|
||||
TraceBreakpoint expectedBreakpoint,
|
||||
boolean expectedEnabled) throws Throwable;
|
||||
TraceBreakpointLocation expectedBreakpoint, boolean expectedEnabled) throws Throwable;
|
||||
|
||||
protected abstract void handleDeleteBreakpointInvocation(T target,
|
||||
TraceBreakpoint expectedBreakpoint)
|
||||
throws Throwable;
|
||||
TraceBreakpointLocation expectedBreakpoint) throws Throwable;
|
||||
|
||||
@Before
|
||||
public void setUpBreakpointServiceTest() throws Throwable {
|
||||
@@ -293,7 +294,8 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
assertNull(enLb.getProgramLocation());
|
||||
assertEquals(Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE), enLb.getKinds());
|
||||
|
||||
TraceBreakpoint bpt = Unique.assertOne(trace.getBreakpointManager().getAllBreakpoints());
|
||||
TraceBreakpointLocation bpt =
|
||||
Unique.assertOne(trace.getBreakpointManager().getAllBreakpointLocations());
|
||||
assertEquals(Set.of(trace), enLb.getMappedTraces());
|
||||
assertEquals(addr(trace, 0x56550123), enLb.getTraceAddress(trace));
|
||||
assertEquals(Set.of(bpt), enLb.getTraceBreakpoints(trace));
|
||||
@@ -314,7 +316,8 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
assertNull(enLb.getProgramLocation());
|
||||
assertEquals(Set.of(TraceBreakpointKind.SW_EXECUTE), enLb.getKinds());
|
||||
|
||||
TraceBreakpoint bpt = Unique.assertOne(trace.getBreakpointManager().getAllBreakpoints());
|
||||
TraceBreakpointLocation bpt =
|
||||
Unique.assertOne(trace.getBreakpointManager().getAllBreakpointLocations());
|
||||
assertEquals(Set.of(trace), enLb.getMappedTraces());
|
||||
assertEquals(addr(trace, offset), enLb.getTraceAddress(trace));
|
||||
assertEquals(Set.of(bpt), enLb.getTraceBreakpoints(trace));
|
||||
@@ -331,7 +334,8 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
assertEquals(State.ENABLED, enLb.computeStateForProgram(program));
|
||||
assertEquals(Set.of(TraceBreakpointKind.SW_EXECUTE), enLb.getKinds());
|
||||
|
||||
TraceBreakpoint bpt = Unique.assertOne(trace.getBreakpointManager().getAllBreakpoints());
|
||||
TraceBreakpointLocation bpt =
|
||||
Unique.assertOne(trace.getBreakpointManager().getAllBreakpointLocations());
|
||||
assertEquals(Set.of(trace), enLb.getMappedTraces());
|
||||
assertEquals(addr(trace, 0x55550123), enLb.getTraceAddress(trace));
|
||||
assertEquals(Set.of(bpt), enLb.getTraceBreakpoints(trace));
|
||||
@@ -402,8 +406,10 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
assertEquals(addr(trace1, 0x55550123), enLb.getTraceAddress(trace1));
|
||||
assertEquals(addr(trace2, 0x55551123), enLb.getTraceAddress(trace2));
|
||||
|
||||
TraceBreakpoint bpt1 = Unique.assertOne(trace1.getBreakpointManager().getAllBreakpoints());
|
||||
TraceBreakpoint bpt2 = Unique.assertOne(trace2.getBreakpointManager().getAllBreakpoints());
|
||||
TraceBreakpointLocation bpt1 =
|
||||
Unique.assertOne(trace1.getBreakpointManager().getAllBreakpointLocations());
|
||||
TraceBreakpointLocation bpt2 =
|
||||
Unique.assertOne(trace2.getBreakpointManager().getAllBreakpointLocations());
|
||||
assertEquals(Set.of(bpt1), enLb.getTraceBreakpoints(trace1));
|
||||
assertEquals(Set.of(bpt2), enLb.getTraceBreakpoints(trace2));
|
||||
assertNotEquals(Set.of(bpt2), enLb.getTraceBreakpoints(trace1)); // Sanity check
|
||||
@@ -441,7 +447,8 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
assertEquals(Set.of(trace), enLb.getMappedTraces());
|
||||
assertEquals(addr(trace, 0x55550123), enLb.getTraceAddress(trace));
|
||||
|
||||
TraceBreakpoint bpt = Unique.assertOne(trace.getBreakpointManager().getAllBreakpoints());
|
||||
TraceBreakpointLocation bpt =
|
||||
Unique.assertOne(trace.getBreakpointManager().getAllBreakpointLocations());
|
||||
assertEquals(Set.of(bpt), enLb.getTraceBreakpoints(trace));
|
||||
assertEquals(Set.of(bpt), enLb.getTraceBreakpoints());
|
||||
|
||||
@@ -1339,12 +1346,11 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
|
||||
LogicalBreakpoint lb = Unique.assertOne(breakpointService.getAllBreakpoints());
|
||||
|
||||
int id = Integer.parseInt(
|
||||
((TraceObjectBreakpointLocation) Unique.assertOne(lb.getTraceBreakpoints(trace)))
|
||||
.getSpecification()
|
||||
.getObject()
|
||||
.getCanonicalPath()
|
||||
.index());
|
||||
int id = Integer.parseInt(Unique.assertOne(lb.getTraceBreakpoints(trace))
|
||||
.getSpecification()
|
||||
.getObject()
|
||||
.getCanonicalPath()
|
||||
.index());
|
||||
|
||||
// Simulate a step, which should also cause snap advance in target
|
||||
simulateTargetStep(target1);
|
||||
@@ -1414,11 +1420,11 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
|
||||
assertEquals(2, lb.getTraceBreakpoints().size());
|
||||
|
||||
Set<TraceBreakpoint> locs = lb.getTraceBreakpoints();
|
||||
Set<TraceBreakpointLocation> locs = lb.getTraceBreakpoints();
|
||||
|
||||
long snap = getSnap(target1);
|
||||
TraceBreakpoint bpt0 = findLoc(snap, locs, 0);
|
||||
TraceBreakpoint bpt1 = findLoc(snap, locs, 1);
|
||||
TraceBreakpointLocation bpt0 = findLoc(snap, locs, 0);
|
||||
TraceBreakpointLocation bpt1 = findLoc(snap, locs, 1);
|
||||
CompletableFuture<Void> disable = breakpointService.disableLocs(Set.of(bpt0));
|
||||
handleToggleBreakpointInvocation(target1, bpt0, false);
|
||||
waitOn(disable);
|
||||
@@ -1517,6 +1523,12 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
intoProject(program);
|
||||
programManager.openProgram(program);
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(SCHEMA_CTX);
|
||||
tb.trace.getObjectManager()
|
||||
.createObject(KeyPath.parse("Processes[1].Breakpoints"))
|
||||
.insert(Lifespan.nowOn(0), ConflictResolution.DENY);
|
||||
}
|
||||
addTextMappingDead(0, program, tb);
|
||||
|
||||
addEnabledProgramBreakpointWithSleigh(program);
|
||||
@@ -1531,7 +1543,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
waitForDomainObject(program);
|
||||
waitOn(breakpointService.changesSettled());
|
||||
|
||||
TraceBreakpoint bpt = Unique.assertOne(
|
||||
TraceBreakpointLocation bpt = Unique.assertOne(
|
||||
tb.trace.getBreakpointManager().getBreakpointsAt(0, tb.addr(0x55550123)));
|
||||
assertEquals("r0=0xbeef;", bpt.getEmuSleigh(0));
|
||||
}
|
||||
@@ -1552,6 +1564,12 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
|
||||
assertEquals("r0=0xbeef;", lb.getEmuSleigh());
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(SCHEMA_CTX);
|
||||
tb.trace.getObjectManager()
|
||||
.createObject(KeyPath.parse("Processes[1].Breakpoints"))
|
||||
.insert(Lifespan.nowOn(0), ConflictResolution.DENY);
|
||||
}
|
||||
addTextMappingDead(0, program, tb);
|
||||
waitOn(mappingService.changesSettled());
|
||||
waitOn(breakpointService.changesSettled());
|
||||
@@ -1563,7 +1581,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
waitForDomainObject(program);
|
||||
waitOn(breakpointService.changesSettled());
|
||||
|
||||
TraceBreakpoint bpt = Unique.assertOne(
|
||||
TraceBreakpointLocation bpt = Unique.assertOne(
|
||||
tb.trace.getBreakpointManager().getBreakpointsAt(0, tb.addr(0x55550123)));
|
||||
assertEquals("r0=0xbeef;", bpt.getEmuSleigh(0));
|
||||
}
|
||||
@@ -1585,8 +1603,9 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
programManager.openProgram(program);
|
||||
|
||||
try (Transaction tid = tb.startTransaction()) {
|
||||
TraceBreakpoint bpt = tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Processes[1].Breakpoints[0]", Lifespan.nowOn(0),
|
||||
tb.createRootObject(SCHEMA_CTX);
|
||||
TraceBreakpointLocation bpt = tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Processes[1].Breakpoints[0][0]", Lifespan.nowOn(0),
|
||||
tb.addr(0x55550123), Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE),
|
||||
false /* emuEnabled defaults to true */, "");
|
||||
bpt.setEmuSleigh(0, "r0=0xbeef;");
|
||||
@@ -1639,7 +1658,7 @@ public abstract class AbstractDebuggerLogicalBreakpointServiceTest<T, MR>
|
||||
programManager.openProgram(program);
|
||||
|
||||
try (Transaction tid = tb.startTransaction()) {
|
||||
TraceBreakpoint bpt = tb.trace.getBreakpointManager()
|
||||
TraceBreakpointLocation bpt = tb.trace.getBreakpointManager()
|
||||
.addBreakpoint("Processes[1].Breakpoints[0]", Lifespan.nowOn(0),
|
||||
tb.addr(0x55550123),
|
||||
Set.of(), Set.of(TraceBreakpointKind.SW_EXECUTE),
|
||||
|
||||
+28
-34
@@ -29,16 +29,17 @@ import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind.TraceBreakpointKindSet;
|
||||
import ghidra.trace.model.memory.TraceObjectMemoryRegion;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointLocation;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointSpec;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.modules.TraceStaticMapping;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.time.TraceSnapshot;
|
||||
|
||||
public class DebuggerRmiLogicalBreakpointServiceTest extends
|
||||
AbstractDebuggerLogicalBreakpointServiceTest<TraceRmiTarget, TraceObjectMemoryRegion> {
|
||||
AbstractDebuggerLogicalBreakpointServiceTest<TraceRmiTarget, TraceMemoryRegion> {
|
||||
|
||||
ToyDBTraceBuilder tb3;
|
||||
|
||||
@@ -101,42 +102,42 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TraceObjectMemoryRegion addTargetTextRegion(TraceRmiTarget target, long offset)
|
||||
protected TraceMemoryRegion addTargetTextRegion(TraceRmiTarget target, long offset)
|
||||
throws Throwable {
|
||||
Trace trace = target.getTrace();
|
||||
TraceObjectMemoryRegion result;
|
||||
TraceMemoryRegion result;
|
||||
try (Transaction tx = trace.openTransaction("Add .text")) {
|
||||
result = Objects.requireNonNull(
|
||||
addMemoryRegion(trace.getObjectManager(), Lifespan.nowOn(target.getSnap()),
|
||||
tb.range(offset, offset + 0x0fff), "bin:.text", "rx")
|
||||
.queryInterface(TraceObjectMemoryRegion.class));
|
||||
.queryInterface(TraceMemoryRegion.class));
|
||||
}
|
||||
waitForDomainObject(trace);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TraceObjectMemoryRegion addTargetTextRegion(TraceRmiTarget target) throws Throwable {
|
||||
protected TraceMemoryRegion addTargetTextRegion(TraceRmiTarget target) throws Throwable {
|
||||
return addTargetTextRegion(target, 0x55550000);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TraceObjectMemoryRegion addTargetDataRegion(TraceRmiTarget target) throws Throwable {
|
||||
protected TraceMemoryRegion addTargetDataRegion(TraceRmiTarget target) throws Throwable {
|
||||
Trace trace = target.getTrace();
|
||||
long offset = 0x56550000;
|
||||
TraceObjectMemoryRegion result;
|
||||
TraceMemoryRegion result;
|
||||
try (Transaction tx = trace.openTransaction("Add .data")) {
|
||||
result = Objects.requireNonNull(
|
||||
addMemoryRegion(trace.getObjectManager(), Lifespan.nowOn(target.getSnap()),
|
||||
tb.range(offset, offset + 0x0fff), "bin:.data", "rw")
|
||||
.queryInterface(TraceObjectMemoryRegion.class));
|
||||
.queryInterface(TraceMemoryRegion.class));
|
||||
}
|
||||
waitForDomainObject(trace);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addTextMapping(TraceRmiTarget target, TraceObjectMemoryRegion text,
|
||||
protected void addTextMapping(TraceRmiTarget target, TraceMemoryRegion text,
|
||||
Program program) throws Throwable {
|
||||
Trace trace = target.getTrace();
|
||||
long snap = getSnap(target);
|
||||
@@ -162,7 +163,7 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addTargetAccessBreakpoint(TraceRmiTarget target, TraceObjectMemoryRegion region)
|
||||
protected void addTargetAccessBreakpoint(TraceRmiTarget target, TraceMemoryRegion region)
|
||||
throws Throwable {
|
||||
Address min = region.getMinAddress(getSnap(target)).add(0x0123);
|
||||
Trace trace = target.getTrace();
|
||||
@@ -175,7 +176,7 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends
|
||||
|
||||
@Override
|
||||
protected void addTargetSoftwareBreakpoint(TraceRmiTarget target,
|
||||
TraceObjectMemoryRegion region, int offset, Integer id) throws Throwable {
|
||||
TraceMemoryRegion region, int offset, Integer id) throws Throwable {
|
||||
Address min = region.getMinAddress(getSnap(target)).add(offset);
|
||||
Trace trace = target.getTrace();
|
||||
try (Transaction tx = trace.openTransaction("Add software breakpoint")) {
|
||||
@@ -190,20 +191,18 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends
|
||||
Trace trace = target.getTrace();
|
||||
long snap = target.getSnap();
|
||||
Lifespan nowOn = Lifespan.nowOn(snap);
|
||||
List<TraceObjectBreakpointLocation> locsToDel = trace.getBreakpointManager()
|
||||
.getAllBreakpoints()
|
||||
List<? extends TraceBreakpointLocation> locsToDel = trace.getBreakpointManager()
|
||||
.getAllBreakpointLocations()
|
||||
.stream()
|
||||
.filter(bp -> bp.getKinds(snap).equals(TraceBreakpointKindSet.SW_EXECUTE))
|
||||
.filter(bp -> bp instanceof TraceObjectBreakpointLocation)
|
||||
.map(bp -> (TraceObjectBreakpointLocation) bp)
|
||||
.filter(loc -> loc.getKinds(snap).equals(TraceBreakpointKindSet.SW_EXECUTE))
|
||||
.toList();
|
||||
List<TraceObjectBreakpointSpec> specsToDel =
|
||||
List<TraceBreakpointSpec> specsToDel =
|
||||
locsToDel.stream().map(bp -> bp.getSpecification()).distinct().toList();
|
||||
try (Transaction tx = trace.openTransaction("Delete software breakpoints")) {
|
||||
for (TraceObjectBreakpointLocation loc : locsToDel) {
|
||||
for (TraceBreakpointLocation loc : locsToDel) {
|
||||
loc.getObject().remove(nowOn);
|
||||
}
|
||||
for (TraceObjectBreakpointSpec spec : specsToDel) {
|
||||
for (TraceBreakpointSpec spec : specsToDel) {
|
||||
spec.getObject().remove(nowOn);
|
||||
}
|
||||
}
|
||||
@@ -216,7 +215,8 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TraceBreakpoint findLoc(long snap, Set<TraceBreakpoint> locs, int index) {
|
||||
protected TraceBreakpointLocation findLoc(long snap, Set<TraceBreakpointLocation> locs,
|
||||
int index) {
|
||||
return locs.stream()
|
||||
.filter(b -> b.getName(snap).equals(Integer.toString(index + 1)))
|
||||
.findAny()
|
||||
@@ -225,34 +225,28 @@ public class DebuggerRmiLogicalBreakpointServiceTest extends
|
||||
|
||||
@Override
|
||||
protected void handleToggleBreakpointInvocation(TraceRmiTarget target,
|
||||
TraceBreakpoint expectedBreakpoint, boolean expectedEn) throws Throwable {
|
||||
if (!(expectedBreakpoint instanceof TraceObjectBreakpointLocation loc)) {
|
||||
throw new AssertionError("Unexpected trace breakpoint type: " + expectedBreakpoint);
|
||||
}
|
||||
TraceBreakpointLocation expectedLoc, boolean expectedEn) throws Throwable {
|
||||
Map<String, Object> args = rmiMethodToggleBreak.expect();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
loc.setEnabled(Lifespan.nowOn(target.getSnap()), expectedEn);
|
||||
expectedLoc.setEnabled(Lifespan.nowOn(target.getSnap()), expectedEn);
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
rmiMethodToggleBreak.result(null);
|
||||
assertEquals(Map.ofEntries(
|
||||
Map.entry("breakpoint", loc.getSpecification().getObject()),
|
||||
Map.entry("breakpoint", expectedLoc.getSpecification().getObject()),
|
||||
Map.entry("enabled", expectedEn)), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleDeleteBreakpointInvocation(TraceRmiTarget target,
|
||||
TraceBreakpoint expectedBreakpoint) throws Throwable {
|
||||
if (!(expectedBreakpoint instanceof TraceObjectBreakpointLocation loc)) {
|
||||
throw new AssertionError("Unexpected trace breakpoint type: " + expectedBreakpoint);
|
||||
}
|
||||
TraceBreakpointLocation expectedLoc) throws Throwable {
|
||||
Map<String, Object> args = rmiMethodDeleteBreak.expect();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
loc.getObject().removeTree(Lifespan.nowOn(target.getSnap()));
|
||||
expectedLoc.getObject().removeTree(Lifespan.nowOn(target.getSnap()));
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
rmiMethodDeleteBreak.result(null);
|
||||
assertEquals(Map.ofEntries(
|
||||
Map.entry("breakpoint", loc.getSpecification().getObject())), args);
|
||||
Map.entry("breakpoint", expectedLoc.getSpecification().getObject())), args);
|
||||
}
|
||||
}
|
||||
|
||||
+16
-17
@@ -40,9 +40,8 @@ import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.guest.TracePlatform;
|
||||
import ghidra.trace.model.memory.TraceMemoryFlag;
|
||||
import ghidra.trace.model.stack.TraceObjectStackFrame;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.thread.TraceObjectThread;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule;
|
||||
|
||||
@@ -173,7 +172,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
createAndOpenTrace();
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
// NB. TraceManager should automatically activate the first thread
|
||||
thread = tb.createObjectsProcessAndThreads();
|
||||
@@ -203,7 +202,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
createAndOpenTrace();
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
// NB. TraceManager should automatically activate the first thread
|
||||
thread = tb.createObjectsProcessAndThreads();
|
||||
@@ -243,7 +242,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
createAndOpenTrace();
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
// NB. TraceManager should automatically activate the first thread
|
||||
thread = tb.createObjectsProcessAndThreads();
|
||||
@@ -286,7 +285,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
// NB. TraceManager should automatically activate the first thread
|
||||
TraceObjectThread thread = tb.createObjectsProcessAndThreads();
|
||||
TraceThread thread = tb.createObjectsProcessAndThreads();
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), getPlatform(), 1);
|
||||
}
|
||||
activateTrace();
|
||||
@@ -314,7 +313,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
createAndOpenTrace();
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_EMULATOR);
|
||||
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
// NB. TraceManager should automatically activate the first thread
|
||||
thread = tb.createObjectsProcessAndThreads();
|
||||
@@ -385,7 +384,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
createAndOpenTrace();
|
||||
controlService.setCurrentMode(tb.trace, ControlMode.RW_TRACE);
|
||||
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
// NB. TraceManager should automatically activate the first thread
|
||||
thread = tb.createObjectsProcessAndThreads();
|
||||
@@ -417,8 +416,8 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createObjectsProcessAndThreads();
|
||||
TraceObjectThread thread =
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceObjectThread.class);
|
||||
TraceThread thread =
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), getPlatform(), 1);
|
||||
tb.trace.getMemoryManager()
|
||||
.addRegion("Processes[1].Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
@@ -436,7 +435,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
|
||||
TraceObject process = tb.obj("Processes[1]");
|
||||
TraceThread thread =
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceObjectThread.class);
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class);
|
||||
activateTrace(); // platform
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
@@ -456,7 +455,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
addTarget();
|
||||
|
||||
TraceThread thread =
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceObjectThread.class);
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class);
|
||||
activateTrace(); // platform
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
@@ -466,7 +465,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
assertTrue(editor.isRegisterEditable(r0));
|
||||
CompletableFuture<Void> future = editor.setRegister(rv1234);
|
||||
handleWriteRegInvocation(
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceObjectStackFrame.class),
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceStackFrame.class),
|
||||
"r0", 1234);
|
||||
waitOn(future);
|
||||
}
|
||||
@@ -477,7 +476,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
addTarget();
|
||||
|
||||
TraceThread thread =
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceObjectThread.class);
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class);
|
||||
activateTrace(); // platform
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
@@ -487,14 +486,14 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
assertTrue(editor.isRegisterEditable(r0));
|
||||
CompletableFuture<Void> future = editor.setRegister(rv1234);
|
||||
handleWriteRegInvocation(
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceObjectStackFrame.class),
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceStackFrame.class),
|
||||
"r0", 1234);
|
||||
waitOn(future);
|
||||
|
||||
assertTrue(editor.isRegisterEditable(r0h));
|
||||
CompletableFuture<Void> future2 = editor.setRegister(rvHigh1234);
|
||||
handleWriteRegInvocation(
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceObjectStackFrame.class),
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceStackFrame.class),
|
||||
"r0h", 1234);
|
||||
waitOn(future2);
|
||||
}
|
||||
@@ -505,7 +504,7 @@ public class DebuggerControlServiceTest extends AbstractGhidraHeadedDebuggerInte
|
||||
Target target = addTarget();
|
||||
|
||||
TraceThread thread =
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceObjectThread.class);
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class);
|
||||
activateTrace(); // platform
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
+28
-9
@@ -46,6 +46,7 @@ import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder.ToySchemaBuilder;
|
||||
import ghidra.trace.database.memory.DBTraceMemoryManager;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.memory.TraceMemoryFlag;
|
||||
@@ -99,8 +100,10 @@ public class DynamicStaticSynchronizationPluginTest
|
||||
monitor, false);
|
||||
}
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject("Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
TraceLocation from =
|
||||
new DefaultTraceLocation(tb.trace, null, Lifespan.nowOn(0), tb.addr(0x00400000));
|
||||
@@ -158,15 +161,22 @@ public class DynamicStaticSynchronizationPluginTest
|
||||
}
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(new ToySchemaBuilder()
|
||||
.noRegisterGroups()
|
||||
.useRegistersPerFrame()
|
||||
.build(),
|
||||
"Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
TraceLocation from =
|
||||
new DefaultTraceLocation(tb.trace, null, Lifespan.nowOn(0), tb.addr(0x00400000));
|
||||
ProgramLocation to = new ProgramLocation(program, ss.getAddress(0x00600000));
|
||||
DebuggerStaticMappingUtils.addMapping(from, to, 0x8000, false);
|
||||
|
||||
thread = tb.getOrAddThread("Thread1", 0);
|
||||
thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
Register pc = tb.trace.getBaseLanguage().getProgramCounter();
|
||||
TraceMemorySpace regs = memory.getMemoryRegisterSpace(thread, true);
|
||||
regs.setValue(1, new RegisterValue(pc, BigInteger.valueOf(0x00401234)));
|
||||
@@ -344,8 +354,10 @@ public class DynamicStaticSynchronizationPluginTest
|
||||
monitor, false);
|
||||
}
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject("Target");
|
||||
DBTraceMemoryManager memory = tb.trace.getMemoryManager();
|
||||
memory.addRegion("exe:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0040ffff),
|
||||
memory.addRegion("Memory[exe:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0040ffff),
|
||||
TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE);
|
||||
TraceLocation from =
|
||||
new DefaultTraceLocation(tb.trace, null, Lifespan.nowOn(0), tb.addr(0x00400000));
|
||||
@@ -432,13 +444,17 @@ public class DynamicStaticSynchronizationPluginTest
|
||||
|
||||
createAndOpenTrace();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject("Target");
|
||||
tb.trace.getMemoryManager()
|
||||
.addRegion("bash:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0041ffff),
|
||||
.addRegion("Memory[bash:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0041ffff),
|
||||
Set.of(TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE));
|
||||
|
||||
TraceModule bin = tb.trace.getModuleManager()
|
||||
.addLoadedModule("/bin/bash", "/bin/bash", tb.range(0x00400000, 0x0041ffff), 0);
|
||||
bin.addSection(0, "bash[.text]", tb.range(0x00400000, 0x0040ffff));
|
||||
.addLoadedModule("Modules[/bin/bash]", "/bin/bash",
|
||||
tb.range(0x00400000, 0x0041ffff), 0);
|
||||
bin.addSection(0, "Modules[/bin/bash].Sections[.text]",
|
||||
tb.range(0x00400000, 0x0040ffff));
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
traceManager.activateTrace(tb.trace);
|
||||
@@ -464,12 +480,15 @@ public class DynamicStaticSynchronizationPluginTest
|
||||
|
||||
createAndOpenTrace();
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject("Target");
|
||||
tb.trace.getMemoryManager()
|
||||
.addRegion("bash:.text", Lifespan.nowOn(0), tb.range(0x00400000, 0x0041ffff),
|
||||
.addRegion("Memory[bash:.text]", Lifespan.nowOn(0),
|
||||
tb.range(0x00400000, 0x0041ffff),
|
||||
Set.of(TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE));
|
||||
|
||||
tb.trace.getModuleManager()
|
||||
.addLoadedModule("/bin/bash", "/bin/bash", tb.range(0x00400000, 0x0041ffff), 0);
|
||||
.addLoadedModule("Modules[/bin/bash]", "/bin/bash",
|
||||
tb.range(0x00400000, 0x0041ffff), 0);
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
traceManager.activateTrace(tb.trace);
|
||||
|
||||
+21
-26
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package ghidra.app.plugin.core.debug.service.tracemgr;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
@@ -34,16 +35,11 @@ import ghidra.debug.api.target.Target;
|
||||
import ghidra.debug.api.tracemgr.DebuggerCoordinates;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.trace.database.target.DBTraceObjectManager;
|
||||
import ghidra.trace.database.target.DBTraceObjectManagerTest;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.iface.TraceObjectEventScope;
|
||||
import ghidra.trace.model.target.iface.TraceEventScope;
|
||||
import ghidra.trace.model.target.path.KeyPath;
|
||||
import ghidra.trace.model.target.schema.SchemaContext;
|
||||
import ghidra.trace.model.target.schema.TraceObjectSchema.SchemaName;
|
||||
import ghidra.trace.model.target.schema.XmlSchemaContext;
|
||||
import ghidra.trace.model.thread.TraceObjectThread;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule.ScheduleForm;
|
||||
@@ -136,7 +132,8 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
thread = tb.getOrAddThread("Thread 1", 0);
|
||||
tb.createRootObject("Target");
|
||||
thread = tb.getOrAddThread("Threads[1]", 0);
|
||||
}
|
||||
waitForDomainObject(tb.trace);
|
||||
|
||||
@@ -236,18 +233,16 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||
|
||||
assertEquals(null, traceManager.getCurrentObject());
|
||||
|
||||
SchemaContext ctx = XmlSchemaContext.deserialize(DBTraceObjectManagerTest.XML_CTX);
|
||||
TraceObject objThread0;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
DBTraceObjectManager objectManager = tb.trace.getObjectManager();
|
||||
objectManager.createRootObject(ctx.getSchema(new SchemaName("Session"))).getChild();
|
||||
objThread0 =
|
||||
objectManager.createObject(KeyPath.parse("Targets[0].Threads[0]"));
|
||||
tb.createRootObject();
|
||||
objThread0 = objectManager.createObject(KeyPath.parse("Targets[0].Threads[0]"));
|
||||
}
|
||||
// Manager listens for the root-created event to activate it. Wait for it to clear.
|
||||
waitForDomainObject(tb.trace);
|
||||
TraceThread thread =
|
||||
Objects.requireNonNull(objThread0.queryInterface(TraceObjectThread.class));
|
||||
Objects.requireNonNull(objThread0.queryInterface(TraceThread.class));
|
||||
|
||||
traceManager.activateObject(objThread0);
|
||||
waitForSwing();
|
||||
@@ -359,7 +354,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||
public void testFollowPresent() throws Throwable {
|
||||
createRmiConnection();
|
||||
createAndOpenTrace();
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getObjectManager().createRootObject(SCHEMA_SESSION);
|
||||
thread = tb.createObjectsProcessAndThreads();
|
||||
@@ -407,7 +402,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||
createRmiConnection();
|
||||
addActivateMethods();
|
||||
createAndOpenTrace();
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getObjectManager().createRootObject(SCHEMA_SESSION);
|
||||
thread = tb.createObjectsProcessAndThreads();
|
||||
@@ -456,7 +451,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||
createRmiConnection();
|
||||
addActivateMethods();
|
||||
createAndOpenTrace();
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getObjectManager().createRootObject(SCHEMA_SESSION);
|
||||
thread = tb.createObjectsProcessAndThreads();
|
||||
@@ -502,7 +497,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||
createRmiConnection();
|
||||
addActivateWithTimeMethods();
|
||||
createAndOpenTrace();
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getObjectManager().createRootObject(SCHEMA_SESSION);
|
||||
thread = tb.createObjectsProcessAndThreads();
|
||||
@@ -530,7 +525,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||
createRmiConnection();
|
||||
addActivateMethods();
|
||||
createAndOpenTrace();
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getObjectManager().createRootObject(SCHEMA_SESSION);
|
||||
thread = tb.createObjectsProcessAndThreads();
|
||||
@@ -558,13 +553,13 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||
assertNull(target.getSupportedTimeForm(thread, 0));
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceObjectEventScope.KEY_TIME_SUPPORT,
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceEventScope.KEY_TIME_SUPPORT,
|
||||
ScheduleForm.SNAP_ONLY.name());
|
||||
}
|
||||
assertEquals(ScheduleForm.SNAP_ONLY, target.getSupportedTimeForm(thread, 0));
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceObjectEventScope.KEY_TIME_SUPPORT,
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceEventScope.KEY_TIME_SUPPORT,
|
||||
ScheduleForm.SNAP_ANY_STEPS_OPS.name());
|
||||
}
|
||||
// Constrained by method parameter
|
||||
@@ -588,25 +583,25 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||
assertNull(target.getSupportedTimeForm(thread, 0));
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceObjectEventScope.KEY_TIME_SUPPORT,
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceEventScope.KEY_TIME_SUPPORT,
|
||||
ScheduleForm.SNAP_ONLY.name());
|
||||
}
|
||||
assertEquals(ScheduleForm.SNAP_ONLY, target.getSupportedTimeForm(thread, 0));
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceObjectEventScope.KEY_TIME_SUPPORT,
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceEventScope.KEY_TIME_SUPPORT,
|
||||
ScheduleForm.SNAP_EVT_STEPS.name());
|
||||
}
|
||||
assertEquals(ScheduleForm.SNAP_EVT_STEPS, target.getSupportedTimeForm(thread, 0));
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceObjectEventScope.KEY_TIME_SUPPORT,
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceEventScope.KEY_TIME_SUPPORT,
|
||||
ScheduleForm.SNAP_ANY_STEPS.name());
|
||||
}
|
||||
assertEquals(ScheduleForm.SNAP_ANY_STEPS, target.getSupportedTimeForm(thread, 0));
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceObjectEventScope.KEY_TIME_SUPPORT,
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceEventScope.KEY_TIME_SUPPORT,
|
||||
ScheduleForm.SNAP_ANY_STEPS_OPS.name());
|
||||
}
|
||||
assertEquals(ScheduleForm.SNAP_ANY_STEPS_OPS, target.getSupportedTimeForm(thread, 0));
|
||||
@@ -617,7 +612,7 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||
createRmiConnection();
|
||||
addActivateMethods();
|
||||
createAndOpenTrace();
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getObjectManager().createRootObject(SCHEMA_SESSION);
|
||||
thread = tb.createObjectsProcessAndThreads();
|
||||
@@ -652,12 +647,12 @@ public class DebuggerTraceManagerServiceTest extends AbstractGhidraHeadedDebugge
|
||||
createRmiConnection();
|
||||
addActivateWithTimeMethods();
|
||||
createAndOpenTrace();
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
TraceObject root;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
root = tb.trace.getObjectManager().createRootObject(SCHEMA_SESSION).getChild();
|
||||
thread = tb.createObjectsProcessAndThreads();
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceObjectEventScope.KEY_TIME_SUPPORT,
|
||||
root.setAttribute(Lifespan.nowOn(0), TraceEventScope.KEY_TIME_SUPPORT,
|
||||
ScheduleForm.SNAP_EVT_STEPS.name());
|
||||
tb.trace.getTimeManager()
|
||||
.getSnapshot(0, true)
|
||||
|
||||
+13
-3
@@ -40,12 +40,13 @@ import ghidra.app.services.*;
|
||||
import ghidra.debug.api.control.ControlMode;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.lang.*;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder.ToySchemaBuilder;
|
||||
import ghidra.trace.database.memory.DBTraceMemoryManager;
|
||||
import ghidra.trace.database.memory.DBTraceMemorySpace;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.memory.TraceMemoryFlag;
|
||||
import ghidra.trace.model.stack.TraceStack;
|
||||
import ghidra.trace.model.target.schema.SchemaContext;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
|
||||
public abstract class AbstractFlatDebuggerAPITest<API extends FlatDebuggerAPI>
|
||||
@@ -79,6 +80,13 @@ public abstract class AbstractFlatDebuggerAPITest<API extends FlatDebuggerAPI>
|
||||
api.getState().setCurrentProgram(program);
|
||||
}
|
||||
|
||||
protected SchemaContext buildContext() {
|
||||
return new ToySchemaBuilder()
|
||||
.noRegisterGroups()
|
||||
.useRegistersPerFrame()
|
||||
.build();
|
||||
}
|
||||
|
||||
protected TraceThread createTraceWithThreadAndStack(boolean open) throws Throwable {
|
||||
if (open) {
|
||||
createAndOpenTrace();
|
||||
@@ -88,9 +96,9 @@ public abstract class AbstractFlatDebuggerAPITest<API extends FlatDebuggerAPI>
|
||||
}
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
thread = tb.getOrAddThread("Threads[0]", 0);
|
||||
TraceStack stack = tb.trace.getStackManager().getStack(thread, 0, true);
|
||||
stack.setDepth(0, 3, true);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 3);
|
||||
}
|
||||
waitForSwing();
|
||||
return thread;
|
||||
@@ -100,6 +108,7 @@ public abstract class AbstractFlatDebuggerAPITest<API extends FlatDebuggerAPI>
|
||||
createAndOpenTrace();
|
||||
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
DBTraceMemoryManager mm = tb.trace.getMemoryManager();
|
||||
mm.createRegion("Memory[bin.text]", 0, tb.range(0x00400000, 0x0040ffff),
|
||||
Set.of(TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE));
|
||||
@@ -128,6 +137,7 @@ public abstract class AbstractFlatDebuggerAPITest<API extends FlatDebuggerAPI>
|
||||
|
||||
CompletableFuture<Void> changesSettled;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
tb.trace.getMemoryManager()
|
||||
.createRegion("Memory[bin.text]", 0, tb.range(0x00400000, 0x00400fff),
|
||||
Set.of(TraceMemoryFlag.READ, TraceMemoryFlag.EXECUTE));
|
||||
|
||||
+2
@@ -100,6 +100,7 @@ public class DeadFlatDebuggerAPITest extends AbstractFlatDebuggerAPITest<FlatDeb
|
||||
createAndOpenTrace();
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
thread = tb.getOrAddThread("Threads[0]", 0);
|
||||
}
|
||||
waitForSwing();
|
||||
@@ -130,6 +131,7 @@ public class DeadFlatDebuggerAPITest extends AbstractFlatDebuggerAPITest<FlatDeb
|
||||
createAndOpenTrace();
|
||||
TraceThread thread;
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.createRootObject(buildContext(), "Target");
|
||||
thread = tb.getOrAddThread("Threads[0]", 0);
|
||||
TraceStack stack = tb.trace.getStackManager().getStack(thread, 0, true);
|
||||
stack.setDepth(0, 3, true);
|
||||
|
||||
+2
-4
@@ -38,7 +38,6 @@ import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.trace.database.memory.DBTraceMemorySpace;
|
||||
import ghidra.trace.database.target.DBTraceObjectManager;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.thread.TraceObjectThread;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
|
||||
public class FlatDebuggerRmiAPITest extends AbstractLiveFlatDebuggerAPITest<FlatDebuggerRmiAPI> {
|
||||
@@ -74,7 +73,7 @@ public class FlatDebuggerRmiAPITest extends AbstractLiveFlatDebuggerAPITest<Flat
|
||||
objs.createRootObject(SCHEMA_SESSION);
|
||||
tb.createObjectsProcessAndThreads();
|
||||
tb.createObjectsFramesAndRegs(
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceObjectThread.class),
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class),
|
||||
Lifespan.nowOn(0), tb.host, 2);
|
||||
addMemoryRegion(objs, Lifespan.nowOn(0), tb.range(0x00400000, 0x00400fff), ".text",
|
||||
"rx");
|
||||
@@ -201,8 +200,7 @@ public class FlatDebuggerRmiAPITest extends AbstractLiveFlatDebuggerAPITest<Flat
|
||||
protected void runTestStep(Predicate<TraceThread> step, Supplier<TestRemoteMethod> method)
|
||||
throws Throwable {
|
||||
createTarget();
|
||||
TraceObjectThread thread =
|
||||
tb.obj("Processes[1].Threads[1]").queryInterface(TraceObjectThread.class);
|
||||
TraceThread thread = tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class);
|
||||
traceManager.activateThread(thread);
|
||||
waitForSwing();
|
||||
|
||||
|
||||
+5
-5
@@ -31,16 +31,16 @@ import ghidra.pcode.exec.PcodeArithmetic.Purpose;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.memory.TraceMemorySpace;
|
||||
import ghidra.trace.model.stack.TraceObjectStackFrame;
|
||||
import ghidra.trace.model.stack.TraceStackFrame;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.thread.TraceObjectThread;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.time.TraceSnapshot;
|
||||
import ghidra.trace.model.time.schedule.TraceSchedule;
|
||||
|
||||
public class TraceRmiPcodeExecTest extends AbstractGhidraHeadedDebuggerIntegrationTest {
|
||||
|
||||
Target target;
|
||||
TraceObjectThread thread;
|
||||
TraceThread thread;
|
||||
SleighLanguage language;
|
||||
|
||||
protected void setupExecTest() throws Throwable {
|
||||
@@ -50,7 +50,7 @@ public class TraceRmiPcodeExecTest extends AbstractGhidraHeadedDebuggerIntegrati
|
||||
try (Transaction tx = tb.startTransaction()) {
|
||||
tb.trace.getObjectManager().createRootObject(SCHEMA_SESSION);
|
||||
tb.createObjectsProcessAndThreads();
|
||||
thread = tb.obj("Processes[1].Threads[1]").queryInterface(TraceObjectThread.class);
|
||||
thread = tb.obj("Processes[1].Threads[1]").queryInterface(TraceThread.class);
|
||||
tb.createObjectsFramesAndRegs(thread, Lifespan.nowOn(0), tb.host, 1);
|
||||
}
|
||||
target = rmiCx.publishTarget(tool, tb.trace);
|
||||
@@ -149,7 +149,7 @@ public class TraceRmiPcodeExecTest extends AbstractGhidraHeadedDebuggerIntegrati
|
||||
});
|
||||
|
||||
handleWriteRegInvocation(
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceObjectStackFrame.class),
|
||||
tb.obj("Processes[1].Threads[1].Stack[0]").queryInterface(TraceStackFrame.class),
|
||||
"r2", 11);
|
||||
|
||||
waitOn(futResult);
|
||||
|
||||
Reference in New Issue
Block a user