GP-3818: Create TraceRMI launcher framework. Launch script for gdb.

This commit is contained in:
Dan
2023-09-20 15:17:37 -04:00
parent 4561e8335d
commit eea90f49c9
379 changed files with 5180 additions and 1487 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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]);

View File

@@ -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]);

View File

@@ -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;
}

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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");
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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());
}
}
}

View File

@@ -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 {