Files
clang-p2996/lldb/test/API/tools/lldb-server/TestGdbRemote_qMemoryRegion.py
David Peixotto d1deaed0d2 [lldb] Split some lldb-server tests to avoid timeout (#129614)
Split test cases out of TestLldbGdbServer.py and TestGdbRemoteFork.py
into separate files to avoid hitting the 600s timeout limit. The
inferior used by these tests (main.cpp) takes approximately 20s to
compile with a Debug build of clang, causing timeouts when a single test
file contains many tests. By grouping similar tests into separate files,
we can prevent timeouts and improve overall test efficiency.
2025-03-13 15:54:45 -07:00

211 lines
8.0 KiB
Python

import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test.lldbdwarf import *
class TestGdbRemote_qMemoryRegion(gdbremote_testcase.GdbRemoteTestCaseBase):
def test_qMemoryRegionInfo_is_supported(self):
self.build()
self.set_inferior_startup_launch()
# Start up the inferior.
procs = self.prep_debug_monitor_and_inferior()
# Ask if it supports $qMemoryRegionInfo.
self.test_sequence.add_log_lines(
["read packet: $qMemoryRegionInfo#00", "send packet: $OK#00"], True
)
self.expect_gdbremote_sequence()
@skipIfWindows # No pty support to test any inferior output
def test_qMemoryRegionInfo_reports_code_address_as_executable(self):
self.build()
self.set_inferior_startup_launch()
# Start up the inferior.
procs = self.prep_debug_monitor_and_inferior(
inferior_args=["get-code-address-hex:hello", "sleep:5"]
)
# Run the process
self.test_sequence.add_log_lines(
[
# Start running after initial stop.
"read packet: $c#63",
# Match output line that prints the memory address of the message buffer within the inferior.
# Note we require launch-only testing so we can get inferior otuput.
{
"type": "output_match",
"regex": self.maybe_strict_output_regex(
r"code address: 0x([0-9a-fA-F]+)\r\n"
),
"capture": {1: "code_address"},
},
# Now stop the inferior.
"read packet: {}".format(chr(3)),
# And wait for the stop notification.
{
"direction": "send",
"regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
"capture": {1: "stop_signo", 2: "stop_thread_id"},
},
],
True,
)
# Run the packet stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Grab the code address.
self.assertIsNotNone(context.get("code_address"))
code_address = int(context.get("code_address"), 16)
# Grab memory region info from the inferior.
self.reset_test_sequence()
self.add_query_memory_region_packets(code_address)
# Run the packet stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
mem_region_dict = self.parse_memory_region_packet(context)
# Ensure there are no errors reported.
self.assertNotIn("error", mem_region_dict)
# Ensure code address is readable and executable.
self.assertIn("permissions", mem_region_dict)
self.assertIn("r", mem_region_dict["permissions"])
self.assertIn("x", mem_region_dict["permissions"])
# Ensure the start address and size encompass the address we queried.
self.assert_address_within_memory_region(code_address, mem_region_dict)
@skipIfWindows # No pty support to test any inferior output
def test_qMemoryRegionInfo_reports_stack_address_as_rw(self):
self.build()
self.set_inferior_startup_launch()
# Start up the inferior.
procs = self.prep_debug_monitor_and_inferior(
inferior_args=["get-stack-address-hex:", "sleep:5"]
)
# Run the process
self.test_sequence.add_log_lines(
[
# Start running after initial stop.
"read packet: $c#63",
# Match output line that prints the memory address of the message buffer within the inferior.
# Note we require launch-only testing so we can get inferior otuput.
{
"type": "output_match",
"regex": self.maybe_strict_output_regex(
r"stack address: 0x([0-9a-fA-F]+)\r\n"
),
"capture": {1: "stack_address"},
},
# Now stop the inferior.
"read packet: {}".format(chr(3)),
# And wait for the stop notification.
{
"direction": "send",
"regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
"capture": {1: "stop_signo", 2: "stop_thread_id"},
},
],
True,
)
# Run the packet stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Grab the address.
self.assertIsNotNone(context.get("stack_address"))
stack_address = int(context.get("stack_address"), 16)
# Grab memory region info from the inferior.
self.reset_test_sequence()
self.add_query_memory_region_packets(stack_address)
# Run the packet stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
mem_region_dict = self.parse_memory_region_packet(context)
# Ensure there are no errors reported.
self.assertNotIn("error", mem_region_dict)
# Ensure address is readable and executable.
self.assertIn("permissions", mem_region_dict)
self.assertIn("r", mem_region_dict["permissions"])
self.assertIn("w", mem_region_dict["permissions"])
# Ensure the start address and size encompass the address we queried.
self.assert_address_within_memory_region(stack_address, mem_region_dict)
@skipIfWindows # No pty support to test any inferior output
def test_qMemoryRegionInfo_reports_heap_address_as_rw(self):
self.build()
self.set_inferior_startup_launch()
# Start up the inferior.
procs = self.prep_debug_monitor_and_inferior(
inferior_args=["get-heap-address-hex:", "sleep:5"]
)
# Run the process
self.test_sequence.add_log_lines(
[
# Start running after initial stop.
"read packet: $c#63",
# Match output line that prints the memory address of the message buffer within the inferior.
# Note we require launch-only testing so we can get inferior otuput.
{
"type": "output_match",
"regex": self.maybe_strict_output_regex(
r"heap address: 0x([0-9a-fA-F]+)\r\n"
),
"capture": {1: "heap_address"},
},
# Now stop the inferior.
"read packet: {}".format(chr(3)),
# And wait for the stop notification.
{
"direction": "send",
"regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);",
"capture": {1: "stop_signo", 2: "stop_thread_id"},
},
],
True,
)
# Run the packet stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
# Grab the address.
self.assertIsNotNone(context.get("heap_address"))
heap_address = int(context.get("heap_address"), 16)
# Grab memory region info from the inferior.
self.reset_test_sequence()
self.add_query_memory_region_packets(heap_address)
# Run the packet stream.
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
mem_region_dict = self.parse_memory_region_packet(context)
# Ensure there are no errors reported.
self.assertNotIn("error", mem_region_dict)
# Ensure address is readable and executable.
self.assertIn("permissions", mem_region_dict)
self.assertIn("r", mem_region_dict["permissions"])
self.assertIn("w", mem_region_dict["permissions"])
# Ensure the start address and size encompass the address we queried.
self.assert_address_within_memory_region(heap_address, mem_region_dict)