""" Tests debugserver support for MultiMemRead. """ import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil @skipUnlessDarwin @skipIfOutOfTreeDebugserver class TestCase(TestBase): def send_process_packet(self, packet_str): self.runCmd(f"proc plugin packet send {packet_str}", check=False) # The output is of the form: # packet: # response: reply = self.res.GetOutput().split("\n") packet = reply[0].strip() response = reply[1].strip() self.assertTrue(packet.startswith("packet: ")) self.assertTrue(response.startswith("response: ")) return response[len("response: ") :] def check_invalid_packet(self, packet_str): reply = self.send_process_packet("packet_str") self.assertEqual(reply, "E03") def test_packets(self): self.build() source_file = lldb.SBFileSpec("main.c") target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( self, "break here", source_file ) reply = self.send_process_packet("qSupported") self.assertIn("MultiMemRead+", reply) mem_address_var = thread.frames[0].FindVariable("memory") self.assertTrue(mem_address_var) mem_address = mem_address_var.GetValueAsUnsigned() + 42 # no ":" self.check_invalid_packet("MultiMemRead") # missing ranges self.check_invalid_packet("MultiMemRead:") # needs at least one range self.check_invalid_packet("MultiMemRead:ranges:") # needs at least one range self.check_invalid_packet("MultiMemRead:ranges:,") # a range is a pair of numbers self.check_invalid_packet("MultiMemRead:ranges:10") # a range is a pair of numbers self.check_invalid_packet("MultiMemRead:ranges:10,") # range list must end with ; self.check_invalid_packet("MultiMemRead:ranges:10,2") self.check_invalid_packet("MultiMemRead:ranges:10,2,") self.check_invalid_packet("MultiMemRead:ranges:10,2,3") # ranges are pairs of numbers. self.check_invalid_packet("MultiMemRead:ranges:10,2,3;") # unrecognized field self.check_invalid_packet("MultiMemRead:ranges:10,2;blah:;") # unrecognized field self.check_invalid_packet("MultiMemRead:blah:;ranges:10,2;") # Zero-length reads are ok. reply = self.send_process_packet("MultiMemRead:ranges:0,0;") self.assertEqual(reply, "0;") # Debugserver is permissive with trailing commas. reply = self.send_process_packet("MultiMemRead:ranges:10,2,;") self.assertEqual(reply, "0;") reply = self.send_process_packet(f"MultiMemRead:ranges:{mem_address:x},2,;") self.assertEqual(reply, "2;ab") reply = self.send_process_packet("MultiMemRead:ranges:10,2;") self.assertEqual(reply, "0;") reply = self.send_process_packet(f"MultiMemRead:ranges:{mem_address:x},0;") self.assertEqual(reply, "0;") reply = self.send_process_packet(f"MultiMemRead:ranges:{mem_address:x},2;") self.assertEqual(reply, "2;ab") reply = self.send_process_packet( f"MultiMemRead:ranges:{mem_address:x},2,{mem_address+2:x},4;" ) self.assertEqual(reply, "2,4;abcdef") reply = self.send_process_packet( f"MultiMemRead:ranges:{mem_address:x},2,{mem_address+2:x},4,{mem_address+6:x},8;" ) self.assertEqual(reply, "2,4,8;abcdefghijklmn") # Test zero length in the middle. reply = self.send_process_packet( f"MultiMemRead:ranges:{mem_address:x},2,{mem_address+2:x},0,{mem_address+6:x},8;" ) self.assertEqual(reply, "2,0,8;abghijklmn") # Test zero length in the end. reply = self.send_process_packet( f"MultiMemRead:ranges:{mem_address:x},2,{mem_address+2:x},4,{mem_address+6:x},0;" ) self.assertEqual(reply, "2,4,0;abcdef")