Skip to content

Commit

Permalink
[lldb] Speed up FindInMemory tests
Browse files Browse the repository at this point in the history
A memory region can be relatively large. Searching for a value in the
entire region is time-consuming, especially when running tests against
a remote target, because the memory data is transferred in small chunks
over a relatively slow GDBRemote protocol. The patch limits the address
range to be searched to 2K, which seems sufficient for these tests. In
my setup, for local runs, these tests now take half the time they did
before the patch. For a remote target, the improvement is even more
significant.
  • Loading branch information
igorkudrin committed Oct 11, 2024
1 parent 1809d0f commit 6ea1173
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 31 deletions.
10 changes: 5 additions & 5 deletions lldb/test/API/python_api/find_in_memory/TestFindInMemory.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def test_find_in_memory_ok(self):
error = lldb.SBError()
addr = self.process.FindInMemory(
SINGLE_INSTANCE_PATTERN_STACK,
GetStackRange(self),
GetStackRange(self, True),
1,
error,
)
Expand All @@ -70,7 +70,7 @@ def test_find_in_memory_double_instance_ok(self):
error = lldb.SBError()
addr = self.process.FindInMemory(
DOUBLE_INSTANCE_PATTERN_HEAP,
GetHeapRanges(self)[0],
GetHeapRanges(self, True)[0],
1,
error,
)
Expand All @@ -86,7 +86,7 @@ def test_find_in_memory_invalid_alignment(self):
error = lldb.SBError()
addr = self.process.FindInMemory(
SINGLE_INSTANCE_PATTERN_STACK,
GetStackRange(self),
GetStackRange(self, True),
0,
error,
)
Expand Down Expand Up @@ -118,7 +118,7 @@ def test_find_in_memory_invalid_buffer(self):
error = lldb.SBError()
addr = self.process.FindInMemory(
"",
GetStackRange(self),
GetStackRange(self, True),
1,
error,
)
Expand All @@ -131,7 +131,7 @@ def test_find_in_memory_unaligned(self):
self.assertTrue(self.process, PROCESS_IS_VALID)
self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
error = lldb.SBError()
range = GetAlignedRange(self)
range = GetAlignedRange(self, True)

# First we make sure the pattern is found with alignment 1
addr = self.process.FindInMemory(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def test_find_ranges_in_memory_two_matches(self):
self.assertTrue(self.process, PROCESS_IS_VALID)
self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)

addr_ranges = GetHeapRanges(self)
addr_ranges = GetHeapRanges(self, True)
error = lldb.SBError()
matches = self.process.FindRangesInMemory(
DOUBLE_INSTANCE_PATTERN_HEAP,
Expand All @@ -48,7 +48,7 @@ def test_find_ranges_in_memory_one_match(self):
self.assertTrue(self.process, PROCESS_IS_VALID)
self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)

addr_ranges = GetStackRanges(self)
addr_ranges = GetStackRanges(self, True)
error = lldb.SBError()
matches = self.process.FindRangesInMemory(
SINGLE_INSTANCE_PATTERN_STACK,
Expand All @@ -66,7 +66,7 @@ def test_find_ranges_in_memory_one_match_multiple_ranges(self):
self.assertTrue(self.process, PROCESS_IS_VALID)
self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)

addr_ranges = GetRanges(self)
addr_ranges = GetRanges(self, True)
addr_ranges.Append(lldb.SBAddressRange())
self.assertGreater(addr_ranges.GetSize(), 2)
error = lldb.SBError()
Expand All @@ -86,7 +86,7 @@ def test_find_ranges_in_memory_one_match_max(self):
self.assertTrue(self.process, PROCESS_IS_VALID)
self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)

addr_ranges = GetHeapRanges(self)
addr_ranges = GetHeapRanges(self, True)
error = lldb.SBError()
matches = self.process.FindRangesInMemory(
DOUBLE_INSTANCE_PATTERN_HEAP,
Expand All @@ -104,7 +104,7 @@ def test_find_ranges_in_memory_invalid_alignment(self):
self.assertTrue(self.process, PROCESS_IS_VALID)
self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)

addr_ranges = GetHeapRanges(self)
addr_ranges = GetHeapRanges(self, True)
error = lldb.SBError()
matches = self.process.FindRangesInMemory(
DOUBLE_INSTANCE_PATTERN_HEAP,
Expand Down Expand Up @@ -160,7 +160,7 @@ def test_find_ranges_in_memory_invalid_buffer(self):
self.assertTrue(self.process, PROCESS_IS_VALID)
self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)

