aboutsummaryrefslogtreecommitdiff
path: root/lldb/test/API/python_api
diff options
context:
space:
mode:
authorMiro Bucko <mbucko@meta.com>2024-06-24 11:06:20 -0400
committerGitHub <noreply@github.com>2024-06-24 11:06:20 -0400
commit10bd5ad0a133fe73ffc1b05e63bc3fb2d56ba79c (patch)
tree4bb3605dff443e0d38427626e0bd5c73e7129737 /lldb/test/API/python_api
parentdb9e9eabb7835bae4285a3f13c7cc7c985455e27 (diff)
downloadllvm-10bd5ad0a133fe73ffc1b05e63bc3fb2d56ba79c.zip
llvm-10bd5ad0a133fe73ffc1b05e63bc3fb2d56ba79c.tar.gz
llvm-10bd5ad0a133fe73ffc1b05e63bc3fb2d56ba79c.tar.bz2
[lldb][API] Add Find(Ranges)InMemory() to Process SB API (#95007)
Test Plan: llvm-lit llvm-project/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py llvm-project/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py Reviewers: clayborg Tasks: lldb
Diffstat (limited to 'lldb/test/API/python_api')
-rw-r--r--lldb/test/API/python_api/find_in_memory/Makefile3
-rw-r--r--lldb/test/API/python_api/find_in_memory/TestFindInMemory.py131
-rw-r--r--lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py221
-rw-r--r--lldb/test/API/python_api/find_in_memory/address_ranges_helper.py73
-rw-r--r--lldb/test/API/python_api/find_in_memory/main.cpp27
5 files changed, 455 insertions, 0 deletions
diff --git a/lldb/test/API/python_api/find_in_memory/Makefile b/lldb/test/API/python_api/find_in_memory/Makefile
new file mode 100644
index 0000000..99998b2
--- /dev/null
+++ b/lldb/test/API/python_api/find_in_memory/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py
new file mode 100644
index 0000000..4a459c4
--- /dev/null
+++ b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py
@@ -0,0 +1,131 @@
+"""
+Test Process::FindInMemory.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from address_ranges_helper import *
+
+
+class FindInMemoryTestCase(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def setUp(self):
+ TestBase.setUp(self)
+
+ self.build()
+ (
+ self.target,
+ self.process,
+ self.thread,
+ self.bp,
+ ) = lldbutil.run_to_source_breakpoint(
+ self, "break here", lldb.SBFileSpec("main.cpp")
+ )
+ self.assertTrue(self.bp.IsValid())
+
+ def test_find_in_memory_ok(self):
+ """Make sure a match exists in the heap memory and the right address ranges are provided"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+ error = lldb.SBError()
+ addr = self.process.FindInMemory(
+ SINGLE_INSTANCE_PATTERN_STACK,
+ GetStackRange(self),
+ 1,
+ error,
+ )
+
+ self.assertSuccess(error)
+ self.assertNotEqual(addr, lldb.LLDB_INVALID_ADDRESS)
+
+ def test_find_in_memory_double_instance_ok(self):
+ """Make sure a match exists in the heap memory and the right address ranges are provided"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+ error = lldb.SBError()
+ addr = self.process.FindInMemory(
+ DOUBLE_INSTANCE_PATTERN_HEAP,
+ GetHeapRanges(self)[0],
+ 1,
+ error,
+ )
+
+ self.assertSuccess(error)
+ self.assertNotEqual(addr, lldb.LLDB_INVALID_ADDRESS)
+
+ def test_find_in_memory_invalid_alignment(self):
+ """Make sure the alignment 0 is failing"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ error = lldb.SBError()
+ addr = self.process.FindInMemory(
+ SINGLE_INSTANCE_PATTERN_STACK,
+ GetStackRange(self),
+ 0,
+ error,
+ )
+
+ self.assertFailure(error)
+ self.assertEqual(addr, lldb.LLDB_INVALID_ADDRESS)
+
+ def test_find_in_memory_invalid_address_range(self):
+ """Make sure invalid address range is failing"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ error = lldb.SBError()
+ addr = self.process.FindInMemory(
+ SINGLE_INSTANCE_PATTERN_STACK,
+ lldb.SBAddressRange(),
+ 1,
+ error,
+ )
+
+ self.assertFailure(error)
+ self.assertEqual(addr, lldb.LLDB_INVALID_ADDRESS)
+
+ def test_find_in_memory_invalid_buffer(self):
+ """Make sure the empty buffer is failing"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ error = lldb.SBError()
+ addr = self.process.FindInMemory(
+ "",
+ GetStackRange(self),
+ 1,
+ error,
+ )
+
+ self.assertFailure(error)
+ self.assertEqual(addr, lldb.LLDB_INVALID_ADDRESS)
+
+ def test_find_in_memory_unaligned(self):
+ """Make sure the unaligned match exists in the heap memory and is not found with alignment 8"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+ error = lldb.SBError()
+ range = GetAlignedRange(self)
+
+ # First we make sure the pattern is found with alignment 1
+ addr = self.process.FindInMemory(
+ UNALIGNED_INSTANCE_PATTERN_HEAP,
+ range,
+ 1,
+ error,
+ )
+ self.assertSuccess(error)
+ self.assertNotEqual(addr, lldb.LLDB_INVALID_ADDRESS)
+
+ # With alignment 8 the pattern should not be found
+ addr = self.process.FindInMemory(
+ UNALIGNED_INSTANCE_PATTERN_HEAP,
+ range,
+ 8,
+ error,
+ )
+ self.assertSuccess(error)
+ self.assertEqual(addr, lldb.LLDB_INVALID_ADDRESS)
diff --git a/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py b/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py
new file mode 100644
index 0000000..31bc0e9
--- /dev/null
+++ b/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py
@@ -0,0 +1,221 @@
+"""
+Test Process::FindRangesInMemory.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+from address_ranges_helper import *
+
+
+class FindRangesInMemoryTestCase(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def setUp(self):
+ TestBase.setUp(self)
+
+ self.build()
+ (
+ self.target,
+ self.process,
+ self.thread,
+ self.bp,
+ ) = lldbutil.run_to_source_breakpoint(
+ self, "break here", lldb.SBFileSpec("main.cpp")
+ )
+ self.assertTrue(self.bp.IsValid())
+
+ def test_find_ranges_in_memory_two_matches(self):
+ """Make sure two matches exist in the heap memory and the right address ranges are provided"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ addr_ranges = GetHeapRanges(self)
+ error = lldb.SBError()
+ matches = self.process.FindRangesInMemory(
+ DOUBLE_INSTANCE_PATTERN_HEAP,
+ addr_ranges,
+ 1,
+ 10,
+ error,
+ )
+
+ self.assertSuccess(error)
+ self.assertEqual(matches.GetSize(), 2)
+
+ def test_find_ranges_in_memory_one_match(self):
+ """Make sure exactly one match exists in the heap memory and the right address ranges are provided"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ addr_ranges = GetStackRanges(self)
+ error = lldb.SBError()
+ matches = self.process.FindRangesInMemory(
+ SINGLE_INSTANCE_PATTERN_STACK,
+ addr_ranges,
+ 1,
+ 10,
+ error,
+ )
+
+ self.assertSuccess(error)
+ self.assertEqual(matches.GetSize(), 1)
+
+ def test_find_ranges_in_memory_one_match_multiple_ranges(self):
+ """Make sure exactly one match exists in the heap memory and multiple address ranges are provided"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ addr_ranges = GetRanges(self)
+ addr_ranges.Append(lldb.SBAddressRange())
+ self.assertGreater(addr_ranges.GetSize(), 2)
+ error = lldb.SBError()
+ matches = self.process.FindRangesInMemory(
+ SINGLE_INSTANCE_PATTERN_STACK,
+ addr_ranges,
+ 1,
+ 10,
+ error,
+ )
+
+ self.assertSuccess(error)
+ self.assertEqual(matches.GetSize(), 1)
+
+ def test_find_ranges_in_memory_one_match_max(self):
+ """Make sure at least one matche exists in the heap memory and the right address ranges are provided"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ addr_ranges = GetHeapRanges(self)
+ error = lldb.SBError()
+ matches = self.process.FindRangesInMemory(
+ DOUBLE_INSTANCE_PATTERN_HEAP,
+ addr_ranges,
+ 1,
+ 1,
+ error,
+ )
+
+ self.assertSuccess(error)
+ self.assertEqual(matches.GetSize(), 1)
+
+ def test_find_ranges_in_memory_invalid_alignment(self):
+ """Make sure the alignment 0 is failing"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ addr_ranges = GetHeapRanges(self)
+ error = lldb.SBError()
+ matches = self.process.FindRangesInMemory(
+ DOUBLE_INSTANCE_PATTERN_HEAP,
+ addr_ranges,
+ 0,
+ 10,
+ error,
+ )
+
+ self.assertFailure(error)
+ self.assertEqual(matches.GetSize(), 0)
+
+ def test_find_ranges_in_memory_invalid_range(self):
+ """Make sure the alignment 0 is failing"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ addr_ranges = lldb.SBAddressRangeList()
+ addr_ranges.Append(lldb.SBAddressRange())
+ error = lldb.SBError()
+ matches = self.process.FindRangesInMemory(
+ DOUBLE_INSTANCE_PATTERN_HEAP,
+ addr_ranges,
+ 1,
+ 10,
+ error,
+ )
+
+ self.assertFailure(error)
+ self.assertIn("unable to resolve any ranges", str(error))
+ self.assertEqual(matches.GetSize(), 0)
+
+ def test_find_ranges_in_memory_empty_ranges(self):
+ """Make sure the empty ranges is failing"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ addr_ranges = lldb.SBAddressRangeList()
+ error = lldb.SBError()
+ matches = self.process.FindRangesInMemory(
+ DOUBLE_INSTANCE_PATTERN_HEAP,
+ addr_ranges,
+ 1,
+ 10,
+ error,
+ )
+
+ self.assertFailure(error)
+ self.assertEqual(matches.GetSize(), 0)
+
+ def test_find_ranges_in_memory_invalid_buffer(self):
+ """Make sure the empty buffer is failing"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ addr_ranges = GetHeapRanges(self)
+ error = lldb.SBError()
+ matches = self.process.FindRangesInMemory(
+ "",
+ addr_ranges,
+ 1,
+ 10,
+ error,
+ )
+
+ self.assertFailure(error)
+ self.assertEqual(matches.GetSize(), 0)
+
+ def test_find_ranges_in_memory_invalid_max_matches(self):
+ """Make sure the empty buffer is failing"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ addr_ranges = GetHeapRanges(self)
+ error = lldb.SBError()
+ matches = self.process.FindRangesInMemory(
+ DOUBLE_INSTANCE_PATTERN_HEAP,
+ addr_ranges,
+ 1,
+ 0,
+ error,
+ )
+
+ self.assertFailure(error)
+ self.assertEqual(matches.GetSize(), 0)
+
+ def test_find_in_memory_unaligned(self):
+ """Make sure the unaligned match exists in the heap memory and is not found with alignment 8"""
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ addr_ranges = lldb.SBAddressRangeList()
+ addr_ranges.Append(GetAlignedRange(self))
+ error = lldb.SBError()
+
+ matches = self.process.FindRangesInMemory(
+ UNALIGNED_INSTANCE_PATTERN_HEAP,
+ addr_ranges,
+ 1,
+ 10,
+ error,
+ )
+ self.assertSuccess(error)
+ self.assertEqual(matches.GetSize(), 1)
+
+ matches = self.process.FindRangesInMemory(
+ UNALIGNED_INSTANCE_PATTERN_HEAP,
+ addr_ranges,
+ 8,
+ 10,
+ error,
+ )
+ self.assertSuccess(error)
+ self.assertEqual(matches.GetSize(), 0)
diff --git a/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py b/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py
new file mode 100644
index 0000000..0544100
--- /dev/null
+++ b/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py
@@ -0,0 +1,73 @@
+import lldb
+
+SINGLE_INSTANCE_PATTERN_STACK = "stack_there_is_only_one_of_me"
+DOUBLE_INSTANCE_PATTERN_HEAP = "heap_there_is_exactly_two_of_me"
+ALIGNED_INSTANCE_PATTERN_HEAP = "i_am_unaligned_string_on_the_heap"
+UNALIGNED_INSTANCE_PATTERN_HEAP = ALIGNED_INSTANCE_PATTERN_HEAP[1:]
+
+
+def GetAlignedRange(test_base):
+ frame = test_base.thread.GetSelectedFrame()
+ ex = frame.EvaluateExpression("aligned_string_ptr")
+ test_base.assertTrue(ex.IsValid())
+ return GetRangeFromAddrValue(test_base, ex)
+
+
+def GetStackRange(test_base):
+ frame = test_base.thread.GetSelectedFrame()
+ ex = frame.EvaluateExpression("stack_pointer")
+ test_base.assertTrue(ex.IsValid())
+ return GetRangeFromAddrValue(test_base, ex)
+
+
+def GetStackRanges(test_base):
+ addr_ranges = lldb.SBAddressRangeList()
+ addr_ranges.Append(GetStackRange(test_base))
+ return addr_ranges
+
+
+def GetRangeFromAddrValue(test_base, addr):
+ region = lldb.SBMemoryRegionInfo()
+ test_base.assertTrue(
+ test_base.process.GetMemoryRegionInfo(
+ addr.GetValueAsUnsigned(), region
+ ).Success(),
+ )
+
+ test_base.assertTrue(region.IsReadable())
+ test_base.assertFalse(region.IsExecutable())
+
+ address_start = lldb.SBAddress(region.GetRegionBase(), test_base.target)
+ stack_size = region.GetRegionEnd() - region.GetRegionBase()
+ return lldb.SBAddressRange(address_start, stack_size)
+
+
+def IsWithinRange(addr, range, target):
+ start_addr = range.GetBaseAddress().GetLoadAddress(target)
+ end_addr = start_addr + range.GetByteSize()
+ addr = addr.GetValueAsUnsigned()
+ return addr >= start_addr and addr < end_addr
+
+
+def GetHeapRanges(test_base):
+ frame = test_base.thread.GetSelectedFrame()
+
+ ex = frame.EvaluateExpression("heap_pointer1")
+ test_base.assertTrue(ex.IsValid())
+ range = GetRangeFromAddrValue(test_base, ex)
+ addr_ranges = lldb.SBAddressRangeList()
+ addr_ranges.Append(range)
+
+ ex = frame.EvaluateExpression("heap_pointer2")
+ test_base.assertTrue(ex.IsValid())
+ if not IsWithinRange(ex, addr_ranges[0], test_base.target):
+ addr_ranges.Append(GetRangeFromAddrValue(test_base, ex))
+
+ return addr_ranges
+
+
+def GetRanges(test_base):
+ ranges = GetHeapRanges(test_base)
+ ranges.Append(GetStackRanges(test_base))
+
+ return ranges
diff --git a/lldb/test/API/python_api/find_in_memory/main.cpp b/lldb/test/API/python_api/find_in_memory/main.cpp
new file mode 100644
index 0000000..98d378c
--- /dev/null
+++ b/lldb/test/API/python_api/find_in_memory/main.cpp
@@ -0,0 +1,27 @@
+#include <cstdlib>
+#include <cstring>
+#include <string>
+
+int main() {
+ // Stack
+ const char *stack_pointer = "stack_there_is_only_one_of_me";
+
+ // Heap
+ const std::string heap_string1("heap_there_is_exactly_two_of_me");
+ const std::string heap_string2("heap_there_is_exactly_two_of_me");
+ const char *heap_pointer1 = heap_string1.data();
+ const char *heap_pointer2 = heap_string2.data();
+
+ // Aligned Heap
+ constexpr char aligned_string[] = "i_am_unaligned_string_on_the_heap";
+ constexpr size_t len = sizeof(aligned_string) + 1;
+ // Allocate memory aligned to 8-byte boundary
+ void *aligned_string_ptr = aligned_alloc(8, len);
+ memcpy(aligned_string_ptr, aligned_string, len);
+
+ (void)stack_pointer;
+ (void)heap_pointer1;
+ (void)heap_pointer2;
+ (void)aligned_string_ptr; // break here
+ return 0;
+}