mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-3818: Create TraceRMI launcher framework. Launch script for gdb.
This commit is contained in:
@@ -61,12 +61,9 @@ import ghidra.app.plugin.core.debug.gui.thread.DebuggerThreadsProvider;
|
||||
import ghidra.app.plugin.core.debug.gui.time.DebuggerTimeProvider;
|
||||
import ghidra.app.plugin.core.debug.gui.time.DebuggerTimeSelectionDialog;
|
||||
import ghidra.app.plugin.core.debug.gui.watch.DebuggerWatchesProvider;
|
||||
import ghidra.app.plugin.core.debug.gui.watch.WatchRow;
|
||||
import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin;
|
||||
import ghidra.app.plugin.core.debug.service.emulation.DebuggerEmulationServicePlugin.EmulateProgramAction;
|
||||
import ghidra.app.plugin.core.debug.service.model.DebuggerConnectDialog;
|
||||
import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer;
|
||||
import ghidra.app.plugin.core.debug.service.model.launch.DebuggerProgramLaunchOffer.*;
|
||||
import ghidra.app.plugin.core.debug.stack.StackUnwinderTest;
|
||||
import ghidra.app.plugin.core.debug.stack.StackUnwinderTest.HoverLocation;
|
||||
import ghidra.app.plugin.core.debug.stack.UnwindStackCommand;
|
||||
@@ -84,6 +81,10 @@ import ghidra.dbg.target.TargetLauncher;
|
||||
import ghidra.dbg.target.TargetLauncher.TargetCmdLineLauncher;
|
||||
import ghidra.dbg.testutil.DummyProc;
|
||||
import ghidra.dbg.util.ConfigurableFactory.Property;
|
||||
import ghidra.debug.api.model.DebuggerProgramLaunchOffer;
|
||||
import ghidra.debug.api.model.DebuggerProgramLaunchOffer.*;
|
||||
import ghidra.debug.api.watch.WatchRow;
|
||||
import ghidra.debug.api.workflow.DebuggerBot;
|
||||
import ghidra.debug.flatapi.FlatDebuggerAPI;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.TestApplicationUtils;
|
||||
|
||||
@@ -15,55 +15,30 @@
|
||||
*/
|
||||
package agent.dbgeng.rmi;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.nio.file.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.junit.Before;
|
||||
|
||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteAsyncResult;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiAcceptor;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiHandler;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiPlugin;
|
||||
import ghidra.app.plugin.core.debug.utils.ManagedDomainObject;
|
||||
import ghidra.app.services.TraceRmiService;
|
||||
import ghidra.dbg.testutil.DummyProc;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.OperatingSystem;
|
||||
import ghidra.framework.TestApplicationUtils;
|
||||
import ghidra.debug.api.tracermi.*;
|
||||
import ghidra.framework.*;
|
||||
import ghidra.framework.main.ApplicationLevelOnlyPlugin;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.plugintool.Plugin;
|
||||
import ghidra.framework.plugintool.PluginsConfiguration;
|
||||
import ghidra.framework.plugintool.util.PluginDescription;
|
||||
import ghidra.framework.plugintool.util.PluginException;
|
||||
import ghidra.framework.plugintool.util.PluginPackage;
|
||||
import ghidra.framework.plugintool.util.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRangeImpl;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
@@ -174,10 +149,10 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb
|
||||
// If commands come from file, Python will quit after EOF.
|
||||
Msg.info(this, "outFile: " + outFile);
|
||||
Msg.info(this, "errFile: " + errFile);
|
||||
|
||||
|
||||
//pb.inheritIO();
|
||||
pb.redirectInput(ProcessBuilder.Redirect.PIPE);
|
||||
pb.redirectOutput(outFile.toFile());
|
||||
pb.redirectOutput(outFile.toFile());
|
||||
pb.redirectError(errFile.toFile());
|
||||
Process pyproc = pb.start();
|
||||
OutputStream stdin = pyproc.getOutputStream();
|
||||
@@ -195,7 +170,7 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb
|
||||
}
|
||||
Msg.info(this, "Python exited with code " + pyproc.exitValue());
|
||||
return new PythonResult(false, pyproc.exitValue(), Files.readString(outFile),
|
||||
Files.readString(errFile));
|
||||
Files.readString(errFile));
|
||||
}
|
||||
catch (Exception e) {
|
||||
return ExceptionUtils.rethrow(e);
|
||||
@@ -230,10 +205,10 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb
|
||||
return result.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).handle();
|
||||
}
|
||||
|
||||
protected record PythonAndHandler(ExecInPython exec, TraceRmiHandler handler)
|
||||
protected record PythonAndConnection(ExecInPython exec, TraceRmiConnection connection)
|
||||
implements AutoCloseable {
|
||||
protected RemoteMethod getMethod(String name) {
|
||||
return Objects.requireNonNull(handler.getMethods().get(name));
|
||||
return Objects.requireNonNull(connection.getMethods().get(name));
|
||||
}
|
||||
|
||||
public void execute(String cmd) {
|
||||
@@ -258,7 +233,7 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb
|
||||
try {
|
||||
PythonResult r = exec.future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
r.handle();
|
||||
waitForPass(() -> assertTrue(handler.isClosed()));
|
||||
waitForPass(() -> assertTrue(connection.isClosed()));
|
||||
}
|
||||
finally {
|
||||
exec.python.destroyForcibly();
|
||||
@@ -266,15 +241,15 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb
|
||||
}
|
||||
}
|
||||
|
||||
protected PythonAndHandler startAndConnectPython(Function<String, String> scriptSupplier)
|
||||
protected PythonAndConnection startAndConnectPython(Function<String, String> scriptSupplier)
|
||||
throws Exception {
|
||||
TraceRmiAcceptor acceptor = traceRmi.acceptOne(null);
|
||||
ExecInPython exec =
|
||||
execInPython(scriptSupplier.apply(sockToStringForPython(acceptor.getAddress())));
|
||||
acceptor.setTimeout(CONNECT_TIMEOUT_MS);
|
||||
try {
|
||||
TraceRmiHandler handler = acceptor.accept();
|
||||
return new PythonAndHandler(exec, handler);
|
||||
TraceRmiConnection connection = acceptor.accept();
|
||||
return new PythonAndConnection(exec, connection);
|
||||
}
|
||||
catch (SocketTimeoutException e) {
|
||||
exec.python.destroyForcibly();
|
||||
@@ -283,7 +258,7 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb
|
||||
}
|
||||
}
|
||||
|
||||
protected PythonAndHandler startAndConnectPython() throws Exception {
|
||||
protected PythonAndConnection startAndConnectPython() throws Exception {
|
||||
return startAndConnectPython(addr -> """
|
||||
%s
|
||||
ghidra_trace_connect('%s')
|
||||
@@ -293,10 +268,10 @@ public abstract class AbstractDbgEngTraceRmiTest extends AbstractGhidraHeadedDeb
|
||||
@SuppressWarnings("resource")
|
||||
protected String runThrowError(Function<String, String> scriptSupplier)
|
||||
throws Exception {
|
||||
PythonAndHandler conn = startAndConnectPython(scriptSupplier);
|
||||
PythonAndConnection conn = startAndConnectPython(scriptSupplier);
|
||||
PythonResult r = conn.exec.future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
String stdout = r.handle();
|
||||
waitForPass(() -> assertTrue(conn.handler.isClosed()));
|
||||
waitForPass(() -> assertTrue(conn.connection.isClosed()));
|
||||
return stdout;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,28 +15,12 @@
|
||||
*/
|
||||
package agent.dbgeng.rmi;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -45,30 +29,20 @@ import java.util.stream.IntStream;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.Unique;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiAcceptor;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiHandler;
|
||||
import ghidra.app.plugin.core.debug.utils.ManagedDomainObject;
|
||||
import ghidra.dbg.util.PathPredicates;
|
||||
import ghidra.debug.api.tracermi.TraceRmiAcceptor;
|
||||
import ghidra.debug.api.tracermi.TraceRmiConnection;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressRange;
|
||||
import ghidra.program.model.address.AddressRangeImpl;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
import ghidra.trace.model.ImmutableTraceAddressSnapRange;
|
||||
import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.TraceAddressSnapRange;
|
||||
import ghidra.trace.model.*;
|
||||
import ghidra.trace.model.breakpoint.TraceBreakpointKind;
|
||||
import ghidra.trace.model.memory.TraceMemoryRegion;
|
||||
import ghidra.trace.model.memory.TraceMemorySpace;
|
||||
import ghidra.trace.model.memory.TraceMemoryState;
|
||||
import ghidra.trace.model.memory.*;
|
||||
import ghidra.trace.model.modules.TraceModule;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.target.TraceObjectKeyPath;
|
||||
import ghidra.trace.model.target.TraceObjectValue;
|
||||
import ghidra.trace.model.target.*;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.time.TraceSnapshot;
|
||||
import ghidra.util.Msg;
|
||||
@@ -80,9 +54,9 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
TraceRmiAcceptor acceptor = traceRmi.acceptOne(null);
|
||||
Msg.info(this,
|
||||
"Use: ghidra_trace_connect(" + sockToStringForPython(acceptor.getAddress()) + ")");
|
||||
TraceRmiHandler handler = acceptor.accept();
|
||||
Msg.info(this, "Connected: " + sockToStringForPython(handler.getRemoteAddress()));
|
||||
handler.waitClosed();
|
||||
TraceRmiConnection connection = acceptor.accept();
|
||||
Msg.info(this, "Connected: " + sockToStringForPython(connection.getRemoteAddress()));
|
||||
connection.waitClosed();
|
||||
Msg.info(this, "Closed");
|
||||
}
|
||||
|
||||
@@ -186,7 +160,8 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
ghidra_trace_stop()
|
||||
quit()
|
||||
""".formatted(PREAMBLE, addr));
|
||||
DomainFile dfBash = env.getProject().getProjectData().getFile("/New Traces/pydbg/notepad.exe");
|
||||
DomainFile dfBash =
|
||||
env.getProject().getProjectData().getFile("/New Traces/pydbg/notepad.exe");
|
||||
assertNotNull(dfBash);
|
||||
// TODO: Given the 'quit' command, I'm not sure this assertion is checking anything.
|
||||
assertFalse(dfBash.isOpen());
|
||||
@@ -222,18 +197,18 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
extractOutSection(out, "---Import---"));
|
||||
assertEquals("""
|
||||
Connected to Ghidra at %s
|
||||
|
||||
|
||||
No trace""".formatted(refAddr.get()),
|
||||
extractOutSection(out, "---Connect---").replaceAll("\r", "").substring(0,48));
|
||||
extractOutSection(out, "---Connect---").replaceAll("\r", "").substring(0, 48));
|
||||
String expected = """
|
||||
Connected to Ghidra at %s
|
||||
|
||||
|
||||
Trace active""".formatted(refAddr.get());
|
||||
String actual = extractOutSection(out, "---Start---").replaceAll("\r", "");
|
||||
assertEquals(expected, actual.substring(0,expected.length()));
|
||||
assertEquals(expected, actual.substring(0, expected.length()));
|
||||
assertEquals("""
|
||||
Connected to Ghidra at %s
|
||||
|
||||
|
||||
No trace""".formatted(refAddr.get()),
|
||||
extractOutSection(out, "---Stop---").replaceAll("\r", ""));
|
||||
assertEquals("""
|
||||
@@ -245,7 +220,7 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
public void testLcsp() throws Exception {
|
||||
// TODO: This test assumes x86-64 on test system
|
||||
String out = runThrowError(
|
||||
"""
|
||||
"""
|
||||
%s
|
||||
print('---Import---')
|
||||
ghidra_trace_info_lcsp()
|
||||
@@ -263,19 +238,20 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
""".formatted(PREAMBLE));
|
||||
|
||||
assertTrue(
|
||||
extractOutSection(out, "---File---").replaceAll("\r", "").contains(
|
||||
"""
|
||||
Selected Ghidra language: x86:LE:64:default
|
||||
|
||||
Selected Ghidra compiler: windows"""));
|
||||
extractOutSection(out, "---File---").replaceAll("\r", "")
|
||||
.contains(
|
||||
"""
|
||||
Selected Ghidra language: x86:LE:64:default
|
||||
|
||||
Selected Ghidra compiler: windows"""));
|
||||
assertEquals("""
|
||||
Selected Ghidra language: Toy:BE:64:default
|
||||
|
||||
|
||||
Selected Ghidra compiler: default""",
|
||||
extractOutSection(out, "---Language---").replaceAll("\r", ""));
|
||||
assertEquals("""
|
||||
Selected Ghidra language: Toy:BE:64:default
|
||||
|
||||
|
||||
Selected Ghidra compiler: posStack""",
|
||||
extractOutSection(out, "---Compiler---").replaceAll("\r", ""));
|
||||
}
|
||||
@@ -475,8 +451,8 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
* code.definedData() // .create(Lifespan.nowOn(0), tb.reg("st0"),
|
||||
* Float10DataType.dataType); // } // assertEquals("1.5",
|
||||
* st0.getDefaultValueRepresentation());
|
||||
*/
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -526,8 +502,8 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
* code.definedData() // .create(Lifespan.nowOn(0), tb.reg("st0"),
|
||||
* Float10DataType.dataType); // } // assertEquals("0.0",
|
||||
* st0.getDefaultValueRepresentation());
|
||||
*/
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -814,7 +790,7 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
assertNotNull(object);
|
||||
String expected = "1\tTest.Objects[1]";
|
||||
String actual = extractOutSection(out, "---GetObject---");
|
||||
assertEquals(expected, actual.substring(0,expected.length()));
|
||||
assertEquals(expected, actual.substring(0, expected.length()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,12 +851,14 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
Test.Objects[1] vshortarr [0,+inf) [1, 2, 3] SHORT_ARR
|
||||
Test.Objects[1] vstring [0,+inf) 'Hello' STRING
|
||||
Test.Objects[1] vaddr [0,+inf) ram:deadbeef ADDRESS"""
|
||||
.replaceAll(" ", "")
|
||||
.replaceAll(" ", "")
|
||||
.replaceAll("\n", "");
|
||||
String actual = extractOutSection(out, "---GetValues---").replaceAll(" ", "")
|
||||
.replaceAll("\r", "")
|
||||
.replaceAll("\n", "");
|
||||
String actual = extractOutSection(out, "---GetValues---").replaceAll(" ", "").replaceAll("\r", "").replaceAll("\n", "");
|
||||
assertEquals(
|
||||
expected,
|
||||
actual.substring(0,expected.length()));
|
||||
actual.substring(0, expected.length()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -905,7 +883,7 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
String expected = """
|
||||
Parent Key Span Value Type
|
||||
|
||||
|
||||
Test.Objects[1] vaddr [0,+inf) ram:deadbeef ADDRESS""";
|
||||
String actual = extractOutSection(out, "---GetValues---").replaceAll("\r", "");
|
||||
assertEquals(expected, actual.substring(0, expected.length()));
|
||||
@@ -957,7 +935,7 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
total += cu.getLength();
|
||||
}
|
||||
String extract = extractOutSection(out, "---Disassemble---");
|
||||
String [] split = extract.split("\r\n");
|
||||
String[] split = extract.split("\r\n");
|
||||
assertEquals("Disassembled %d bytes".formatted(total),
|
||||
split[0]);
|
||||
}
|
||||
@@ -1208,14 +1186,14 @@ public class DbgEngCommandsTest extends AbstractDbgEngTraceRmiTest {
|
||||
quit()
|
||||
""".formatted(PREAMBLE, addr));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMinimal2() throws Exception {
|
||||
Function<String, String> scriptSupplier = addr -> """
|
||||
%s
|
||||
ghidra_trace_connect('%s')
|
||||
""".formatted(PREAMBLE, addr);
|
||||
try (PythonAndHandler conn = startAndConnectPython(scriptSupplier)) {
|
||||
try (PythonAndConnection conn = startAndConnectPython(scriptSupplier)) {
|
||||
conn.execute("print('FINISHED')");
|
||||
conn.close();
|
||||
}
|
||||
|
||||
@@ -16,10 +16,7 @@
|
||||
package agent.dbgeng.rmi;
|
||||
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
@@ -28,9 +25,7 @@ import java.util.Objects;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod;
|
||||
import ghidra.app.plugin.core.debug.utils.ManagedDomainObject;
|
||||
import ghidra.dbg.testutil.DummyProc;
|
||||
import ghidra.dbg.util.PathPattern;
|
||||
import ghidra.dbg.util.PathPredicates;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
@@ -39,14 +34,13 @@ import ghidra.trace.model.Lifespan;
|
||||
import ghidra.trace.model.Trace;
|
||||
import ghidra.trace.model.memory.TraceMemorySpace;
|
||||
import ghidra.trace.model.target.TraceObject;
|
||||
import ghidra.trace.model.thread.TraceThread;
|
||||
import ghidra.trace.model.time.TraceSnapshot;
|
||||
|
||||
public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest {
|
||||
private static final long RUN_TIMEOUT_MS = 20000;
|
||||
private static final long RETRY_MS = 500;
|
||||
|
||||
record PythonAndTrace(PythonAndHandler conn, ManagedDomainObject mdo) implements AutoCloseable {
|
||||
record PythonAndTrace(PythonAndConnection conn, ManagedDomainObject mdo) implements AutoCloseable {
|
||||
public void execute(String cmd) {
|
||||
conn.execute(cmd);
|
||||
}
|
||||
@@ -64,20 +58,20 @@ public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
protected PythonAndTrace startAndSyncPython(String exec) throws Exception {
|
||||
PythonAndHandler conn = startAndConnectPython();
|
||||
PythonAndConnection conn = startAndConnectPython();
|
||||
try {
|
||||
ManagedDomainObject mdo;
|
||||
conn.execute("from ghidradbg.commands import *");
|
||||
conn.execute(
|
||||
"util.set_convenience_variable('ghidra-language', 'x86:LE:64:default')");
|
||||
if (exec != null) {
|
||||
start(conn, exec);
|
||||
mdo = waitDomainObject("/New Traces/pydbg/"+exec);
|
||||
}
|
||||
else {
|
||||
conn.execute("ghidra_trace_start()");
|
||||
mdo = waitDomainObject("/New Traces/pydbg/noname");
|
||||
}
|
||||
if (exec != null) {
|
||||
start(conn, exec);
|
||||
mdo = waitDomainObject("/New Traces/pydbg/" + exec);
|
||||
}
|
||||
else {
|
||||
conn.execute("ghidra_trace_start()");
|
||||
mdo = waitDomainObject("/New Traces/pydbg/noname");
|
||||
}
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
return new PythonAndTrace(conn, mdo);
|
||||
}
|
||||
@@ -88,7 +82,7 @@ public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest {
|
||||
}
|
||||
|
||||
protected long lastSnap(PythonAndTrace conn) {
|
||||
return conn.conn.handler().getLastSnapshot(tb.trace);
|
||||
return conn.conn.connection().getLastSnapshot(tb.trace);
|
||||
}
|
||||
|
||||
@Test // The 10s wait makes this a pretty expensive test
|
||||
@@ -110,7 +104,8 @@ public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
conn.execute("dbg().go(10)");
|
||||
|
||||
waitForPass(() -> assertTrue(tb.objValues(lastSnap(conn), "Processes[].Threads[]").size() > 4),
|
||||
waitForPass(
|
||||
() -> assertTrue(tb.objValues(lastSnap(conn), "Processes[].Threads[]").size() > 4),
|
||||
RUN_TIMEOUT_MS, RETRY_MS);
|
||||
}
|
||||
}
|
||||
@@ -203,8 +198,8 @@ public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest {
|
||||
conn.execute("ghidra_trace_txstart('Tx')");
|
||||
conn.execute("ghidra_trace_putmem('$pc 10')");
|
||||
conn.execute("ghidra_trace_txcommit()");
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
conn.execute("util.get_debugger().write("+address+", b'\\x7f')");
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
conn.execute("util.get_debugger().write(" + address + ", b'\\x7f')");
|
||||
|
||||
waitForPass(() -> {
|
||||
ByteBuffer buf = ByteBuffer.allocate(10);
|
||||
@@ -322,7 +317,7 @@ public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest {
|
||||
conn.execute("dbg.stepi()");
|
||||
assertEquals(false, tb.objValue(brk, lastSnap(conn), "Enabled"));
|
||||
|
||||
/* Not currently enabled
|
||||
/* Not currently enabled
|
||||
assertEquals("", tb.objValue(brk, lastSnap(conn), "Command"));
|
||||
conn.execute("dbg.bp(expr=pc, windbgcmd='bl')");
|
||||
conn.execute("dbg.stepi()");
|
||||
@@ -356,23 +351,23 @@ public class DbgEngHooksTest extends AbstractDbgEngTraceRmiTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void start(PythonAndHandler conn, String obj) {
|
||||
private void start(PythonAndConnection conn, String obj) {
|
||||
conn.execute("from ghidradbg.commands import *");
|
||||
if (obj != null)
|
||||
conn.execute("ghidra_trace_create('"+obj+"')");
|
||||
else
|
||||
conn.execute("ghidra_trace_create()");
|
||||
conn.execute("ghidra_trace_create('" + obj + "')");
|
||||
else
|
||||
conn.execute("ghidra_trace_create()");
|
||||
conn.execute("ghidra_trace_sync_enable()");
|
||||
}
|
||||
|
||||
private void txPut(PythonAndTrace conn, String obj) {
|
||||
conn.execute("ghidra_trace_txstart('Tx" + obj + "')");
|
||||
conn.execute("ghidra_trace_put_" + obj +"()");
|
||||
conn.execute("ghidra_trace_put_" + obj + "()");
|
||||
conn.execute("ghidra_trace_txcommit()");
|
||||
}
|
||||
|
||||
private long getAddressAtOffset(PythonAndTrace conn, int offset) {
|
||||
String inst = "util.get_inst(util.get_debugger().reg.get_pc()+"+offset+")";
|
||||
String inst = "util.get_inst(util.get_debugger().reg.get_pc()+" + offset + ")";
|
||||
String ret = conn.executeCapture(inst);
|
||||
String[] split = ret.split("\\s+"); // get target
|
||||
return Long.decode(split[1]);
|
||||
|
||||
@@ -24,12 +24,11 @@ import java.util.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.Unique;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.ValueDecoder;
|
||||
import ghidra.app.plugin.core.debug.utils.ManagedDomainObject;
|
||||
import ghidra.dbg.testutil.DummyProc;
|
||||
import ghidra.dbg.util.PathPattern;
|
||||
import ghidra.dbg.util.PathPredicates;
|
||||
import ghidra.debug.api.tracermi.RemoteMethod;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
@@ -46,7 +45,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testEvaluate() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
RemoteMethod evaluate = conn.getMethod("evaluate");
|
||||
assertEquals("11",
|
||||
evaluate.invoke(Map.of("expr", "3+4*2")));
|
||||
@@ -55,10 +54,9 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testExecuteCapture() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
RemoteMethod execute = conn.getMethod("execute");
|
||||
assertEquals(false,
|
||||
execute.parameters().get("to_string").defaultValue().get(ValueDecoder.DEFAULT));
|
||||
assertEquals(false, execute.parameters().get("to_string").getDefaultValue());
|
||||
assertEquals("11\n",
|
||||
execute.invoke(Map.of("cmd", "print(3+4*2)", "to_string", true)));
|
||||
}
|
||||
@@ -66,7 +64,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testExecute() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
conn.execute("ghidra_trace_kill()");
|
||||
}
|
||||
@@ -77,7 +75,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshAvailable() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, null);
|
||||
txCreate(conn, "Available");
|
||||
|
||||
@@ -100,7 +98,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshBreakpoints() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -113,7 +111,8 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
conn.execute("dbg.bp(expr=pc)");
|
||||
conn.execute("dbg.ba(expr=pc+4)");
|
||||
txPut(conn, "breakpoints");
|
||||
TraceObject breakpoints = Objects.requireNonNull(tb.objAny("Processes[].Breakpoints"));
|
||||
TraceObject breakpoints =
|
||||
Objects.requireNonNull(tb.objAny("Processes[].Breakpoints"));
|
||||
refreshBreakpoints.invoke(Map.of("node", breakpoints));
|
||||
|
||||
List<TraceObjectValue> procBreakLocVals = tb.trace.getObjectManager()
|
||||
@@ -138,7 +137,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshBreakpoints2() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "all");
|
||||
|
||||
@@ -186,7 +185,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshProcesses() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, null);
|
||||
txCreate(conn, "Processes");
|
||||
txCreate(conn, "Processes[1]");
|
||||
@@ -210,7 +209,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshEnvironment() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
String path = "Processes[].Environment";
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "all");
|
||||
@@ -233,7 +232,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshThreads() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
String path = "Processes[].Threads";
|
||||
start(conn, "notepad.exe");
|
||||
txCreate(conn, path);
|
||||
@@ -254,7 +253,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshStack() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
String path = "Processes[].Threads[].Stack";
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
@@ -280,7 +279,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshRegisters() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
String path = "Processes[].Threads[].Registers";
|
||||
start(conn, "notepad.exe");
|
||||
conn.execute("ghidra_trace_txstart('Tx')");
|
||||
@@ -309,7 +308,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshMappings() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
String path = "Processes[].Memory";
|
||||
start(conn, "notepad.exe");
|
||||
txCreate(conn, path);
|
||||
@@ -331,7 +330,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshModules() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
String path = "Processes[].Modules";
|
||||
start(conn, "notepad.exe");
|
||||
txCreate(conn, path);
|
||||
@@ -354,7 +353,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testActivateThread() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -384,7 +383,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRemoveProcess() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "netstat.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -404,7 +403,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
@Test
|
||||
public void testAttachObj() throws Exception {
|
||||
try (DummyProc dproc = DummyProc.run("notepad.exe")) {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, null);
|
||||
txPut(conn, "available");
|
||||
|
||||
@@ -425,14 +424,15 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
@Test
|
||||
public void testAttachPid() throws Exception {
|
||||
try (DummyProc dproc = DummyProc.run("notepad.exe")) {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, null);
|
||||
txPut(conn, "available");
|
||||
|
||||
RemoteMethod attachPid = conn.getMethod("attach_pid");
|
||||
try (ManagedDomainObject mdo = openDomainObject("/New Traces/pydbg/noname")) {
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
Objects.requireNonNull(tb.objAny("Available["+dproc.pid+"]", Lifespan.at(0)));
|
||||
Objects.requireNonNull(
|
||||
tb.objAny("Available[" + dproc.pid + "]", Lifespan.at(0)));
|
||||
attachPid.invoke(Map.of("pid", dproc.pid));
|
||||
|
||||
String out = conn.executeCapture("list(util.process_list())");
|
||||
@@ -444,7 +444,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testDetach() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "netstat.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -463,7 +463,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testLaunchEntry() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, null);
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -472,7 +472,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
|
||||
launch.invoke(Map.ofEntries(
|
||||
Map.entry("file", "notepad.exe")));
|
||||
Map.entry("file", "notepad.exe")));
|
||||
|
||||
String out = conn.executeCapture("list(util.process_list())");
|
||||
assertThat(out, containsString("notepad.exe"));
|
||||
@@ -482,7 +482,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test //Can't do this test because create(xxx, initial_break=False) doesn't return
|
||||
public void testLaunch() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, null);
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -502,9 +502,9 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void testKill() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -524,7 +524,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testStepInto() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -547,7 +547,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
// lab1:
|
||||
// addr1
|
||||
String[] split = disCall.split("\\s+"); // get target
|
||||
long pcCallee = Long.decode(split[split.length-1]);
|
||||
long pcCallee = Long.decode(split[split.length - 1]);
|
||||
|
||||
step_into.invoke(Map.of("thread", thread));
|
||||
long pc = getAddressAtOffset(conn, 0);
|
||||
@@ -558,7 +558,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testStepOver() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -576,7 +576,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
String disCall = getInst(conn);
|
||||
String[] split = disCall.split("\\s+"); // get target
|
||||
long pcCallee = Long.decode(split[split.length-1]);
|
||||
long pcCallee = Long.decode(split[split.length - 1]);
|
||||
|
||||
step_over.invoke(Map.of("thread", thread));
|
||||
long pc = getAddressAtOffset(conn, 0);
|
||||
@@ -585,9 +585,9 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void testStepTo() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
|
||||
RemoteMethod step_into = conn.getMethod("step_into");
|
||||
@@ -601,7 +601,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
step_into.invoke(Map.of("thread", thread));
|
||||
}
|
||||
step_into.invoke(Map.of("thread", thread));
|
||||
|
||||
|
||||
int sz = Integer.parseInt(getInstSizeAtOffset(conn, 0));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
sz += Integer.parseInt(getInstSizeAtOffset(conn, sz));
|
||||
@@ -609,9 +609,10 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
long pcNext = getAddressAtOffset(conn, sz);
|
||||
|
||||
boolean success = (boolean) step_to.invoke(Map.of("thread", thread, "address", tb.addr(pcNext), "max", 10));
|
||||
boolean success = (boolean) step_to
|
||||
.invoke(Map.of("thread", thread, "address", tb.addr(pcNext), "max", 10));
|
||||
assertTrue(success);
|
||||
|
||||
|
||||
long pc = getAddressAtOffset(conn, 0);
|
||||
assertEquals(pcNext, pc);
|
||||
}
|
||||
@@ -620,7 +621,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testStepOut() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -650,7 +651,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakAddress() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -659,8 +660,8 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
|
||||
TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]"));
|
||||
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
breakAddress.invoke(Map.of("process", proc, "address", tb.addr(address)));
|
||||
|
||||
String out = conn.executeCapture("list(util.get_breakpoints())");
|
||||
@@ -671,7 +672,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakExpression() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -688,9 +689,9 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void testBreakHardwareAddress() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -699,8 +700,8 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
|
||||
TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]"));
|
||||
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
breakAddress.invoke(Map.of("process", proc, "address", tb.addr(address)));
|
||||
|
||||
String out = conn.executeCapture("list(util.get_breakpoints())");
|
||||
@@ -711,7 +712,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakHardwareExpression() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -730,7 +731,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakReadRange() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -740,7 +741,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
waitStopped();
|
||||
|
||||
TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]"));
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
AddressRange range = tb.range(address, address + 3); // length 4
|
||||
breakRange.invoke(Map.of("process", proc, "range", range));
|
||||
|
||||
@@ -754,7 +755,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakReadExpression() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -763,10 +764,10 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
|
||||
breakExpression.invoke(Map.of("expression", "ntdll!LdrInitShimEngineDynamic"));
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
|
||||
String out = conn.executeCapture("list(util.get_breakpoints())");
|
||||
assertThat(out, containsString(Long.toHexString(address>>24)));
|
||||
assertThat(out, containsString(Long.toHexString(address >> 24)));
|
||||
assertThat(out, containsString("sz=1"));
|
||||
assertThat(out, containsString("type=r"));
|
||||
}
|
||||
@@ -775,7 +776,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakWriteRange() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -785,7 +786,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
waitStopped();
|
||||
|
||||
TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]"));
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
AddressRange range = tb.range(address, address + 3); // length 4
|
||||
breakRange.invoke(Map.of("process", proc, "range", range));
|
||||
|
||||
@@ -799,7 +800,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakWriteExpression() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -808,10 +809,10 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
|
||||
breakExpression.invoke(Map.of("expression", "ntdll!LdrInitShimEngineDynamic"));
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
|
||||
String out = conn.executeCapture("list(util.get_breakpoints())");
|
||||
assertThat(out, containsString(Long.toHexString(address>>24)));
|
||||
assertThat(out, containsString(Long.toHexString(address >> 24)));
|
||||
assertThat(out, containsString("sz=1"));
|
||||
assertThat(out, containsString("type=w"));
|
||||
}
|
||||
@@ -820,7 +821,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakAccessRange() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -830,7 +831,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
waitStopped();
|
||||
|
||||
TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]"));
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
AddressRange range = tb.range(address, address + 3); // length 4
|
||||
breakRange.invoke(Map.of("process", proc, "range", range));
|
||||
|
||||
@@ -844,7 +845,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakAccessExpression() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -853,10 +854,10 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
|
||||
breakExpression.invoke(Map.of("expression", "ntdll!LdrInitShimEngineDynamic"));
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
|
||||
String out = conn.executeCapture("list(util.get_breakpoints())");
|
||||
assertThat(out, containsString(Long.toHexString(address>>24)));
|
||||
assertThat(out, containsString(Long.toHexString(address >> 24)));
|
||||
assertThat(out, containsString("sz=1"));
|
||||
assertThat(out, containsString("type=rw"));
|
||||
}
|
||||
@@ -865,7 +866,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testToggleBreakpoint() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -874,7 +875,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
try (ManagedDomainObject mdo = openDomainObject("/New Traces/pydbg/notepad.exe")) {
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]"));
|
||||
breakAddress.invoke(Map.of("process", proc, "address", tb.addr(address)));
|
||||
|
||||
@@ -891,7 +892,7 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testDeleteBreakpoint() throws Exception {
|
||||
try (PythonAndHandler conn = startAndConnectPython()) {
|
||||
try (PythonAndConnection conn = startAndConnectPython()) {
|
||||
start(conn, "notepad.exe");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -899,8 +900,8 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
RemoteMethod deleteBreakpoint = conn.getMethod("delete_breakpoint");
|
||||
try (ManagedDomainObject mdo = openDomainObject("/New Traces/pydbg/notepad.exe")) {
|
||||
tb = new ToyDBTraceBuilder((Trace) mdo.get());
|
||||
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
|
||||
long address = getAddressAtOffset(conn, 0);
|
||||
TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]"));
|
||||
breakAddress.invoke(Map.of("process", proc, "address", tb.addr(address)));
|
||||
|
||||
@@ -915,42 +916,43 @@ public class DbgEngMethodsTest extends AbstractDbgEngTraceRmiTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void start(PythonAndHandler conn, String obj) {
|
||||
private void start(PythonAndConnection conn, String obj) {
|
||||
conn.execute("from ghidradbg.commands import *");
|
||||
if (obj != null)
|
||||
conn.execute("ghidra_trace_create('"+obj+"')");
|
||||
else
|
||||
conn.execute("ghidra_trace_create()"); }
|
||||
conn.execute("ghidra_trace_create('" + obj + "')");
|
||||
else
|
||||
conn.execute("ghidra_trace_create()");
|
||||
}
|
||||
|
||||
private void txPut(PythonAndHandler conn, String obj) {
|
||||
private void txPut(PythonAndConnection conn, String obj) {
|
||||
conn.execute("ghidra_trace_txstart('Tx')");
|
||||
conn.execute("ghidra_trace_put_" + obj + "()");
|
||||
conn.execute("ghidra_trace_txcommit()");
|
||||
}
|
||||
|
||||
private void txCreate(PythonAndHandler conn, String path) {
|
||||
private void txCreate(PythonAndConnection conn, String path) {
|
||||
conn.execute("ghidra_trace_txstart('Fake')");
|
||||
conn.execute("ghidra_trace_create_obj('%s')".formatted(path));
|
||||
conn.execute("ghidra_trace_txcommit()");
|
||||
}
|
||||
|
||||
private String getInst(PythonAndHandler conn) {
|
||||
private String getInst(PythonAndConnection conn) {
|
||||
return getInstAtOffset(conn, 0);
|
||||
}
|
||||
|
||||
private String getInstAtOffset(PythonAndHandler conn, int offset) {
|
||||
String inst = "util.get_inst(util.get_debugger().reg.get_pc()+"+offset+")";
|
||||
private String getInstAtOffset(PythonAndConnection conn, int offset) {
|
||||
String inst = "util.get_inst(util.get_debugger().reg.get_pc()+" + offset + ")";
|
||||
String ret = conn.executeCapture(inst);
|
||||
return ret.substring(1, ret.length()-1); // remove <>
|
||||
return ret.substring(1, ret.length() - 1); // remove <>
|
||||
}
|
||||
|
||||
private String getInstSizeAtOffset(PythonAndHandler conn, int offset) {
|
||||
String instSize = "util.get_inst_sz(util.get_debugger().reg.get_pc()+"+offset+")";
|
||||
private String getInstSizeAtOffset(PythonAndConnection conn, int offset) {
|
||||
String instSize = "util.get_inst_sz(util.get_debugger().reg.get_pc()+" + offset + ")";
|
||||
return conn.executeCapture(instSize);
|
||||
}
|
||||
|
||||
private long getAddressAtOffset(PythonAndHandler conn, int offset) {
|
||||
String inst = "util.get_inst(util.get_debugger().reg.get_pc()+"+offset+")";
|
||||
private long getAddressAtOffset(PythonAndConnection conn, int offset) {
|
||||
String inst = "util.get_inst(util.get_debugger().reg.get_pc()+" + offset + ")";
|
||||
String ret = conn.executeCapture(inst);
|
||||
String[] split = ret.split("\\s+"); // get target
|
||||
return Long.decode(split[1]);
|
||||
|
||||
@@ -33,11 +33,12 @@ import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.junit.Before;
|
||||
|
||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.*;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiPlugin;
|
||||
import ghidra.app.plugin.core.debug.utils.ManagedDomainObject;
|
||||
import ghidra.app.services.TraceRmiService;
|
||||
import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState;
|
||||
import ghidra.dbg.testutil.DummyProc;
|
||||
import ghidra.debug.api.tracermi.*;
|
||||
import ghidra.framework.*;
|
||||
import ghidra.framework.main.ApplicationLevelOnlyPlugin;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
@@ -228,10 +229,10 @@ public abstract class AbstractGdbTraceRmiTest extends AbstractGhidraHeadedDebugg
|
||||
return result.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).handle();
|
||||
}
|
||||
|
||||
protected record GdbAndHandler(ExecInGdb exec, TraceRmiHandler handler)
|
||||
protected record GdbAndConnection(ExecInGdb exec, TraceRmiConnection connection)
|
||||
implements AutoCloseable {
|
||||
protected RemoteMethod getMethod(String name) {
|
||||
return Objects.requireNonNull(handler.getMethods().get(name));
|
||||
return Objects.requireNonNull(connection.getMethods().get(name));
|
||||
}
|
||||
|
||||
public void execute(String cmd) {
|
||||
@@ -282,7 +283,7 @@ public abstract class AbstractGdbTraceRmiTest extends AbstractGhidraHeadedDebugg
|
||||
}
|
||||
GdbResult r = exec.future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
r.handle();
|
||||
waitForPass(() -> assertTrue(handler.isClosed()));
|
||||
waitForPass(() -> assertTrue(connection.isClosed()));
|
||||
}
|
||||
finally {
|
||||
exec.gdb.destroyForcibly();
|
||||
@@ -290,14 +291,14 @@ public abstract class AbstractGdbTraceRmiTest extends AbstractGhidraHeadedDebugg
|
||||
}
|
||||
}
|
||||
|
||||
protected GdbAndHandler startAndConnectGdb(Function<String, String> scriptSupplier)
|
||||
protected GdbAndConnection startAndConnectGdb(Function<String, String> scriptSupplier)
|
||||
throws Exception {
|
||||
TraceRmiAcceptor acceptor = traceRmi.acceptOne(null);
|
||||
ExecInGdb exec = execInGdb(scriptSupplier.apply(sockToStringForGdb(acceptor.getAddress())));
|
||||
acceptor.setTimeout(CONNECT_TIMEOUT_MS);
|
||||
try {
|
||||
TraceRmiHandler handler = acceptor.accept();
|
||||
return new GdbAndHandler(exec, handler);
|
||||
TraceRmiConnection connection = acceptor.accept();
|
||||
return new GdbAndConnection(exec, connection);
|
||||
}
|
||||
catch (SocketTimeoutException e) {
|
||||
exec.gdb.destroyForcibly();
|
||||
@@ -306,7 +307,7 @@ public abstract class AbstractGdbTraceRmiTest extends AbstractGhidraHeadedDebugg
|
||||
}
|
||||
}
|
||||
|
||||
protected GdbAndHandler startAndConnectGdb() throws Exception {
|
||||
protected GdbAndConnection startAndConnectGdb() throws Exception {
|
||||
return startAndConnectGdb(addr -> """
|
||||
%s
|
||||
ghidra trace connect %s
|
||||
@@ -316,10 +317,10 @@ public abstract class AbstractGdbTraceRmiTest extends AbstractGhidraHeadedDebugg
|
||||
@SuppressWarnings("resource")
|
||||
protected String runThrowError(Function<String, String> scriptSupplier)
|
||||
throws Exception {
|
||||
GdbAndHandler conn = startAndConnectGdb(scriptSupplier);
|
||||
GdbAndConnection conn = startAndConnectGdb(scriptSupplier);
|
||||
GdbResult r = conn.exec.future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
String stdout = r.handle();
|
||||
waitForPass(() -> assertTrue(conn.handler.isClosed()));
|
||||
waitForPass(() -> assertTrue(conn.connection.isClosed()));
|
||||
return stdout;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,11 @@ import org.junit.experimental.categories.Category;
|
||||
import db.Transaction;
|
||||
import generic.Unique;
|
||||
import generic.test.category.NightlyCategory;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiAcceptor;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiHandler;
|
||||
import ghidra.app.plugin.core.debug.utils.ManagedDomainObject;
|
||||
import ghidra.dbg.testutil.DummyProc;
|
||||
import ghidra.dbg.util.PathPredicates;
|
||||
import ghidra.debug.api.tracermi.TraceRmiAcceptor;
|
||||
import ghidra.debug.api.tracermi.TraceRmiConnection;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.Float10DataType;
|
||||
@@ -60,9 +60,9 @@ public class GdbCommandsTest extends AbstractGdbTraceRmiTest {
|
||||
TraceRmiAcceptor acceptor = traceRmi.acceptOne(null);
|
||||
Msg.info(this,
|
||||
"Use: ghidra trace connect " + sockToStringForGdb(acceptor.getAddress()));
|
||||
TraceRmiHandler handler = acceptor.accept();
|
||||
Msg.info(this, "Connected: " + sockToStringForGdb(handler.getRemoteAddress()));
|
||||
handler.waitClosed();
|
||||
TraceRmiConnection connection = acceptor.accept();
|
||||
Msg.info(this, "Connected: " + sockToStringForGdb(connection.getRemoteAddress()));
|
||||
connection.waitClosed();
|
||||
Msg.info(this, "Closed");
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
package agent.gdb.rmi;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@@ -43,7 +44,7 @@ public class GdbHooksTest extends AbstractGdbTraceRmiTest {
|
||||
private static final long RUN_TIMEOUT_MS = 20000;
|
||||
private static final long RETRY_MS = 500;
|
||||
|
||||
record GdbAndTrace(GdbAndHandler conn, ManagedDomainObject mdo) implements AutoCloseable {
|
||||
record GdbAndTrace(GdbAndConnection conn, ManagedDomainObject mdo) implements AutoCloseable {
|
||||
public void execute(String cmd) {
|
||||
conn.execute(cmd);
|
||||
}
|
||||
@@ -61,7 +62,7 @@ public class GdbHooksTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
protected GdbAndTrace startAndSyncGdb() throws Exception {
|
||||
GdbAndHandler conn = startAndConnectGdb();
|
||||
GdbAndConnection conn = startAndConnectGdb();
|
||||
try {
|
||||
// TODO: Why does using 'set arch' cause a hang at quit?
|
||||
conn.execute("""
|
||||
@@ -142,7 +143,7 @@ public class GdbHooksTest extends AbstractGdbTraceRmiTest {
|
||||
}
|
||||
|
||||
protected long lastSnap(GdbAndTrace conn) {
|
||||
return conn.conn.handler().getLastSnapshot(tb.trace);
|
||||
return conn.conn.connection().getLastSnapshot(tb.trace);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -28,12 +28,11 @@ import org.junit.experimental.categories.Category;
|
||||
import db.Transaction;
|
||||
import generic.Unique;
|
||||
import generic.test.category.NightlyCategory;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.ValueDecoder;
|
||||
import ghidra.app.plugin.core.debug.utils.ManagedDomainObject;
|
||||
import ghidra.dbg.testutil.DummyProc;
|
||||
import ghidra.dbg.util.PathPattern;
|
||||
import ghidra.dbg.util.PathPredicates;
|
||||
import ghidra.debug.api.tracermi.RemoteMethod;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.Float10DataType;
|
||||
import ghidra.program.model.lang.Register;
|
||||
@@ -55,17 +54,16 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testExecuteCapture() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
RemoteMethod execute = conn.getMethod("execute");
|
||||
assertEquals(false,
|
||||
execute.parameters().get("to_string").defaultValue().get(ValueDecoder.DEFAULT));
|
||||
assertEquals(false, execute.parameters().get("to_string").getDefaultValue());
|
||||
assertEquals("test", execute.invoke(Map.of("cmd", "echo test", "to_string", true)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecute() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
RemoteMethod execute = conn.getMethod("execute");
|
||||
execute.invoke(Map.of("cmd", """
|
||||
file bash
|
||||
@@ -80,7 +78,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshAvailable() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
ghidra trace start
|
||||
ghidra trace tx-open "Fake" 'ghidra trace create-obj Available'""");
|
||||
@@ -103,7 +101,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshBreakpoints() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -157,7 +155,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshInfBreakpoints() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -211,7 +209,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshInferiors() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
add-inferior
|
||||
ghidra trace start
|
||||
@@ -235,7 +233,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshEnvironment() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
String path = "Inferiors[1].Environment";
|
||||
conn.execute("""
|
||||
file bash
|
||||
@@ -260,7 +258,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshThreads() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
String path = "Inferiors[1].Threads";
|
||||
conn.execute("""
|
||||
file bash
|
||||
@@ -282,7 +280,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshStack() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
String path = "Inferiors[1].Threads[1].Stack";
|
||||
conn.execute("""
|
||||
file bash
|
||||
@@ -316,7 +314,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
String count = IntStream.iterate(0, i -> i < 32, i -> i + 1)
|
||||
.mapToObj(Integer::toString)
|
||||
.collect(Collectors.joining(",", "{", "}"));
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
String path = "Inferiors[1].Threads[1].Stack[0].Registers";
|
||||
conn.execute("""
|
||||
file bash
|
||||
@@ -361,7 +359,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshMappings() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
String path = "Inferiors[1].Memory";
|
||||
conn.execute("""
|
||||
file bash
|
||||
@@ -385,7 +383,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshModules() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
String path = "Inferiors[1].Modules";
|
||||
conn.execute("""
|
||||
file bash
|
||||
@@ -410,7 +408,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testActivateInferior() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
add-inferior
|
||||
ghidra trace start
|
||||
@@ -437,7 +435,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testActivateThread() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
add-inferior
|
||||
ghidra trace start
|
||||
@@ -474,7 +472,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testActivateFrame() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -508,7 +506,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testDeleteInferior() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
add-inferior
|
||||
ghidra trace start
|
||||
@@ -531,7 +529,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
public void testAttachObj() throws Exception {
|
||||
String sleep = DummyProc.which("expTraceableSleep");
|
||||
try (DummyProc proc = DummyProc.run(sleep)) {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
ghidra trace start
|
||||
ghidra trace tx-open Init 'ghidra trace put-available'
|
||||
@@ -556,7 +554,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
public void testAttachPid() throws Exception {
|
||||
String sleep = DummyProc.which("expTraceableSleep");
|
||||
try (DummyProc proc = DummyProc.run(sleep)) {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
ghidra trace start
|
||||
ghidra trace tx-open Init 'ghidra trace put-inferiors'""");
|
||||
@@ -578,7 +576,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
public void testDetach() throws Exception {
|
||||
String sleep = DummyProc.which("expTraceableSleep");
|
||||
try (DummyProc proc = DummyProc.run(sleep)) {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
ghidra trace start
|
||||
%s
|
||||
@@ -602,7 +600,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testLaunchMain() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
ghidra trace start
|
||||
%s
|
||||
@@ -626,7 +624,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testLaunchLoader() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
ghidra trace start
|
||||
%s
|
||||
@@ -650,7 +648,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testLaunchRun() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
ghidra trace start
|
||||
%s
|
||||
@@ -679,7 +677,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testKill() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -703,7 +701,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testResumeInterrupt5() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
RemoteMethod resume = conn.getMethod("resume");
|
||||
RemoteMethod interrupt = conn.getMethod("interrupt");
|
||||
conn.execute("""
|
||||
@@ -752,7 +750,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testStepInto() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -783,7 +781,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testStepOver() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -814,7 +812,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testStepOut() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -842,7 +840,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testStepAdvance() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -870,7 +868,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testStepReturn() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -897,7 +895,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakSwExecuteAddress() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -921,7 +919,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakSwExecuteExpression() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -943,7 +941,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakHwExecuteAddress() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -968,7 +966,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakHwExecuteExpression() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -991,7 +989,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakReadRange() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -1018,7 +1016,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakReadExpression() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -1041,7 +1039,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakWriteRange() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -1068,7 +1066,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakWriteExpression() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -1091,7 +1089,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakAccessRange() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -1118,7 +1116,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakAccessExpression() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -1141,7 +1139,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakEvent() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -1164,7 +1162,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testToggleBreakpoint() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -1190,7 +1188,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testToggleBreakpointLocation() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
@@ -1232,7 +1230,7 @@ public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testDeleteBreakpoint() throws Exception {
|
||||
try (GdbAndHandler conn = startAndConnectGdb()) {
|
||||
try (GdbAndConnection conn = startAndConnectGdb()) {
|
||||
conn.execute("""
|
||||
file bash
|
||||
ghidra trace start
|
||||
|
||||
@@ -32,10 +32,11 @@ import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.junit.Before;
|
||||
|
||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.*;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiPlugin;
|
||||
import ghidra.app.plugin.core.debug.utils.ManagedDomainObject;
|
||||
import ghidra.app.services.TraceRmiService;
|
||||
import ghidra.dbg.testutil.DummyProc;
|
||||
import ghidra.debug.api.tracermi.*;
|
||||
import ghidra.framework.*;
|
||||
import ghidra.framework.main.ApplicationLevelOnlyPlugin;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
@@ -228,10 +229,10 @@ public abstract class AbstractLldbTraceRmiTest extends AbstractGhidraHeadedDebug
|
||||
return result.get(TIMEOUT_SECONDS, TimeUnit.SECONDS).handle();
|
||||
}
|
||||
|
||||
protected record LldbAndHandler(ExecInLldb exec, TraceRmiHandler handler)
|
||||
protected record LldbAndConnection(ExecInLldb exec, TraceRmiConnection connection)
|
||||
implements AutoCloseable {
|
||||
protected RemoteMethod getMethod(String name) {
|
||||
return Objects.requireNonNull(handler.getMethods().get(name));
|
||||
return Objects.requireNonNull(connection.getMethods().get(name));
|
||||
}
|
||||
|
||||
public void execute(String cmd) {
|
||||
@@ -256,7 +257,7 @@ public abstract class AbstractLldbTraceRmiTest extends AbstractGhidraHeadedDebug
|
||||
try {
|
||||
LldbResult r = exec.future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
r.handle();
|
||||
waitForPass(() -> assertTrue(handler.isClosed()));
|
||||
waitForPass(() -> assertTrue(connection.isClosed()));
|
||||
}
|
||||
finally {
|
||||
exec.lldb.destroyForcibly();
|
||||
@@ -264,15 +265,15 @@ public abstract class AbstractLldbTraceRmiTest extends AbstractGhidraHeadedDebug
|
||||
}
|
||||
}
|
||||
|
||||
protected LldbAndHandler startAndConnectLldb(Function<String, String> scriptSupplier)
|
||||
protected LldbAndConnection startAndConnectLldb(Function<String, String> scriptSupplier)
|
||||
throws Exception {
|
||||
TraceRmiAcceptor acceptor = traceRmi.acceptOne(null);
|
||||
ExecInLldb exec =
|
||||
execInLldb(scriptSupplier.apply(sockToStringForLldb(acceptor.getAddress())));
|
||||
acceptor.setTimeout(CONNECT_TIMEOUT_MS);
|
||||
try {
|
||||
TraceRmiHandler handler = acceptor.accept();
|
||||
return new LldbAndHandler(exec, handler);
|
||||
TraceRmiConnection connection = acceptor.accept();
|
||||
return new LldbAndConnection(exec, connection);
|
||||
}
|
||||
catch (SocketTimeoutException e) {
|
||||
exec.lldb.destroyForcibly();
|
||||
@@ -281,7 +282,7 @@ public abstract class AbstractLldbTraceRmiTest extends AbstractGhidraHeadedDebug
|
||||
}
|
||||
}
|
||||
|
||||
protected LldbAndHandler startAndConnectLldb() throws Exception {
|
||||
protected LldbAndConnection startAndConnectLldb() throws Exception {
|
||||
return startAndConnectLldb(addr -> """
|
||||
%s
|
||||
ghidra_trace_connect %s
|
||||
@@ -291,10 +292,10 @@ public abstract class AbstractLldbTraceRmiTest extends AbstractGhidraHeadedDebug
|
||||
@SuppressWarnings("resource")
|
||||
protected String runThrowError(Function<String, String> scriptSupplier)
|
||||
throws Exception {
|
||||
LldbAndHandler conn = startAndConnectLldb(scriptSupplier);
|
||||
LldbAndConnection conn = startAndConnectLldb(scriptSupplier);
|
||||
LldbResult r = conn.exec.future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
String stdout = r.handle();
|
||||
waitForPass(() -> assertTrue(conn.handler.isClosed()));
|
||||
waitForPass(() -> assertTrue(conn.connection.isClosed()));
|
||||
return stdout;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,10 @@ import org.junit.experimental.categories.Category;
|
||||
|
||||
import generic.Unique;
|
||||
import generic.test.category.NightlyCategory;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiAcceptor;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.TraceRmiHandler;
|
||||
import ghidra.app.plugin.core.debug.utils.ManagedDomainObject;
|
||||
import ghidra.dbg.util.PathPredicates;
|
||||
import ghidra.debug.api.tracermi.TraceRmiAcceptor;
|
||||
import ghidra.debug.api.tracermi.TraceRmiConnection;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
@@ -56,9 +56,9 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
|
||||
TraceRmiAcceptor acceptor = traceRmi.acceptOne(null);
|
||||
Msg.info(this,
|
||||
"Use: ghidra_trace_connect " + sockToStringForLldb(acceptor.getAddress()));
|
||||
TraceRmiHandler handler = acceptor.accept();
|
||||
Msg.info(this, "Connected: " + sockToStringForLldb(handler.getRemoteAddress()));
|
||||
handler.waitClosed();
|
||||
TraceRmiConnection connection = acceptor.accept();
|
||||
Msg.info(this, "Connected: " + sockToStringForLldb(connection.getRemoteAddress()));
|
||||
connection.waitClosed();
|
||||
Msg.info(this, "Closed");
|
||||
}
|
||||
|
||||
@@ -1220,7 +1220,7 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testPutFrames() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("file bash");
|
||||
conn.execute("ghidra_trace_start");
|
||||
conn.execute("ghidra_trace_txstart 'Tx'");
|
||||
@@ -1256,7 +1256,7 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
|
||||
%s
|
||||
ghidra_trace_connect %s
|
||||
""".formatted(PREAMBLE, addr);
|
||||
try (LldbAndHandler conn = startAndConnectLldb(scriptSupplier)) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb(scriptSupplier)) {
|
||||
conn.execute("script print('FINISHED')");
|
||||
conn.execute("quit");
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
|
||||
private static final long RUN_TIMEOUT_MS = 20000;
|
||||
private static final long RETRY_MS = 500;
|
||||
|
||||
record LldbAndTrace(LldbAndHandler conn, ManagedDomainObject mdo) implements AutoCloseable {
|
||||
record LldbAndTrace(LldbAndConnection conn, ManagedDomainObject mdo) implements AutoCloseable {
|
||||
public void execute(String cmd) {
|
||||
conn.execute(cmd);
|
||||
}
|
||||
@@ -62,7 +62,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
protected LldbAndTrace startAndSyncLldb() throws Exception {
|
||||
LldbAndHandler conn = startAndConnectLldb();
|
||||
LldbAndConnection conn = startAndConnectLldb();
|
||||
try {
|
||||
// TODO: Why does using 'set arch' cause a hang at quit?
|
||||
conn.execute(
|
||||
@@ -79,7 +79,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
|
||||
}
|
||||
|
||||
protected long lastSnap(LldbAndTrace conn) {
|
||||
return conn.conn.handler().getLastSnapshot(tb.trace);
|
||||
return conn.conn.connection().getLastSnapshot(tb.trace);
|
||||
}
|
||||
|
||||
// TODO: This passes if you single-step through it but fails on some transactional stuff if run
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
package agent.lldb.rmi;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
@@ -25,12 +26,11 @@ import org.junit.experimental.categories.Category;
|
||||
|
||||
import generic.Unique;
|
||||
import generic.test.category.NightlyCategory;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.RemoteMethod;
|
||||
import ghidra.app.plugin.core.debug.service.rmi.trace.ValueDecoder;
|
||||
import ghidra.app.plugin.core.debug.utils.ManagedDomainObject;
|
||||
import ghidra.dbg.testutil.DummyProc;
|
||||
import ghidra.dbg.util.PathPattern;
|
||||
import ghidra.dbg.util.PathPredicates;
|
||||
import ghidra.debug.api.tracermi.RemoteMethod;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.trace.database.ToyDBTraceBuilder;
|
||||
@@ -48,10 +48,9 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testExecuteCapture() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
RemoteMethod execute = conn.getMethod("execute");
|
||||
assertEquals(false,
|
||||
execute.parameters().get("to_string").defaultValue().get(ValueDecoder.DEFAULT));
|
||||
assertEquals(false, execute.parameters().get("to_string").getDefaultValue());
|
||||
assertEquals("test\n",
|
||||
execute.invoke(Map.of("cmd", "script print('test')", "to_string", true)));
|
||||
}
|
||||
@@ -59,7 +58,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testExecute() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
conn.execute("kill");
|
||||
}
|
||||
@@ -70,7 +69,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshAvailable() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("ghidra_trace_start");
|
||||
txCreate(conn, "Available");
|
||||
|
||||
@@ -93,7 +92,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshBreakpoints() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -131,7 +130,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshProcBreakpoints() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
txPut(conn, "breakpoints");
|
||||
@@ -169,7 +168,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshProcWatchpoints() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "all");
|
||||
|
||||
@@ -216,7 +215,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshProcesses() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("ghidra_trace_start");
|
||||
txCreate(conn, "Processes");
|
||||
txCreate(conn, "Processes[1]");
|
||||
@@ -240,7 +239,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshEnvironment() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
String path = "Processes[].Environment";
|
||||
start(conn, "bash");
|
||||
txPut(conn, "all");
|
||||
@@ -263,7 +262,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshThreads() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
String path = "Processes[].Threads";
|
||||
start(conn, "bash");
|
||||
txCreate(conn, path);
|
||||
@@ -283,7 +282,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshStack() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
String path = "Processes[].Threads[].Stack";
|
||||
conn.execute("file bash");
|
||||
conn.execute("ghidra_trace_start");
|
||||
@@ -312,7 +311,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshRegisters() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
String path = "Processes[].Threads[].Stack[].Registers";
|
||||
start(conn, "bash");
|
||||
conn.execute("ghidra_trace_txstart 'Tx'");
|
||||
@@ -341,7 +340,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshMappings() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
String path = "Processes[].Memory";
|
||||
start(conn, "bash");
|
||||
txCreate(conn, path);
|
||||
@@ -363,7 +362,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshModules() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
String path = "Processes[].Modules";
|
||||
start(conn, "bash");
|
||||
txCreate(conn, path);
|
||||
@@ -386,7 +385,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testActivateThread() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
// TODO: need to find this file (same issue in LldbHookTests
|
||||
String dproc = DummyProc.which("expCloneExit");
|
||||
conn.execute("file " + dproc);
|
||||
@@ -421,7 +420,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testActivateFrame() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("file bash");
|
||||
conn.execute("ghidra_trace_start");
|
||||
txPut(conn, "processes");
|
||||
@@ -453,7 +452,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testRemoveProcess() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -474,7 +473,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
public void testAttachObj() throws Exception {
|
||||
String sleep = DummyProc.which("expTraceableSleep");
|
||||
try (DummyProc dproc = DummyProc.run(sleep)) {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("ghidra_trace_start");
|
||||
txPut(conn, "available");
|
||||
txPut(conn, "processes");
|
||||
@@ -499,7 +498,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
public void testAttachPid() throws Exception {
|
||||
String sleep = DummyProc.which("expTraceableSleep");
|
||||
try (DummyProc dproc = DummyProc.run(sleep)) {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("ghidra_trace_start");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -519,7 +518,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testDetach() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
//conn.execute("process attach -p %d".formatted(dproc.pid));
|
||||
@@ -540,7 +539,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testLaunchEntry() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("ghidra_trace_start");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -562,7 +561,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test //Not clear how to send interrupt
|
||||
public void testLaunch() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("ghidra_trace_start");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -593,7 +592,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testKill() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -613,7 +612,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testStepInto() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -647,7 +646,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testStepOver() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("file bash");
|
||||
conn.execute("ghidra_trace_start");
|
||||
txPut(conn, "processes");
|
||||
@@ -681,7 +680,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
//@Test Not obvious "thread until -a" works (and definitely requires debug info")
|
||||
public void testAdvance() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
|
||||
RemoteMethod step_ext = conn.getMethod("step_ext");
|
||||
@@ -706,7 +705,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testFinish() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("file bash");
|
||||
conn.execute("ghidra_trace_start");
|
||||
txPut(conn, "processes");
|
||||
@@ -734,7 +733,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testReturn() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("file bash");
|
||||
conn.execute("ghidra_trace_start");
|
||||
txPut(conn, "processes");
|
||||
@@ -762,7 +761,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakAddress() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -783,7 +782,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakExpression() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -803,7 +802,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
//@Test stderr getting populated with warning about exhausted hardware breakpoints
|
||||
// Are hardware breakpoints available on our VMs?
|
||||
public void testBreakHardwareAddress() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -824,7 +823,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
//@Test There appear to be issues with hardware register availability in our virtual environments
|
||||
public void testBreakHardwareExpression() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -845,7 +844,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakReadRange() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -869,7 +868,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakReadExpression() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -889,7 +888,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakWriteRange() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -913,7 +912,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakWriteExpression() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -933,7 +932,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakAccessRange() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -957,7 +956,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testBreakAccessExpression() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -978,7 +977,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
// NB: not really equivalent to gdb's "catch" but...
|
||||
@Test
|
||||
public void testBreakException() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -997,7 +996,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testToggleBreakpoint() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("file bash");
|
||||
conn.execute("ghidra_trace_start");
|
||||
txPut(conn, "processes");
|
||||
@@ -1021,7 +1020,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testToggleBreakpointLocation() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("file bash");
|
||||
conn.execute("ghidra_trace_start");
|
||||
txPut(conn, "processes");
|
||||
@@ -1047,7 +1046,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testDeleteBreakpoint() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
conn.execute("file bash");
|
||||
conn.execute("ghidra_trace_start");
|
||||
txPut(conn, "processes");
|
||||
@@ -1071,7 +1070,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
|
||||
@Test
|
||||
public void testDeleteWatchpoint() throws Exception {
|
||||
try (LldbAndHandler conn = startAndConnectLldb()) {
|
||||
try (LldbAndConnection conn = startAndConnectLldb()) {
|
||||
start(conn, "bash");
|
||||
txPut(conn, "processes");
|
||||
|
||||
@@ -1097,31 +1096,31 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
|
||||
}
|
||||
}
|
||||
|
||||
private void start(LldbAndHandler conn, String obj) {
|
||||
private void start(LldbAndConnection conn, String obj) {
|
||||
conn.execute("file " + obj);
|
||||
conn.execute("ghidra_trace_start");
|
||||
conn.execute("process launch --stop-at-entry");
|
||||
}
|
||||
|
||||
private void txPut(LldbAndHandler conn, String obj) {
|
||||
private void txPut(LldbAndConnection conn, String obj) {
|
||||
conn.execute("ghidra_trace_txstart 'Tx'");
|
||||
conn.execute("ghidra_trace_put_" + obj);
|
||||
conn.execute("ghidra_trace_txcommit");
|
||||
}
|
||||
|
||||
private void txCreate(LldbAndHandler conn, String path) {
|
||||
private void txCreate(LldbAndConnection conn, String path) {
|
||||
conn.execute("ghidra_trace_txstart 'Fake'");
|
||||
conn.execute("ghidra_trace_create_obj %s".formatted(path));
|
||||
conn.execute("ghidra_trace_txcommit");
|
||||
}
|
||||
|
||||
private void breakAt(LldbAndHandler conn, String fn) {
|
||||
private void breakAt(LldbAndConnection conn, String fn) {
|
||||
conn.execute("ghidra_trace_sync_enable");
|
||||
conn.execute("breakpoint set -n " + fn);
|
||||
conn.execute("run");
|
||||
}
|
||||
|
||||
private int getDepth(LldbAndHandler conn) {
|
||||
private int getDepth(LldbAndConnection conn) {
|
||||
String[] split = conn.executeCapture("bt").split("\n");
|
||||
int initDepth = 0;
|
||||
for (String str : split) {
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.plugin.core.debug.gui.tracermi.launcher;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import db.Transaction;
|
||||
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
|
||||
import ghidra.app.services.TraceRmiLauncherService;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer;
|
||||
import ghidra.debug.api.tracermi.TraceRmiLaunchOffer.*;
|
||||
import ghidra.util.task.ConsoleTaskMonitor;
|
||||
|
||||
public class TraceRmiLauncherServicePluginTest extends AbstractGhidraHeadedDebuggerGUITest {
|
||||
TraceRmiLauncherService launcherService;
|
||||
|
||||
@Before
|
||||
public void setupRmiLauncherTest() throws Exception {
|
||||
launcherService = addPlugin(tool, TraceRmiLauncherServicePlugin.class);
|
||||
}
|
||||
|
||||
protected TraceRmiLaunchOffer findByTitle(Collection<TraceRmiLaunchOffer> offers,
|
||||
String title) {
|
||||
return offers.stream().filter(o -> o.getTitle().equals(title)).findFirst().get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOpinions() throws Exception {
|
||||
assertFalse(launcherService.getOpinions().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOffers() throws Exception {
|
||||
createProgram(getSLEIGH_X86_64_LANGUAGE());
|
||||
|
||||
assertFalse(launcherService.getOffers(program).isEmpty());
|
||||
}
|
||||
|
||||
protected LaunchConfigurator fileOnly(String file) {
|
||||
return new LaunchConfigurator() {
|
||||
@Override
|
||||
public Map<String, ?> configureLauncher(TraceRmiLaunchOffer offer,
|
||||
Map<String, ?> arguments, RelPrompt relPrompt) {
|
||||
Map<String, Object> args = new HashMap<>(arguments);
|
||||
args.put("arg:1", file);
|
||||
return args;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchLocalGdb() throws Exception {
|
||||
createProgram(getSLEIGH_X86_64_LANGUAGE());
|
||||
try (Transaction tx = program.openTransaction("Rename")) {
|
||||
program.setName("bash");
|
||||
}
|
||||
programManager.openProgram(program);
|
||||
|
||||
TraceRmiLaunchOffer gdbOffer = findByTitle(launcherService.getOffers(program), "gdb");
|
||||
|
||||
try (LaunchResult result =
|
||||
gdbOffer.launchProgram(new ConsoleTaskMonitor(), fileOnly("/usr/bin/bash"))) {
|
||||
if (result.exception() != null) {
|
||||
throw new AssertionError(result.exception());
|
||||
}
|
||||
|
||||
assertEquals("bash", result.trace().getName());
|
||||
assertEquals(getSLEIGH_X86_64_LANGUAGE(), result.trace().getBaseLanguage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,9 @@ package ghidra.util.bean;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@@ -55,7 +58,8 @@ public class PathnameTablePanelTest extends AbstractDockingTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
panel = new PathnameTablePanel(tablePaths, true, false, () -> reset());
|
||||
// enable edits, add to bottom, ordered
|
||||
panel = new PathnameTablePanel(tablePaths, () -> reset(), true, false, true);
|
||||
table = panel.getTable();
|
||||
frame = new JFrame("Test");
|
||||
frame.getContentPane().add(panel);
|
||||
@@ -245,6 +249,32 @@ public class PathnameTablePanelTest extends AbstractDockingTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnordered() throws Exception {
|
||||
panel.setOrdered(false);
|
||||
File temp = createTempFileForTest();
|
||||
Preferences.setProperty(Preferences.LAST_PATH_DIRECTORY, temp.getParent());
|
||||
panel.setFileChooserProperties("Select Source Files", Preferences.LAST_PATH_DIRECTORY,
|
||||
GhidraFileChooserMode.FILES_AND_DIRECTORIES, true,
|
||||
new ExtensionFileFilter(new String[] { "h" }, "C Header Files"));
|
||||
|
||||
assertNotNull(addButton);
|
||||
pressButton(addButton, false);
|
||||
|
||||
waitForSwing();
|
||||
selectFromFileChooser();
|
||||
|
||||
assertEquals(6, table.getRowCount());
|
||||
|
||||
List<String> expected = new ArrayList<>(List.of(tablePaths));
|
||||
expected.add(new File(temp.getParentFile(), "fred.h").getAbsolutePath());
|
||||
expected.sort(String::compareTo);
|
||||
List<String> actual = IntStream.range(0, 6)
|
||||
.mapToObj(i -> (String) table.getModel().getValueAt(i, 0))
|
||||
.toList();
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReset() throws Exception {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user