Merge remote-tracking branch 'origin/GP-2677_Dan_disableTests'

This commit is contained in:
Ryan Kurtz 2023-08-04 14:02:14 -04:00
commit 7a476ecc23
8 changed files with 185 additions and 199 deletions

View file

@ -78,7 +78,9 @@ ext.addExports([
'java.desktop/sun.java2d=ALL-UNNAMED'
])
integrationTest {
// The CI system runs these tests as root and pip complains about using venv
// Disable them for now
/* integrationTest {
dependsOn { project(':Debugger-agent-gdb').installPyPackage }
dependsOn { project(':Debugger-agent-lldb').installPyPackage }
}
} */

View file

@ -25,6 +25,7 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.Ignore;
import org.junit.Test;
import db.Transaction;
@ -50,6 +51,7 @@ import ghidra.trace.model.target.*;
import ghidra.trace.model.time.TraceSnapshot;
import ghidra.util.Msg;
@Ignore("Cannot install python packages in CI")
public class GdbCommandsTest extends AbstractGdbTraceRmiTest {
//@Test

View file

@ -37,6 +37,7 @@ import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.time.TraceSnapshot;
@Ignore("Cannot install python packages in CI")
public class GdbHooksTest extends AbstractGdbTraceRmiTest {
private static final long RUN_TIMEOUT_MS = 20000;
private static final long RETRY_MS = 500;

View file

@ -22,6 +22,7 @@ import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.Ignore;
import org.junit.Test;
import db.Transaction;
@ -48,6 +49,7 @@ import ghidra.trace.model.modules.TraceModule;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObjectValue;
@Ignore("Cannot install python packages in CI")
public class GdbMethodsTest extends AbstractGdbTraceRmiTest {
@Test

View file

@ -15,7 +15,7 @@
*/
package agent.lldb.rmi;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.*;
import java.io.*;
@ -30,7 +30,6 @@ import java.util.stream.Collectors;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.junit.Before;
import org.junit.BeforeClass;
import ghidra.app.plugin.core.debug.gui.AbstractGhidraHeadedDebuggerGUITest;
import ghidra.app.plugin.core.debug.service.rmi.trace.*;

View file

@ -15,32 +15,18 @@
*/
package agent.lldb.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.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;
import java.util.stream.IntStream;
import org.junit.Ignore;
import org.junit.Test;
import generic.Unique;
@ -49,28 +35,19 @@ 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.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.time.TraceSnapshot;
import ghidra.util.Msg;
@Ignore("Cannot install python packages in CI")
public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
//@Test
@ -153,15 +130,17 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
@Test
public void testStartTraceCustomize() throws Exception {
runThrowError(addr -> """
script import ghidralldb
ghidra_trace_connect %s
file bash
script ghidralldb.util.set_convenience_variable('ghidra-language','Toy:BE:64:default')
script ghidralldb.util.set_convenience_varaible('ghidra-compiler','default')
ghidra_trace_start myToy
quit
""".formatted(addr));
runThrowError(
addr -> """
script import ghidralldb
ghidra_trace_connect %s
file bash
script ghidralldb.util.set_convenience_variable('ghidra-language','Toy:BE:64:default')
script ghidralldb.util.set_convenience_varaible('ghidra-compiler','default')
ghidra_trace_start myToy
quit
"""
.formatted(addr));
DomainFile dfMyToy = env.getProject().getProjectData().getFile("/New Traces/myToy");
assertNotNull(dfMyToy);
try (ManagedDomainObject mdo = new ManagedDomainObject(dfMyToy, false, false, monitor)) {
@ -239,22 +218,23 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
@Test
public void testLcsp() throws Exception {
// TODO: This test assumes x86-64 on test system
String out = runThrowError("""
script import ghidralldb
_mark_ ---Import---
ghidra_trace_info_lcsp
_mark_ ---
file bash
_mark_ ---File---
ghidra_trace_info_lcsp
script ghidralldb.util.set_convenience_variable('ghidra-language','Toy:BE:64:default')
_mark_ ---Language---
ghidra_trace_info_lcsp
script ghidralldb.util.set_convenience_variable('ghidra-compiler','posStack')
_mark_ ---Compiler---
ghidra_trace_info_lcsp
quit
""");
String out = runThrowError(
"""
script import ghidralldb
_mark_ ---Import---
ghidra_trace_info_lcsp
_mark_ ---
file bash
_mark_ ---File---
ghidra_trace_info_lcsp
script ghidralldb.util.set_convenience_variable('ghidra-language','Toy:BE:64:default')
_mark_ ---Language---
ghidra_trace_info_lcsp
script ghidralldb.util.set_convenience_variable('ghidra-compiler','posStack')
_mark_ ---Compiler---
ghidra_trace_info_lcsp
quit
""");
// assertEquals("""
// Selected Ghidra language: DATA:LE:64:default
@ -420,7 +400,7 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
String eval = extractOutSection(out, "---Start---");
String addrstr = eval.split("=")[1].trim();
if (addrstr.contains(" ")) {
addrstr= addrstr.substring(0, addrstr.indexOf(" "));
addrstr = addrstr.substring(0, addrstr.indexOf(" "));
}
Address addr = tb.addr(Long.decode(addrstr));
@ -496,10 +476,10 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
AddressSpace t1f0 = tb.trace.getBaseAddressFactory()
.getAddressSpace(tobj.getCanonicalPath().toString());
TraceMemorySpace regs = tb.trace.getMemoryManager().getMemorySpace(t1f0, false);
RegisterValue rax = regs.getValue(snap, tb.reg("rax"));
assertEquals("deadbeef", rax.getUnsignedValue().toString(16));
// RegisterValue ymm0 = regs.getValue(snap, tb.reg("ymm0"));
// // LLDB treats registers in arch's endian
// assertEquals("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100",
@ -552,7 +532,7 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
RegisterValue rax = regs.getValue(snap, tb.reg("rax"));
assertEquals("0", rax.getUnsignedValue().toString(16));
// RegisterValue ymm0 = regs.getValue(snap, tb.reg("ymm0"));
// assertEquals("0", ymm0.getUnsignedValue().toString(16));
@ -672,7 +652,7 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
}
// NB: Fails in gdb tests as well
//@Test
//@Test
public void testSetValueNull() throws Exception {
assertNull(runTestSetValue("", "(void)null", ""));
}
@ -751,7 +731,7 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
runTestSetValue("expr char $x[]={'H', 0, 'W'}", "$x", "CHAR_ARR"));
}
@Test
@Test
public void testSetValueShortArrUsingString() throws Exception {
// Because explicit array type is chosen, we get null terminator
assertArrayEquals(new short[] { 'H', 0, 'W', 0 },
@ -903,23 +883,26 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
""".formatted(addr));
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/bash")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
assertEquals("""
Parent Key Span Value Type
Test.Objects[1] vbool [0,+inf) True BOOL
Test.Objects[1] vboolarr [0,+inf) [True, False] BOOL_ARR
Test.Objects[1] vbyte [0,+inf) 1 BYTE
Test.Objects[1] vbytearr [0,+inf) b'\\x01\\x02\\x03' BYTE_ARR
Test.Objects[1] vchar [0,+inf) 'A' CHAR
Test.Objects[1] vchararr [0,+inf) 'Hello\\x00' CHAR_ARR
Test.Objects[1] vint [0,+inf) 3 INT
Test.Objects[1] vintarr [0,+inf) [1, 2, 3] INT_ARR
Test.Objects[1] vlong [0,+inf) 4 LONG
Test.Objects[1] vlongarr [0,+inf) [1, 2, 3] LONG_ARR
Test.Objects[1] vobj [0,+inf) Test.Objects[1] OBJECT
Test.Objects[1] vshort [0,+inf) 2 SHORT
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("\n", ""),
assertEquals(
"""
Parent Key Span Value Type
Test.Objects[1] vbool [0,+inf) True BOOL
Test.Objects[1] vboolarr [0,+inf) [True, False] BOOL_ARR
Test.Objects[1] vbyte [0,+inf) 1 BYTE
Test.Objects[1] vbytearr [0,+inf) b'\\x01\\x02\\x03' BYTE_ARR
Test.Objects[1] vchar [0,+inf) 'A' CHAR
Test.Objects[1] vchararr [0,+inf) 'Hello\\x00' CHAR_ARR
Test.Objects[1] vint [0,+inf) 3 INT
Test.Objects[1] vintarr [0,+inf) [1, 2, 3] INT_ARR
Test.Objects[1] vlong [0,+inf) 4 LONG
Test.Objects[1] vlongarr [0,+inf) [1, 2, 3] LONG_ARR
Test.Objects[1] vobj [0,+inf) Test.Objects[1] OBJECT
Test.Objects[1] vshort [0,+inf) 2 SHORT
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("\n", ""),
extractOutSection(out, "---GetValues---").replaceAll(" ", "").replaceAll("\n", ""));
}
}
@ -947,10 +930,10 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/bash")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
assertEquals("""
Parent
Key
Span
Value
Parent
Key
Span
Value
Type
Test.Objects[1]
vaddr
@ -1122,8 +1105,8 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
.toList();
assertEquals(3, procWatchLocVals.size());
AddressRange rangeMain0 =
procWatchLocVals.get(0).getChild().getValue(0, "_range").castValue();
Address main0 = rangeMain0.getMinAddress();
procWatchLocVals.get(0).getChild().getValue(0, "_range").castValue();
Address main0 = rangeMain0.getMinAddress();
AddressRange rangeMain1 =
procWatchLocVals.get(1).getChild().getValue(0, "_range").castValue();
Address main1 = rangeMain1.getMinAddress();
@ -1131,15 +1114,15 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
procWatchLocVals.get(2).getChild().getValue(0, "_range").castValue();
Address main2 = rangeMain2.getMinAddress();
assertWatchLoc(procWatchLocVals.get(0), "[1]", main0, (int) rangeMain0.getLength(),
Set.of(TraceBreakpointKind.WRITE), "main");
assertWatchLoc(procWatchLocVals.get(1), "[2]", main1, (int) rangeMain1.getLength(),
Set.of(TraceBreakpointKind.READ), "main");
assertWatchLoc(procWatchLocVals.get(2), "[3]", main2, (int) rangeMain2.getLength(),
Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE), "main");
assertWatchLoc(procWatchLocVals.get(0), "[1]", main0, (int) rangeMain0.getLength(),
Set.of(TraceBreakpointKind.WRITE), "main");
assertWatchLoc(procWatchLocVals.get(1), "[2]", main1, (int) rangeMain1.getLength(),
Set.of(TraceBreakpointKind.READ), "main");
assertWatchLoc(procWatchLocVals.get(2), "[3]", main2, (int) rangeMain2.getLength(),
Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE), "main");
}
}
@Test
public void testPutEnvironment() throws Exception {
runThrowError(addr -> """
@ -1157,7 +1140,8 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/bash")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
// Assumes LLDB on Linux amd64
TraceObject env = Objects.requireNonNull(tb.objAny("Processes[].Environment", Lifespan.at(0)));
TraceObject env =
Objects.requireNonNull(tb.objAny("Processes[].Environment", Lifespan.at(0)));
assertEquals("lldb", env.getValue(0, "_debugger").getValue());
assertEquals("x86_64", env.getValue(0, "_arch").getValue());
assertEquals("linux", env.getValue(0, "_os").getValue());
@ -1239,15 +1223,15 @@ public class LldbCommandsTest extends AbstractLldbTraceRmiTest {
conn.execute("file bash");
conn.execute("ghidra_trace_start");
conn.execute("ghidra_trace_txstart 'Tx'");
conn.execute("ghidra_trace_put_processes");
conn.execute("ghidra_trace_put_processes");
conn.execute("ghidra_trace_txcommit");
conn.execute("ghidra_trace_install_hooks");
conn.execute("breakpoint set -n read");
conn.execute("run");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/bash")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
waitStopped();
conn.execute("ghidra_trace_txstart 'Tx'");
conn.execute("ghidra_trace_put_frames");

View file

@ -17,10 +17,7 @@ package agent.lldb.rmi;
import static org.hamcrest.Matchers.greaterThan;
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;
@ -41,6 +38,7 @@ import ghidra.trace.model.memory.TraceMemorySpace;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.time.TraceSnapshot;
@Ignore("Cannot install python packages in CI")
public class LldbHooksTest extends AbstractLldbTraceRmiTest {
private static final long RUN_TIMEOUT_MS = 20000;
private static final long RETRY_MS = 500;
@ -66,7 +64,8 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
LldbAndHandler conn = startAndConnectLldb();
try {
// TODO: Why does using 'set arch' cause a hang at quit?
conn.execute("ghidralldb.util.set_convenience_variable('ghidra-language', 'x86:LE:64:default')");
conn.execute(
"ghidralldb.util.set_convenience_variable('ghidra-language', 'x86:LE:64:default')");
conn.execute("ghidra_trace_start");
ManagedDomainObject mdo = waitDomainObject("/New Traces/lldb/noname");
tb = new ToyDBTraceBuilder((Trace) mdo.get());
@ -95,7 +94,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
assertNotNull(proc);
assertEquals("STOPPED", tb.objValue(proc, lastSnap(conn), "_state"));
}, RUN_TIMEOUT_MS, RETRY_MS);
txPut(conn, "threads");
waitForPass(() -> assertEquals(1,
tb.objValues(lastSnap(conn), "Processes[].Threads[]").size()),
@ -119,7 +118,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
start(conn, "%s".formatted(cloneExit));
conn.execute("break set -n work");
waitForPass(() -> {
TraceObject inf = tb.objAny("Processes[]");
assertNotNull(inf);
@ -137,7 +136,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
assertNotNull(inf);
assertEquals("STOPPED", tb.objValue(inf, lastSnap(conn), "_state"));
}, RUN_TIMEOUT_MS, RETRY_MS);
waitForPass(() -> assertEquals(2,
tb.objValues(lastSnap(conn), "Processes[].Threads[]").size()),
RUN_TIMEOUT_MS, RETRY_MS);
@ -148,7 +147,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
waitForPass(() -> {
String ti0 = conn.executeCapture("thread info");
assertTrue(ti0.contains("#1"));
String threadIndex = threadIndex(traceManager.getCurrentObject());
String threadIndex = threadIndex(traceManager.getCurrentObject());
assertTrue(ti0.contains(threadIndex));
}, RUN_TIMEOUT_MS, RETRY_MS);
@ -157,7 +156,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
waitForPass(() -> {
String ti0 = conn.executeCapture("thread info");
assertTrue(ti0.contains("#2"));
String threadIndex = threadIndex(traceManager.getCurrentObject());
String threadIndex = threadIndex(traceManager.getCurrentObject());
assertTrue(ti0.contains(threadIndex));
}, RUN_TIMEOUT_MS, RETRY_MS);
@ -166,7 +165,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
waitForPass(() -> {
String ti0 = conn.executeCapture("thread info");
assertTrue(ti0.contains("#1"));
String threadIndex = threadIndex(traceManager.getCurrentObject());
String threadIndex = threadIndex(traceManager.getCurrentObject());
assertTrue(ti0.contains(threadIndex));
}, RUN_TIMEOUT_MS, RETRY_MS);
}
@ -210,7 +209,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
start(conn, "bash");
conn.execute("breakpoint set -n read");
conn.execute("cont");
waitStopped();
waitForPass(() -> assertThat(
tb.objValues(lastSnap(conn), "Processes[].Threads[].Stack[]").size(),
@ -244,7 +243,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
conn.execute("ghidra_trace_txstart 'Tx'");
conn.execute("ghidra_trace_putmem `(void(*)())main` 10");
conn.execute("ghidra_trace_txcommit");
waitForPass(() -> {
ByteBuffer buf = ByteBuffer.allocate(10);
tb.trace.getMemoryManager().getBytes(lastSnap(conn), tb.addr(address), buf);
@ -262,7 +261,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
conn.execute("ghidra_trace_txstart 'Tx'");
conn.execute("ghidra_trace_putreg");
conn.execute("ghidra_trace_txcommit");
String path = "Processes[].Threads[].Stack[].Registers";
TraceObject registers = Objects.requireNonNull(tb.objAny(path, Lifespan.at(0)));
AddressSpace space = tb.trace.getBaseAddressFactory()
@ -364,7 +363,7 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
//assertEquals(null, tb.objValue(brk, lastSnap(conn), "Commands"));
//conn.execute("breakpoint command add 'echo test'");
//conn.execute("DONE");
waitForPass(
() -> assertEquals("x>3", tb.objValue(brk, lastSnap(conn), "Condition")));
}
@ -389,20 +388,21 @@ public class LldbHooksTest extends AbstractLldbTraceRmiTest {
conn.execute("stepi");
waitForPass(
() -> assertEquals(0, tb.objValues(lastSnap(conn), "Processes[].Breakpoints[]").size()));
() -> assertEquals(0,
tb.objValues(lastSnap(conn), "Processes[].Breakpoints[]").size()));
}
}
private void start(LldbAndTrace conn, String obj) {
conn.execute("file "+obj);
conn.execute("file " + obj);
conn.execute("ghidra_trace_sync_enable");
conn.execute("process launch --stop-at-entry");
txPut(conn, "processes");
}
private void txPut(LldbAndTrace conn, String obj) {
conn.execute("ghidra_trace_txstart 'Tx"+obj+"'");
conn.execute("ghidra_trace_put_"+obj);
conn.execute("ghidra_trace_txstart 'Tx" + obj + "'");
conn.execute("ghidra_trace_put_" + obj);
conn.execute("ghidra_trace_txcommit");
}

View file

@ -17,17 +17,11 @@ package agent.lldb.rmi;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import org.junit.Ignore;
import org.junit.Test;
import generic.Unique;
@ -37,9 +31,7 @@ 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.Address;
import ghidra.program.model.address.AddressRange;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.address.*;
import ghidra.program.model.lang.RegisterValue;
import ghidra.trace.database.ToyDBTraceBuilder;
import ghidra.trace.model.Lifespan;
@ -51,6 +43,7 @@ import ghidra.trace.model.modules.TraceModule;
import ghidra.trace.model.target.TraceObject;
import ghidra.trace.model.target.TraceObjectValue;
@Ignore("Cannot install python packages in CI")
public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
@Test
@ -59,7 +52,8 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
RemoteMethod execute = conn.getMethod("execute");
assertEquals(false,
execute.parameters().get("to_string").defaultValue().get(ValueDecoder.DEFAULT));
assertEquals("test\n", execute.invoke(Map.of("cmd", "script print('test')", "to_string", true)));
assertEquals("test\n",
execute.invoke(Map.of("cmd", "script print('test')", "to_string", true)));
}
}
@ -79,7 +73,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
try (LldbAndHandler conn = startAndConnectLldb()) {
conn.execute("ghidra_trace_start");
txCreate(conn, "Available");
RemoteMethod refreshAvailable = conn.getMethod("refresh_available");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/noname")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
@ -147,7 +141,8 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
waitStopped();
TraceObject locations = Objects.requireNonNull(tb.objAny("Processes[].Breakpoints"));
TraceObject locations =
Objects.requireNonNull(tb.objAny("Processes[].Breakpoints"));
conn.execute("breakpoint set --name main");
conn.execute("breakpoint set -H --name main");
refreshProcBreakpoints.invoke(Map.of("node", locations));
@ -183,7 +178,8 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
waitStopped();
TraceObject locations = Objects.requireNonNull(tb.objAny("Processes[].Watchpoints"));
TraceObject locations =
Objects.requireNonNull(tb.objAny("Processes[].Watchpoints"));
conn.execute("watchpoint set expression -- `(void(*)())main`");
conn.execute("watchpoint set expression -w read -- `(void(*)())main`+-0x20");
conn.execute("watchpoint set expression -w read_write -- `(void(*)())main`+0x30");
@ -196,8 +192,8 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
.toList();
assertEquals(3, procWatchLocVals.size());
AddressRange rangeMain0 =
procWatchLocVals.get(0).getChild().getValue(0, "_range").castValue();
Address main0 = rangeMain0.getMinAddress();
procWatchLocVals.get(0).getChild().getValue(0, "_range").castValue();
Address main0 = rangeMain0.getMinAddress();
AddressRange rangeMain1 =
procWatchLocVals.get(1).getChild().getValue(0, "_range").castValue();
Address main1 = rangeMain1.getMinAddress();
@ -212,7 +208,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
Set.of(TraceBreakpointKind.READ),
"main+0x20");
assertWatchLoc(procWatchLocVals.get(2), "[3]", main2, (int) rangeMain1.getLength(),
Set.of(TraceBreakpointKind.READ,TraceBreakpointKind.WRITE),
Set.of(TraceBreakpointKind.READ, TraceBreakpointKind.WRITE),
"main+0x30");
}
}
@ -224,7 +220,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
conn.execute("ghidra_trace_start");
txCreate(conn, "Processes");
txCreate(conn, "Processes[1]");
RemoteMethod refreshProcesses = conn.getMethod("refresh_processes");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/noname")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
@ -322,7 +318,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
conn.execute("ghidra_trace_txstart 'Tx'");
conn.execute("ghidra_trace_putreg");
conn.execute("ghidra_trace_txcommit");
RemoteMethod refreshRegisters = conn.getMethod("refresh_registers");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/bash")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
@ -388,13 +384,12 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
public void testActivateThread() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
// TODO: need to find this file (same issue in LldbHookTests
String dproc = DummyProc.which("expCloneExit");
conn.execute("file "+dproc);
conn.execute("file " + dproc);
conn.execute("ghidra_trace_start");
txPut(conn, "processes");
breakAt(conn, "work");
@ -403,9 +398,9 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/expCloneExit")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
waitStopped();
txPut(conn, "threads");
PathPattern pattern =
PathPredicates.parse("Processes[].Threads[]").getSingletonPattern();
List<TraceObject> list = tb.trace.getObjectManager()
@ -424,7 +419,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testActivateFrame() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
conn.execute("file bash");
@ -456,7 +451,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testRemoveProcess() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -475,9 +470,9 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testAttachObj() throws Exception {
String sleep = DummyProc.which("expTraceableSleep");
String sleep = DummyProc.which("expTraceableSleep");
try (DummyProc dproc = DummyProc.run(sleep)) {
try (LldbAndHandler conn = startAndConnectLldb()) {
conn.execute("ghidra_trace_start");
@ -487,7 +482,8 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
RemoteMethod attachObj = conn.getMethod("attach_obj");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/noname")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]", Lifespan.at(0)));
TraceObject proc =
Objects.requireNonNull(tb.objAny("Processes[]", Lifespan.at(0)));
TraceObject target =
Objects.requireNonNull(tb.obj("Available[%d]".formatted(dproc.pid)));
attachObj.invoke(Map.of("process", proc, "target", target));
@ -499,9 +495,9 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testAttachPid() throws Exception {
String sleep = DummyProc.which("expTraceableSleep");
String sleep = DummyProc.which("expTraceableSleep");
try (DummyProc dproc = DummyProc.run(sleep)) {
try (LldbAndHandler conn = startAndConnectLldb()) {
conn.execute("ghidra_trace_start");
@ -510,7 +506,8 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
RemoteMethod attachPid = conn.getMethod("attach_pid");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/noname")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
TraceObject proc = Objects.requireNonNull(tb.objAny("Processes[]", Lifespan.at(0)));
TraceObject proc =
Objects.requireNonNull(tb.objAny("Processes[]", Lifespan.at(0)));
attachPid.invoke(Map.of("process", proc, "pid", dproc.pid));
String out = conn.executeCapture("target list");
@ -526,7 +523,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
start(conn, "bash");
txPut(conn, "processes");
//conn.execute("process attach -p %d".formatted(dproc.pid));
RemoteMethod detach = conn.getMethod("detach");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/bash")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
@ -541,7 +538,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testLaunchEntry() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
conn.execute("ghidra_trace_start");
@ -577,7 +574,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
launch.invoke(Map.ofEntries(
Map.entry("process", proc),
Map.entry("file", "bash")));
txPut(conn, "processes");
waitRunning();
@ -585,7 +582,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
conn.execute("process interrupt");
txPut(conn, "processes");
waitStopped();
String out = conn.executeCapture("bt");
@ -594,7 +591,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testKill() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -619,7 +616,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
txPut(conn, "processes");
RemoteMethod step_into = conn.getMethod("step_into");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/bash")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
@ -655,7 +652,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
conn.execute("ghidra_trace_start");
txPut(conn, "processes");
breakAt(conn, "read");
RemoteMethod step_over = conn.getMethod("step_over");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/bash")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
@ -685,7 +682,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()) {
start(conn, "bash");
start(conn, "bash");
RemoteMethod step_ext = conn.getMethod("step_ext");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/bash")) {
@ -707,7 +704,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testFinish() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
conn.execute("file bash");
@ -724,18 +721,18 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
TraceObject thread = Objects.requireNonNull(tb.objAny("Processes[].Threads[]"));
activate.invoke(Map.of("thread", thread));
int initDepth = getDepth(conn);
step_out.invoke(Map.of("thread", thread));
int finalDepth = getDepth(conn);
assertEquals(initDepth-1, finalDepth);
assertEquals(initDepth - 1, finalDepth);
}
}
}
@Test
@Test
public void testReturn() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
conn.execute("file bash");
@ -752,18 +749,18 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
TraceObject thread = Objects.requireNonNull(tb.objAny("Processes[].Threads[]"));
activate.invoke(Map.of("thread", thread));
int initDepth = getDepth(conn);
ret.invoke(Map.of("thread", thread));
int finalDepth = getDepth(conn);
assertEquals(initDepth-1, finalDepth);
assertEquals(initDepth - 1, finalDepth);
}
}
}
@Test
@Test
public void testBreakAddress() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -784,7 +781,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testBreakExpression() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -825,7 +822,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testBreakHardwareExpression() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -846,7 +843,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testBreakReadRange() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -870,7 +867,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testBreakReadExpression() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -890,7 +887,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testBreakWriteRange() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -914,7 +911,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testBreakWriteExpression() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -934,7 +931,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testBreakAccessRange() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -958,7 +955,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testBreakAccessExpression() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -979,7 +976,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
// NB: not really equivalent to gdb's "catch" but...
@Test
@Test
public void testBreakException() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -998,19 +995,19 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testToggleBreakpoint() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
conn.execute("file bash");
conn.execute("ghidra_trace_start");
txPut(conn, "processes");
breakAt(conn, "main");
RemoteMethod toggleBreakpoint = conn.getMethod("toggle_breakpoint");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/bash")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
waitStopped();
txPut(conn, "breakpoints");
TraceObject bpt = Objects.requireNonNull(tb.objAny("Breakpoints[]"));
@ -1022,20 +1019,19 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testToggleBreakpointLocation() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
conn.execute("file bash");
conn.execute("ghidra_trace_start");
txPut(conn, "processes");
breakAt(conn, "main");
RemoteMethod toggleBreakpointLocation = conn.getMethod("toggle_breakpoint_location");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/bash")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
waitStopped();
txPut(conn, "breakpoints");
// NB. Requires canonical path. Inf[].Brk[] is a link
@ -1049,14 +1045,14 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
@Test
@Test
public void testDeleteBreakpoint() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
conn.execute("file bash");
conn.execute("ghidra_trace_start");
txPut(conn, "processes");
breakAt(conn, "main");
RemoteMethod deleteBreakpoint = conn.getMethod("delete_breakpoint");
try (ManagedDomainObject mdo = openDomainObject("/New Traces/lldb/bash")) {
tb = new ToyDBTraceBuilder((Trace) mdo.get());
@ -1072,8 +1068,8 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
}
@Test
@Test
public void testDeleteWatchpoint() throws Exception {
try (LldbAndHandler conn = startAndConnectLldb()) {
start(conn, "bash");
@ -1086,10 +1082,10 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
breakExpression.invoke(Map.of("expression", "`(void(*)())main`"));
long address = Long.decode(conn.executeCapture("dis -c1 -n main").split("\\s+")[1]);
String out = conn.executeCapture("watchpoint list");
assertThat(out, containsString(Long.toHexString(address)));
txPut(conn, "watchpoints");
TraceObject wpt = Objects.requireNonNull(tb.objAny("Processes[].Watchpoints[]"));
@ -1100,16 +1096,16 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
}
}
}
private void start(LldbAndHandler conn, String obj) {
conn.execute("file "+obj);
conn.execute("file " + obj);
conn.execute("ghidra_trace_start");
conn.execute("process launch --stop-at-entry");
}
private void txPut(LldbAndHandler conn, String obj) {
conn.execute("ghidra_trace_txstart 'Tx'");
conn.execute("ghidra_trace_put_"+obj);
conn.execute("ghidra_trace_put_" + obj);
conn.execute("ghidra_trace_txcommit");
}
@ -1121,7 +1117,7 @@ public class LldbMethodsTest extends AbstractLldbTraceRmiTest {
private void breakAt(LldbAndHandler conn, String fn) {
conn.execute("ghidra_trace_sync_enable");
conn.execute("breakpoint set -n "+fn);
conn.execute("breakpoint set -n " + fn);
conn.execute("run");
}