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)