addr_ranges = GetHeapRanges(self)
addr_ranges = GetHeapRanges(self, True)
error = lldb.SBError()
matches = self.process.FindRangesInMemory(
"",
Expand All @@ -178,7 +178,7 @@ def test_find_ranges_in_memory_invalid_max_matches(self):
self.assertTrue(self.process, PROCESS_IS_VALID)
self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)

addr_ranges = GetHeapRanges(self)
addr_ranges = GetHeapRanges(self, True)
error = lldb.SBError()
matches = self.process.FindRangesInMemory(
DOUBLE_INSTANCE_PATTERN_HEAP,
Expand All @@ -197,7 +197,7 @@ def test_find_in_memory_unaligned(self):
self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)

addr_ranges = lldb.SBAddressRangeList()
addr_ranges.Append(GetAlignedRange(self))
addr_ranges.Append(GetAlignedRange(self, True))
error = lldb.SBError()

matches = self.process.FindRangesInMemory(
Expand Down
50 changes: 32 additions & 18 deletions lldb/test/API/python_api/find_in_memory/address_ranges_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,30 @@
UNALIGNED_INSTANCE_PATTERN_HEAP = ALIGNED_INSTANCE_PATTERN_HEAP[1:]


def GetAlignedRange(test_base):
def GetAlignedRange(test_base, shrink=False):
frame = test_base.thread.GetSelectedFrame()
ex = frame.EvaluateExpression("aligned_string_ptr")
test_base.assertTrue(ex.IsValid())
return GetRangeFromAddrValue(test_base, ex)
return GetRangeFromAddrValue(test_base, ex, shrink)


def GetStackRange(test_base):
def GetStackRange(test_base, shrink=False):
frame = test_base.thread.GetSelectedFrame()
ex = frame.EvaluateExpression("&stack_pointer")
test_base.assertTrue(ex.IsValid())
return GetRangeFromAddrValue(test_base, ex)
return GetRangeFromAddrValue(test_base, ex, shrink)


def GetStackRanges(test_base):
def GetStackRanges(test_base, shrink=False):
addr_ranges = lldb.SBAddressRangeList()
addr_ranges.Append(GetStackRange(test_base))
return addr_ranges


def GetRangeFromAddrValue(test_base, addr):
def GetRangeFromAddrValue(test_base, addr, shrink=False):
""" Return the address range containing 'addr'.
If 'shrink' is True, the size of the region will not exceed 2K.
"""
region = lldb.SBMemoryRegionInfo()
test_base.assertTrue(
test_base.process.GetMemoryRegionInfo(
Expand All @@ -36,38 +39,49 @@ def GetRangeFromAddrValue(test_base, addr):

test_base.assertTrue(region.IsReadable())
test_base.assertFalse(region.IsExecutable())

base = region.GetRegionBase()
end = region.GetRegionEnd()

address_start = lldb.SBAddress(region.GetRegionBase(), test_base.target)
stack_size = region.GetRegionEnd() - region.GetRegionBase()
return lldb.SBAddressRange(address_start, stack_size)
if shrink:
addr2 = addr.GetValueAsUnsigned()
addr2 -= addr2 % 512
base = max(base, addr2 - 1024)
end = min(end, addr2 + 1024)

start = lldb.SBAddress(base, test_base.target)
size = end - base

def IsWithinRange(addr, range, target):
return lldb.SBAddressRange(start, size)


def IsWithinRange(addr, size, 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
return addr >= start_addr and addr + size <= end_addr


def GetHeapRanges(test_base):
def GetHeapRanges(test_base, shrink=False):
frame = test_base.thread.GetSelectedFrame()

ex = frame.EvaluateExpression("heap_pointer1")
test_base.assertTrue(ex.IsValid())
range = GetRangeFromAddrValue(test_base, ex)
range = GetRangeFromAddrValue(test_base, ex, shrink)
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))
size = len(DOUBLE_INSTANCE_PATTERN_HEAP)
if not IsWithinRange(ex, size, addr_ranges[0], test_base.target):
addr_ranges.Append(GetRangeFromAddrValue(test_base, ex, shrink))

return addr_ranges


def GetRanges(test_base):
ranges = GetHeapRanges(test_base)
ranges.Append(GetStackRanges(test_base))
def GetRanges(test_base, shrink=False):
ranges = GetHeapRanges(test_base, shrink)
ranges.Append(GetStackRanges(test_base, shrink))

return ranges

0 comments on commit 6ea1173

Please sign in to comment.