199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest case for testing the gdbremote protocol. 399451b44SJordan Rupprecht 499451b44SJordan RupprechtTests run against debugserver and lldb-server (llgs). 599451b44SJordan Rupprechtlldb-server tests run where the lldb-server exe is 699451b44SJordan Rupprechtavailable. 799451b44SJordan Rupprecht 899451b44SJordan RupprechtThis class will be broken into smaller test case classes by 999451b44SJordan Rupprechtgdb remote packet functional areas. For now it contains 1099451b44SJordan Rupprechtthe initial set of tests implemented. 1199451b44SJordan Rupprecht""" 1299451b44SJordan Rupprecht 136ba3f723SMichał Górnyimport binascii 146ba3f723SMichał Górnyimport itertools 151e74e5e9SMichał Górnyimport struct 166ba3f723SMichał Górny 1799451b44SJordan Rupprechtimport gdbremote_testcase 1899451b44SJordan Rupprechtimport lldbgdbserverutils 1999451b44SJordan Rupprechtfrom lldbsuite.support import seven 2099451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 2199451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 2299451b44SJordan Rupprechtfrom lldbsuite.test.lldbdwarf import * 23ca7824c2SMichał Górnyfrom lldbsuite.test import lldbutil, lldbplatformutil 2499451b44SJordan Rupprecht 2599451b44SJordan Rupprecht 262238dcc3SJonas Devlieghereclass LldbGdbServerTestCase( 272238dcc3SJonas Devlieghere gdbremote_testcase.GdbRemoteTestCaseBase, DwarfOpcodeParser 282238dcc3SJonas Devlieghere): 29a0b68a29SPavel Labath def test_thread_suffix_supported(self): 3099451b44SJordan Rupprecht server = self.connect_to_debug_monitor() 3199451b44SJordan Rupprecht self.assertIsNotNone(server) 3299451b44SJordan Rupprecht 33872b1da6SPavel Labath self.do_handshake() 3499451b44SJordan Rupprecht self.test_sequence.add_log_lines( 352238dcc3SJonas Devlieghere [ 362238dcc3SJonas Devlieghere "lldb-server < 26> read packet: $QThreadSuffixSupported#e4", 372238dcc3SJonas Devlieghere "lldb-server < 6> send packet: $OK#9a", 382238dcc3SJonas Devlieghere ], 392238dcc3SJonas Devlieghere True, 402238dcc3SJonas Devlieghere ) 4199451b44SJordan Rupprecht 4299451b44SJordan Rupprecht self.expect_gdbremote_sequence() 4399451b44SJordan Rupprecht 44a0b68a29SPavel Labath def test_list_threads_in_stop_reply_supported(self): 4599451b44SJordan Rupprecht server = self.connect_to_debug_monitor() 4699451b44SJordan Rupprecht self.assertIsNotNone(server) 4799451b44SJordan Rupprecht 48872b1da6SPavel Labath self.do_handshake() 4999451b44SJordan Rupprecht self.test_sequence.add_log_lines( 502238dcc3SJonas Devlieghere [ 512238dcc3SJonas Devlieghere "lldb-server < 27> read packet: $QListThreadsInStopReply#21", 522238dcc3SJonas Devlieghere "lldb-server < 6> send packet: $OK#9a", 532238dcc3SJonas Devlieghere ], 542238dcc3SJonas Devlieghere True, 552238dcc3SJonas Devlieghere ) 5699451b44SJordan Rupprecht self.expect_gdbremote_sequence() 5799451b44SJordan Rupprecht 58a0b68a29SPavel Labath def test_c_packet_works(self): 59a0b68a29SPavel Labath self.build() 60174b09e9SPavel Labath procs = self.prep_debug_monitor_and_inferior() 6199451b44SJordan Rupprecht self.test_sequence.add_log_lines( 622238dcc3SJonas Devlieghere ["read packet: $c#63", "send packet: $W00#00"], True 632238dcc3SJonas Devlieghere ) 6499451b44SJordan Rupprecht 6599451b44SJordan Rupprecht self.expect_gdbremote_sequence() 6699451b44SJordan Rupprecht 67a0b68a29SPavel Labath @skipIfWindows # No pty support to test any inferior output 68a0b68a29SPavel Labath def test_inferior_print_exit(self): 6999451b44SJordan Rupprecht self.build() 702238dcc3SJonas Devlieghere procs = self.prep_debug_monitor_and_inferior(inferior_args=["hello, world"]) 7199451b44SJordan Rupprecht self.test_sequence.add_log_lines( 722238dcc3SJonas Devlieghere [ 732238dcc3SJonas Devlieghere "read packet: $vCont;c#a8", 742238dcc3SJonas Devlieghere { 752238dcc3SJonas Devlieghere "type": "output_match", 762238dcc3SJonas Devlieghere "regex": self.maybe_strict_output_regex(r"hello, world\r\n"), 772238dcc3SJonas Devlieghere }, 782238dcc3SJonas Devlieghere "send packet: $W00#00", 792238dcc3SJonas Devlieghere ], 802238dcc3SJonas Devlieghere True, 812238dcc3SJonas Devlieghere ) 8299451b44SJordan Rupprecht 8399451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 8499451b44SJordan Rupprecht self.assertIsNotNone(context) 8599451b44SJordan Rupprecht 86a0b68a29SPavel Labath def test_first_launch_stop_reply_thread_matches_first_qC(self): 8799451b44SJordan Rupprecht self.build() 88174b09e9SPavel Labath procs = self.prep_debug_monitor_and_inferior() 892238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 902238dcc3SJonas Devlieghere [ 912238dcc3SJonas Devlieghere "read packet: $qC#00", 922238dcc3SJonas Devlieghere { 932238dcc3SJonas Devlieghere "direction": "send", 9499451b44SJordan Rupprecht "regex": r"^\$QC([0-9a-fA-F]+)#", 952238dcc3SJonas Devlieghere "capture": {1: "thread_id_QC"}, 962238dcc3SJonas Devlieghere }, 9799451b44SJordan Rupprecht "read packet: $?#00", 982238dcc3SJonas Devlieghere { 992238dcc3SJonas Devlieghere "direction": "send", 10099451b44SJordan Rupprecht "regex": r"^\$T[0-9a-fA-F]{2}thread:([0-9a-fA-F]+)", 1012238dcc3SJonas Devlieghere "capture": {1: "thread_id_?"}, 1022238dcc3SJonas Devlieghere }, 1032238dcc3SJonas Devlieghere ], 1042238dcc3SJonas Devlieghere True, 1052238dcc3SJonas Devlieghere ) 106ded66049SPavel Labath context = self.expect_gdbremote_sequence() 107ded66049SPavel Labath self.assertEqual(context.get("thread_id_QC"), context.get("thread_id_?")) 10899451b44SJordan Rupprecht 109a0b68a29SPavel Labath def test_attach_commandline_continue_app_exits(self): 11099451b44SJordan Rupprecht self.build() 111a0b68a29SPavel Labath self.set_inferior_startup_attach() 11299451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior() 11399451b44SJordan Rupprecht self.test_sequence.add_log_lines( 1142238dcc3SJonas Devlieghere ["read packet: $vCont;c#a8", "send packet: $W00#00"], True 1152238dcc3SJonas Devlieghere ) 11699451b44SJordan Rupprecht self.expect_gdbremote_sequence() 11799451b44SJordan Rupprecht 11899451b44SJordan Rupprecht # Wait a moment for completed and now-detached inferior process to 11999451b44SJordan Rupprecht # clear. 12099451b44SJordan Rupprecht time.sleep(1) 12199451b44SJordan Rupprecht 12299451b44SJordan Rupprecht if not lldb.remote_platform: 12399451b44SJordan Rupprecht # Process should be dead now. Reap results. 12499451b44SJordan Rupprecht poll_result = procs["inferior"].poll() 12599451b44SJordan Rupprecht self.assertIsNotNone(poll_result) 12699451b44SJordan Rupprecht 12799451b44SJordan Rupprecht # Where possible, verify at the system level that the process is not 12899451b44SJordan Rupprecht # running. 12999451b44SJordan Rupprecht self.assertFalse( 1302238dcc3SJonas Devlieghere lldbgdbserverutils.process_is_running(procs["inferior"].pid, False) 1312238dcc3SJonas Devlieghere ) 13299451b44SJordan Rupprecht 133a0b68a29SPavel Labath def test_qRegisterInfo_returns_one_valid_result(self): 13499451b44SJordan Rupprecht self.build() 135174b09e9SPavel Labath self.prep_debug_monitor_and_inferior() 13699451b44SJordan Rupprecht self.test_sequence.add_log_lines( 1372238dcc3SJonas Devlieghere [ 1382238dcc3SJonas Devlieghere "read packet: $qRegisterInfo0#00", 1392238dcc3SJonas Devlieghere { 1402238dcc3SJonas Devlieghere "direction": "send", 1412238dcc3SJonas Devlieghere "regex": r"^\$(.+);#[0-9A-Fa-f]{2}", 1422238dcc3SJonas Devlieghere "capture": {1: "reginfo_0"}, 1432238dcc3SJonas Devlieghere }, 1442238dcc3SJonas Devlieghere ], 1452238dcc3SJonas Devlieghere True, 1462238dcc3SJonas Devlieghere ) 14799451b44SJordan Rupprecht 14899451b44SJordan Rupprecht # Run the stream 14999451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 15099451b44SJordan Rupprecht self.assertIsNotNone(context) 15199451b44SJordan Rupprecht 15299451b44SJordan Rupprecht reg_info_packet = context.get("reginfo_0") 15399451b44SJordan Rupprecht self.assertIsNotNone(reg_info_packet) 15499451b44SJordan Rupprecht self.assert_valid_reg_info( 1552238dcc3SJonas Devlieghere lldbgdbserverutils.parse_reg_info_response(reg_info_packet) 1562238dcc3SJonas Devlieghere ) 15799451b44SJordan Rupprecht 158a0b68a29SPavel Labath def test_qRegisterInfo_returns_all_valid_results(self): 15999451b44SJordan Rupprecht self.build() 160174b09e9SPavel Labath self.prep_debug_monitor_and_inferior() 16199451b44SJordan Rupprecht self.add_register_info_collection_packets() 16299451b44SJordan Rupprecht 16399451b44SJordan Rupprecht # Run the stream. 16499451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 16599451b44SJordan Rupprecht self.assertIsNotNone(context) 16699451b44SJordan Rupprecht 16799451b44SJordan Rupprecht # Validate that each register info returned validates. 16899451b44SJordan Rupprecht for reg_info in self.parse_register_info_packets(context): 16999451b44SJordan Rupprecht self.assert_valid_reg_info(reg_info) 17099451b44SJordan Rupprecht 171a0b68a29SPavel Labath def test_qRegisterInfo_contains_required_generics_debugserver(self): 17299451b44SJordan Rupprecht self.build() 173174b09e9SPavel Labath self.prep_debug_monitor_and_inferior() 17499451b44SJordan Rupprecht self.add_register_info_collection_packets() 17599451b44SJordan Rupprecht 17699451b44SJordan Rupprecht # Run the packet stream. 17799451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 17899451b44SJordan Rupprecht self.assertIsNotNone(context) 17999451b44SJordan Rupprecht 18099451b44SJordan Rupprecht # Gather register info entries. 18199451b44SJordan Rupprecht reg_infos = self.parse_register_info_packets(context) 18299451b44SJordan Rupprecht 18399451b44SJordan Rupprecht # Collect all generic registers found. 18499451b44SJordan Rupprecht generic_regs = { 1852238dcc3SJonas Devlieghere reg_info["generic"]: 1 for reg_info in reg_infos if "generic" in reg_info 1862238dcc3SJonas Devlieghere } 18799451b44SJordan Rupprecht 18899451b44SJordan Rupprecht # Ensure we have a program counter register. 1892238dcc3SJonas Devlieghere self.assertIn("pc", generic_regs) 19099451b44SJordan Rupprecht 19199451b44SJordan Rupprecht # Ensure we have a frame pointer register. PPC64le's FP is the same as SP 1922238dcc3SJonas Devlieghere if self.getArchitecture() != "powerpc64le": 1932238dcc3SJonas Devlieghere self.assertIn("fp", generic_regs) 19499451b44SJordan Rupprecht 19599451b44SJordan Rupprecht # Ensure we have a stack pointer register. 1962238dcc3SJonas Devlieghere self.assertIn("sp", generic_regs) 19799451b44SJordan Rupprecht 19899451b44SJordan Rupprecht # Ensure we have a flags register. 1992238dcc3SJonas Devlieghere self.assertIn("flags", generic_regs) 20099451b44SJordan Rupprecht 201a0b68a29SPavel Labath def test_qRegisterInfo_contains_at_least_one_register_set(self): 20299451b44SJordan Rupprecht self.build() 203174b09e9SPavel Labath self.prep_debug_monitor_and_inferior() 20499451b44SJordan Rupprecht self.add_register_info_collection_packets() 20599451b44SJordan Rupprecht 20699451b44SJordan Rupprecht # Run the packet stream. 20799451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 20899451b44SJordan Rupprecht self.assertIsNotNone(context) 20999451b44SJordan Rupprecht 21099451b44SJordan Rupprecht # Gather register info entries. 21199451b44SJordan Rupprecht reg_infos = self.parse_register_info_packets(context) 21299451b44SJordan Rupprecht 21399451b44SJordan Rupprecht # Collect all register sets found. 21499451b44SJordan Rupprecht register_sets = { 2152238dcc3SJonas Devlieghere reg_info["set"]: 1 for reg_info in reg_infos if "set" in reg_info 2162238dcc3SJonas Devlieghere } 2179c246882SJordan Rupprecht self.assertGreaterEqual(len(register_sets), 1) 21899451b44SJordan Rupprecht 21999451b44SJordan Rupprecht def targetHasAVX(self): 22099451b44SJordan Rupprecht triple = self.dbg.GetSelectedPlatform().GetTriple() 22199451b44SJordan Rupprecht 22299451b44SJordan Rupprecht # TODO other platforms, please implement this function 22399451b44SJordan Rupprecht if not re.match(".*-.*-linux", triple): 22499451b44SJordan Rupprecht return True 22599451b44SJordan Rupprecht 22699451b44SJordan Rupprecht # Need to do something different for non-Linux/Android targets 22799451b44SJordan Rupprecht if lldb.remote_platform: 22899451b44SJordan Rupprecht self.runCmd('platform get-file "/proc/cpuinfo" "cpuinfo"') 22999451b44SJordan Rupprecht cpuinfo_path = "cpuinfo" 23099451b44SJordan Rupprecht self.addTearDownHook(lambda: os.unlink("cpuinfo")) 23199451b44SJordan Rupprecht else: 23299451b44SJordan Rupprecht cpuinfo_path = "/proc/cpuinfo" 23399451b44SJordan Rupprecht 2342238dcc3SJonas Devlieghere f = open(cpuinfo_path, "r") 23599451b44SJordan Rupprecht cpuinfo = f.read() 23699451b44SJordan Rupprecht f.close() 23799451b44SJordan Rupprecht return " avx " in cpuinfo 23899451b44SJordan Rupprecht 239a0b68a29SPavel Labath @expectedFailureAll(oslist=["windows"]) # no avx for now. 2402238dcc3SJonas Devlieghere @skipIf(archs=no_match(["amd64", "i386", "x86_64"])) 241a0b68a29SPavel Labath @add_test_categories(["llgs"]) 242a0b68a29SPavel Labath def test_qRegisterInfo_contains_avx_registers(self): 243a0b68a29SPavel Labath self.build() 244174b09e9SPavel Labath self.prep_debug_monitor_and_inferior() 24599451b44SJordan Rupprecht self.add_register_info_collection_packets() 24699451b44SJordan Rupprecht 24799451b44SJordan Rupprecht # Run the packet stream. 24899451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 24999451b44SJordan Rupprecht self.assertIsNotNone(context) 25099451b44SJordan Rupprecht 25199451b44SJordan Rupprecht # Gather register info entries. 25299451b44SJordan Rupprecht reg_infos = self.parse_register_info_packets(context) 25399451b44SJordan Rupprecht 25499451b44SJordan Rupprecht # Collect all generics found. 25599451b44SJordan Rupprecht register_sets = { 2562238dcc3SJonas Devlieghere reg_info["set"]: 1 for reg_info in reg_infos if "set" in reg_info 2572238dcc3SJonas Devlieghere } 25899451b44SJordan Rupprecht self.assertEqual( 2592238dcc3SJonas Devlieghere self.targetHasAVX(), "Advanced Vector Extensions" in register_sets 2602238dcc3SJonas Devlieghere ) 26199451b44SJordan Rupprecht 26299451b44SJordan Rupprecht def qThreadInfo_contains_thread(self): 26399451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior() 26499451b44SJordan Rupprecht self.add_threadinfo_collection_packets() 26599451b44SJordan Rupprecht 26699451b44SJordan Rupprecht # Run the packet stream. 26799451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 26899451b44SJordan Rupprecht self.assertIsNotNone(context) 26999451b44SJordan Rupprecht 27099451b44SJordan Rupprecht # Gather threadinfo entries. 27199451b44SJordan Rupprecht threads = self.parse_threadinfo_packets(context) 27299451b44SJordan Rupprecht self.assertIsNotNone(threads) 27399451b44SJordan Rupprecht 27499451b44SJordan Rupprecht # We should have exactly one thread. 27599451b44SJordan Rupprecht self.assertEqual(len(threads), 1) 27699451b44SJordan Rupprecht 277a0b68a29SPavel Labath def test_qThreadInfo_contains_thread_launch(self): 27899451b44SJordan Rupprecht self.build() 27999451b44SJordan Rupprecht self.set_inferior_startup_launch() 28099451b44SJordan Rupprecht self.qThreadInfo_contains_thread() 28199451b44SJordan Rupprecht 28299451b44SJordan Rupprecht @expectedFailureAll(oslist=["windows"]) # expect one more thread stopped 283a0b68a29SPavel Labath def test_qThreadInfo_contains_thread_attach(self): 28499451b44SJordan Rupprecht self.build() 28599451b44SJordan Rupprecht self.set_inferior_startup_attach() 28699451b44SJordan Rupprecht self.qThreadInfo_contains_thread() 28799451b44SJordan Rupprecht 28899451b44SJordan Rupprecht def qThreadInfo_matches_qC(self): 28999451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior() 29099451b44SJordan Rupprecht 29199451b44SJordan Rupprecht self.add_threadinfo_collection_packets() 29299451b44SJordan Rupprecht self.test_sequence.add_log_lines( 2932238dcc3SJonas Devlieghere [ 2942238dcc3SJonas Devlieghere "read packet: $qC#00", 2952238dcc3SJonas Devlieghere { 2962238dcc3SJonas Devlieghere "direction": "send", 2972238dcc3SJonas Devlieghere "regex": r"^\$QC([0-9a-fA-F]+)#", 2982238dcc3SJonas Devlieghere "capture": {1: "thread_id"}, 2992238dcc3SJonas Devlieghere }, 3002238dcc3SJonas Devlieghere ], 3012238dcc3SJonas Devlieghere True, 3022238dcc3SJonas Devlieghere ) 30399451b44SJordan Rupprecht 30499451b44SJordan Rupprecht # Run the packet stream. 30599451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 30699451b44SJordan Rupprecht self.assertIsNotNone(context) 30799451b44SJordan Rupprecht 30899451b44SJordan Rupprecht # Gather threadinfo entries. 30999451b44SJordan Rupprecht threads = self.parse_threadinfo_packets(context) 31099451b44SJordan Rupprecht self.assertIsNotNone(threads) 31199451b44SJordan Rupprecht 31299451b44SJordan Rupprecht # We should have exactly one thread from threadinfo. 31399451b44SJordan Rupprecht self.assertEqual(len(threads), 1) 31499451b44SJordan Rupprecht 31599451b44SJordan Rupprecht # We should have a valid thread_id from $QC. 31699451b44SJordan Rupprecht QC_thread_id_hex = context.get("thread_id") 31799451b44SJordan Rupprecht self.assertIsNotNone(QC_thread_id_hex) 31899451b44SJordan Rupprecht QC_thread_id = int(QC_thread_id_hex, 16) 31999451b44SJordan Rupprecht 32099451b44SJordan Rupprecht # Those two should be the same. 32199451b44SJordan Rupprecht self.assertEqual(threads[0], QC_thread_id) 32299451b44SJordan Rupprecht 323a0b68a29SPavel Labath def test_qThreadInfo_matches_qC_launch(self): 32499451b44SJordan Rupprecht self.build() 32599451b44SJordan Rupprecht self.set_inferior_startup_launch() 32699451b44SJordan Rupprecht self.qThreadInfo_matches_qC() 32799451b44SJordan Rupprecht 32899451b44SJordan Rupprecht @expectedFailureAll(oslist=["windows"]) # expect one more thread stopped 329a0b68a29SPavel Labath def test_qThreadInfo_matches_qC_attach(self): 33099451b44SJordan Rupprecht self.build() 33199451b44SJordan Rupprecht self.set_inferior_startup_attach() 33299451b44SJordan Rupprecht self.qThreadInfo_matches_qC() 33399451b44SJordan Rupprecht 334a0b68a29SPavel Labath def test_p_returns_correct_data_size_for_each_qRegisterInfo_launch(self): 335a0b68a29SPavel Labath self.build() 336a0b68a29SPavel Labath self.set_inferior_startup_launch() 33799451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior() 33899451b44SJordan Rupprecht self.add_register_info_collection_packets() 33999451b44SJordan Rupprecht 34099451b44SJordan Rupprecht # Run the packet stream. 34199451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 34299451b44SJordan Rupprecht self.assertIsNotNone(context) 34399451b44SJordan Rupprecht 34499451b44SJordan Rupprecht # Gather register info entries. 34599451b44SJordan Rupprecht reg_infos = self.parse_register_info_packets(context) 34699451b44SJordan Rupprecht self.assertIsNotNone(reg_infos) 3479c246882SJordan Rupprecht self.assertGreater(len(reg_infos), 0) 34899451b44SJordan Rupprecht 34999451b44SJordan Rupprecht byte_order = self.get_target_byte_order() 35099451b44SJordan Rupprecht 35199451b44SJordan Rupprecht # Read value for each register. 35299451b44SJordan Rupprecht reg_index = 0 35399451b44SJordan Rupprecht for reg_info in reg_infos: 35499451b44SJordan Rupprecht # Skip registers that don't have a register set. For x86, these are 35599451b44SJordan Rupprecht # the DRx registers, which have no LLDB-kind register number and thus 35699451b44SJordan Rupprecht # cannot be read via normal 35799451b44SJordan Rupprecht # NativeRegisterContext::ReadRegister(reg_info,...) calls. 35899451b44SJordan Rupprecht if not "set" in reg_info: 35999451b44SJordan Rupprecht continue 36099451b44SJordan Rupprecht 36199451b44SJordan Rupprecht # Clear existing packet expectations. 36299451b44SJordan Rupprecht self.reset_test_sequence() 36399451b44SJordan Rupprecht 36499451b44SJordan Rupprecht # Run the register query 36599451b44SJordan Rupprecht self.test_sequence.add_log_lines( 3662238dcc3SJonas Devlieghere [ 3672238dcc3SJonas Devlieghere "read packet: $p{0:x}#00".format(reg_index), 3682238dcc3SJonas Devlieghere { 3692238dcc3SJonas Devlieghere "direction": "send", 3702238dcc3SJonas Devlieghere "regex": r"^\$([0-9a-fA-F]+)#", 3712238dcc3SJonas Devlieghere "capture": {1: "p_response"}, 3722238dcc3SJonas Devlieghere }, 3732238dcc3SJonas Devlieghere ], 3742238dcc3SJonas Devlieghere True, 3752238dcc3SJonas Devlieghere ) 37699451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 37799451b44SJordan Rupprecht self.assertIsNotNone(context) 37899451b44SJordan Rupprecht 37999451b44SJordan Rupprecht # Verify the response length. 38099451b44SJordan Rupprecht p_response = context.get("p_response") 38199451b44SJordan Rupprecht self.assertIsNotNone(p_response) 38299451b44SJordan Rupprecht 3839367b57dSMichał Górny # Skip erraneous (unsupported) registers. 3849367b57dSMichał Górny # TODO: remove this once we make unsupported registers disappear. 3859367b57dSMichał Górny if p_response.startswith("E") and len(p_response) == 3: 3869367b57dSMichał Górny continue 3879367b57dSMichał Górny 38899451b44SJordan Rupprecht if "dynamic_size_dwarf_expr_bytes" in reg_info: 38999451b44SJordan Rupprecht self.updateRegInfoBitsize(reg_info, byte_order) 3902238dcc3SJonas Devlieghere self.assertEqual( 3912238dcc3SJonas Devlieghere len(p_response), 2 * int(reg_info["bitsize"]) / 8, reg_info 3922238dcc3SJonas Devlieghere ) 39399451b44SJordan Rupprecht 39499451b44SJordan Rupprecht # Increment loop 39599451b44SJordan Rupprecht reg_index += 1 39699451b44SJordan Rupprecht 3976c1a8039SMichał Górny def Hg_switches_to_3_threads(self, pass_pid=False): 3985a4fe166SPavel Labath _, threads = self.launch_with_threads(3) 39999451b44SJordan Rupprecht 4006c1a8039SMichał Górny pid_str = "" 4016c1a8039SMichał Górny if pass_pid: 4026c1a8039SMichał Górny pid_str = "p{0:x}.".format(procs["inferior"].pid) 4036c1a8039SMichał Górny 40499451b44SJordan Rupprecht # verify we can $H to each thead, and $qC matches the thread we set. 40599451b44SJordan Rupprecht for thread in threads: 40699451b44SJordan Rupprecht # Change to each thread, verify current thread id. 40799451b44SJordan Rupprecht self.reset_test_sequence() 40899451b44SJordan Rupprecht self.test_sequence.add_log_lines( 4092238dcc3SJonas Devlieghere [ 4102238dcc3SJonas Devlieghere "read packet: $Hg{0}{1:x}#00".format( 4112238dcc3SJonas Devlieghere pid_str, thread 4122238dcc3SJonas Devlieghere ), # Set current thread. 41399451b44SJordan Rupprecht "send packet: $OK#00", 41499451b44SJordan Rupprecht "read packet: $qC#00", 4152238dcc3SJonas Devlieghere { 4162238dcc3SJonas Devlieghere "direction": "send", 4172238dcc3SJonas Devlieghere "regex": r"^\$QC([0-9a-fA-F]+)#", 4182238dcc3SJonas Devlieghere "capture": {1: "thread_id"}, 4192238dcc3SJonas Devlieghere }, 4202238dcc3SJonas Devlieghere ], 4212238dcc3SJonas Devlieghere True, 4222238dcc3SJonas Devlieghere ) 42399451b44SJordan Rupprecht 42499451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 42599451b44SJordan Rupprecht self.assertIsNotNone(context) 42699451b44SJordan Rupprecht 42799451b44SJordan Rupprecht # Verify the thread id. 42899451b44SJordan Rupprecht self.assertIsNotNone(context.get("thread_id")) 42999451b44SJordan Rupprecht self.assertEqual(int(context.get("thread_id"), 16), thread) 43099451b44SJordan Rupprecht 4312238dcc3SJonas Devlieghere @skipIf(compiler="clang", compiler_version=["<", "11.0"]) 432a0b68a29SPavel Labath def test_Hg_switches_to_3_threads_launch(self): 43399451b44SJordan Rupprecht self.build() 43499451b44SJordan Rupprecht self.set_inferior_startup_launch() 43599451b44SJordan Rupprecht self.Hg_switches_to_3_threads() 43699451b44SJordan Rupprecht 4376c1a8039SMichał Górny def Hg_fails_on_pid(self, pass_pid): 4385a4fe166SPavel Labath _, threads = self.launch_with_threads(2) 4396c1a8039SMichał Górny 4406c1a8039SMichał Górny if pass_pid == -1: 4416c1a8039SMichał Górny pid_str = "p-1." 4426c1a8039SMichał Górny else: 4436c1a8039SMichał Górny pid_str = "p{0:x}.".format(pass_pid) 4446c1a8039SMichał Górny thread = threads[1] 4456c1a8039SMichał Górny 4466c1a8039SMichał Górny self.test_sequence.add_log_lines( 4472238dcc3SJonas Devlieghere [ 4482238dcc3SJonas Devlieghere "read packet: $Hg{0}{1:x}#00".format( 4492238dcc3SJonas Devlieghere pid_str, thread 4502238dcc3SJonas Devlieghere ), # Set current thread. 4512238dcc3SJonas Devlieghere "send packet: $Eff#00", 4522238dcc3SJonas Devlieghere ], 4532238dcc3SJonas Devlieghere True, 4542238dcc3SJonas Devlieghere ) 4556c1a8039SMichał Górny 4566c1a8039SMichał Górny self.expect_gdbremote_sequence() 4576c1a8039SMichał Górny 458fcea4181SMichał Górny @add_test_categories(["llgs"]) 4596c1a8039SMichał Górny def test_Hg_fails_on_another_pid(self): 4606c1a8039SMichał Górny self.build() 4616c1a8039SMichał Górny self.set_inferior_startup_launch() 4626c1a8039SMichał Górny self.Hg_fails_on_pid(1) 4636c1a8039SMichał Górny 464fcea4181SMichał Górny @add_test_categories(["llgs"]) 4656c1a8039SMichał Górny def test_Hg_fails_on_zero_pid(self): 4666c1a8039SMichał Górny self.build() 4676c1a8039SMichał Górny self.set_inferior_startup_launch() 4686c1a8039SMichał Górny self.Hg_fails_on_pid(0) 4696c1a8039SMichał Górny 470fcea4181SMichał Górny @add_test_categories(["llgs"]) 471*5a658ee9SDavid Spickett @skipIfWindows # Sometimes returns '$E37'. 4726c1a8039SMichał Górny def test_Hg_fails_on_minus_one_pid(self): 4736c1a8039SMichał Górny self.build() 4746c1a8039SMichał Górny self.set_inferior_startup_launch() 4756c1a8039SMichał Górny self.Hg_fails_on_pid(-1) 4766c1a8039SMichał Górny 47799451b44SJordan Rupprecht def Hc_then_Csignal_signals_correct_thread(self, segfault_signo): 47899451b44SJordan Rupprecht # NOTE only run this one in inferior-launched mode: we can't grab inferior stdout when running attached, 47999451b44SJordan Rupprecht # and the test requires getting stdout from the exe. 48099451b44SJordan Rupprecht 48199451b44SJordan Rupprecht NUM_THREADS = 3 48299451b44SJordan Rupprecht 48399451b44SJordan Rupprecht # Startup the inferior with three threads (main + NUM_THREADS-1 worker threads). 48499451b44SJordan Rupprecht # inferior_args=["thread:print-ids"] 48599451b44SJordan Rupprecht inferior_args = ["thread:segfault"] 48699451b44SJordan Rupprecht for i in range(NUM_THREADS - 1): 48799451b44SJordan Rupprecht # if i > 0: 48899451b44SJordan Rupprecht # Give time between thread creation/segfaulting for the handler to work. 48999451b44SJordan Rupprecht # inferior_args.append("sleep:1") 49099451b44SJordan Rupprecht inferior_args.append("thread:new") 49199451b44SJordan Rupprecht inferior_args.append("sleep:10") 49299451b44SJordan Rupprecht 49399451b44SJordan Rupprecht # Launch/attach. (In our case, this should only ever be launched since 49499451b44SJordan Rupprecht # we need inferior stdout/stderr). 4952238dcc3SJonas Devlieghere procs = self.prep_debug_monitor_and_inferior(inferior_args=inferior_args) 49699451b44SJordan Rupprecht self.test_sequence.add_log_lines(["read packet: $c#63"], True) 49799451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 49899451b44SJordan Rupprecht 49999451b44SJordan Rupprecht signaled_tids = {} 50099451b44SJordan Rupprecht print_thread_ids = {} 50199451b44SJordan Rupprecht 50299451b44SJordan Rupprecht # Switch to each thread, deliver a signal, and verify signal delivery 50399451b44SJordan Rupprecht for i in range(NUM_THREADS - 1): 50499451b44SJordan Rupprecht # Run until SIGSEGV comes in. 50599451b44SJordan Rupprecht self.reset_test_sequence() 5062238dcc3SJonas Devlieghere self.test_sequence.add_log_lines( 5072238dcc3SJonas Devlieghere [ 5082238dcc3SJonas Devlieghere { 5092238dcc3SJonas Devlieghere "direction": "send", 51099451b44SJordan Rupprecht "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", 5112238dcc3SJonas Devlieghere "capture": {1: "signo", 2: "thread_id"}, 5122238dcc3SJonas Devlieghere } 5132238dcc3SJonas Devlieghere ], 5142238dcc3SJonas Devlieghere True, 5152238dcc3SJonas Devlieghere ) 51699451b44SJordan Rupprecht 5170fbbf3a9SJonas Devlieghere context = self.expect_gdbremote_sequence() 51899451b44SJordan Rupprecht self.assertIsNotNone(context) 51999451b44SJordan Rupprecht signo = context.get("signo") 52099451b44SJordan Rupprecht self.assertEqual(int(signo, 16), segfault_signo) 52199451b44SJordan Rupprecht 52299451b44SJordan Rupprecht # Ensure we haven't seen this tid yet. 52399451b44SJordan Rupprecht thread_id = int(context.get("thread_id"), 16) 5243cc37622SDave Lee self.assertNotIn(thread_id, signaled_tids) 52599451b44SJordan Rupprecht signaled_tids[thread_id] = 1 52699451b44SJordan Rupprecht 52799451b44SJordan Rupprecht # Send SIGUSR1 to the thread that signaled the SIGSEGV. 52899451b44SJordan Rupprecht self.reset_test_sequence() 52999451b44SJordan Rupprecht self.test_sequence.add_log_lines( 53099451b44SJordan Rupprecht [ 53199451b44SJordan Rupprecht # Set the continue thread. 53299451b44SJordan Rupprecht # Set current thread. 53399451b44SJordan Rupprecht "read packet: $Hc{0:x}#00".format(thread_id), 53499451b44SJordan Rupprecht "send packet: $OK#00", 53599451b44SJordan Rupprecht # Continue sending the signal number to the continue thread. 53699451b44SJordan Rupprecht # The commented out packet is a way to do this same operation without using 53799451b44SJordan Rupprecht # a $Hc (but this test is testing $Hc, so we'll stick with the former). 5382238dcc3SJonas Devlieghere "read packet: $C{0:x}#00".format( 5392238dcc3SJonas Devlieghere lldbutil.get_signal_number("SIGUSR1") 5402238dcc3SJonas Devlieghere ), 54199451b44SJordan Rupprecht # "read packet: $vCont;C{0:x}:{1:x};c#00".format(lldbutil.get_signal_number('SIGUSR1'), thread_id), 54299451b44SJordan Rupprecht # FIXME: Linux does not report the thread stop on the delivered signal (SIGUSR1 here). MacOSX debugserver does. 54399451b44SJordan Rupprecht # But MacOSX debugserver isn't guaranteeing the thread the signal handler runs on, so currently its an XFAIL. 54499451b44SJordan Rupprecht # Need to rectify behavior here. The linux behavior is more intuitive to me since we're essentially swapping out 54599451b44SJordan Rupprecht # an about-to-be-delivered signal (for which we already sent a stop packet) to a different signal. 54699451b44SJordan Rupprecht # {"direction":"send", "regex":r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", "capture":{1:"stop_signo", 2:"stop_thread_id"} }, 54799451b44SJordan Rupprecht # "read packet: $c#63", 5482238dcc3SJonas Devlieghere { 5492238dcc3SJonas Devlieghere "type": "output_match", 5502238dcc3SJonas Devlieghere "regex": r"^received SIGUSR1 on thread id: ([0-9a-fA-F]+)\r\nthread ([0-9a-fA-F]+): past SIGSEGV\r\n", 5512238dcc3SJonas Devlieghere "capture": {1: "print_thread_id", 2: "post_handle_thread_id"}, 5522238dcc3SJonas Devlieghere }, 55399451b44SJordan Rupprecht ], 5542238dcc3SJonas Devlieghere True, 5552238dcc3SJonas Devlieghere ) 55699451b44SJordan Rupprecht 55799451b44SJordan Rupprecht # Run the sequence. 5580fbbf3a9SJonas Devlieghere context = self.expect_gdbremote_sequence() 55999451b44SJordan Rupprecht self.assertIsNotNone(context) 56099451b44SJordan Rupprecht 56199451b44SJordan Rupprecht # Ensure the stop signal is the signal we delivered. 56299451b44SJordan Rupprecht # stop_signo = context.get("stop_signo") 56399451b44SJordan Rupprecht # self.assertIsNotNone(stop_signo) 56480fcecb1SJonas Devlieghere # self.assertEqual(int(stop_signo,16), lldbutil.get_signal_number('SIGUSR1')) 56599451b44SJordan Rupprecht 56699451b44SJordan Rupprecht # Ensure the stop thread is the thread to which we delivered the signal. 56799451b44SJordan Rupprecht # stop_thread_id = context.get("stop_thread_id") 56899451b44SJordan Rupprecht # self.assertIsNotNone(stop_thread_id) 56980fcecb1SJonas Devlieghere # self.assertEqual(int(stop_thread_id,16), thread_id) 57099451b44SJordan Rupprecht 57199451b44SJordan Rupprecht # Ensure we haven't seen this thread id yet. The inferior's 57299451b44SJordan Rupprecht # self-obtained thread ids are not guaranteed to match the stub 57399451b44SJordan Rupprecht # tids (at least on MacOSX). 57499451b44SJordan Rupprecht print_thread_id = context.get("print_thread_id") 57599451b44SJordan Rupprecht self.assertIsNotNone(print_thread_id) 57699451b44SJordan Rupprecht print_thread_id = int(print_thread_id, 16) 5773cc37622SDave Lee self.assertNotIn(print_thread_id, print_thread_ids) 57899451b44SJordan Rupprecht 57999451b44SJordan Rupprecht # Now remember this print (i.e. inferior-reflected) thread id and 58099451b44SJordan Rupprecht # ensure we don't hit it again. 58199451b44SJordan Rupprecht print_thread_ids[print_thread_id] = 1 58299451b44SJordan Rupprecht 58399451b44SJordan Rupprecht # Ensure post signal-handle thread id matches the thread that 58499451b44SJordan Rupprecht # initially raised the SIGSEGV. 58599451b44SJordan Rupprecht post_handle_thread_id = context.get("post_handle_thread_id") 58699451b44SJordan Rupprecht self.assertIsNotNone(post_handle_thread_id) 58799451b44SJordan Rupprecht post_handle_thread_id = int(post_handle_thread_id, 16) 58899451b44SJordan Rupprecht self.assertEqual(post_handle_thread_id, print_thread_id) 58999451b44SJordan Rupprecht 590d9ba8142SPavel Labath @expectedFailureDarwin 59199451b44SJordan Rupprecht @skipIfWindows # no SIGSEGV support 592266c90feSMichał Górny @expectedFailureNetBSD 593d9ba8142SPavel Labath def test_Hc_then_Csignal_signals_correct_thread_launch(self): 59499451b44SJordan Rupprecht self.build() 59599451b44SJordan Rupprecht self.set_inferior_startup_launch() 596d9ba8142SPavel Labath 597d9ba8142SPavel Labath if self.platformIsDarwin(): 598d9ba8142SPavel Labath # Darwin debugserver translates some signals like SIGSEGV into some gdb 599d9ba8142SPavel Labath # expectations about fixed signal numbers. 600d9ba8142SPavel Labath self.Hc_then_Csignal_signals_correct_thread(self.TARGET_EXC_BAD_ACCESS) 601d9ba8142SPavel Labath else: 60299451b44SJordan Rupprecht self.Hc_then_Csignal_signals_correct_thread( 6032238dcc3SJonas Devlieghere lldbutil.get_signal_number("SIGSEGV") 6042238dcc3SJonas Devlieghere ) 60599451b44SJordan Rupprecht 606d9ba8142SPavel Labath @skipIfWindows # No pty support to test any inferior output 607d9ba8142SPavel Labath def test_m_packet_reads_memory(self): 608d9ba8142SPavel Labath self.build() 609d9ba8142SPavel Labath self.set_inferior_startup_launch() 61099451b44SJordan Rupprecht # This is the memory we will write into the inferior and then ensure we 61199451b44SJordan Rupprecht # can read back with $m. 61299451b44SJordan Rupprecht MEMORY_CONTENTS = "Test contents 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz" 61399451b44SJordan Rupprecht 61499451b44SJordan Rupprecht # Start up the inferior. 61599451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior( 61699451b44SJordan Rupprecht inferior_args=[ 6172238dcc3SJonas Devlieghere "set-message:%s" % MEMORY_CONTENTS, 61899451b44SJordan Rupprecht "get-data-address-hex:g_message", 6192238dcc3SJonas Devlieghere "sleep:5", 6202238dcc3SJonas Devlieghere ] 6212238dcc3SJonas Devlieghere ) 62299451b44SJordan Rupprecht 62399451b44SJordan Rupprecht # Run the process 62499451b44SJordan Rupprecht self.test_sequence.add_log_lines( 62599451b44SJordan Rupprecht [ 62699451b44SJordan Rupprecht # Start running after initial stop. 62799451b44SJordan Rupprecht "read packet: $c#63", 62899451b44SJordan Rupprecht # Match output line that prints the memory address of the message buffer within the inferior. 62999451b44SJordan Rupprecht # Note we require launch-only testing so we can get inferior otuput. 6302238dcc3SJonas Devlieghere { 6312238dcc3SJonas Devlieghere "type": "output_match", 6322238dcc3SJonas Devlieghere "regex": self.maybe_strict_output_regex( 6332238dcc3SJonas Devlieghere r"data address: 0x([0-9a-fA-F]+)\r\n" 6342238dcc3SJonas Devlieghere ), 6352238dcc3SJonas Devlieghere "capture": {1: "message_address"}, 6362238dcc3SJonas Devlieghere }, 63799451b44SJordan Rupprecht # Now stop the inferior. 63899451b44SJordan Rupprecht "read packet: {}".format(chr(3)), 63999451b44SJordan Rupprecht # And wait for the stop notification. 6402238dcc3SJonas Devlieghere { 6412238dcc3SJonas Devlieghere "direction": "send", 6422238dcc3SJonas Devlieghere "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", 6432238dcc3SJonas Devlieghere "capture": {1: "stop_signo", 2: "stop_thread_id"}, 6442238dcc3SJonas Devlieghere }, 6452238dcc3SJonas Devlieghere ], 6462238dcc3SJonas Devlieghere True, 6472238dcc3SJonas Devlieghere ) 64899451b44SJordan Rupprecht 64999451b44SJordan Rupprecht # Run the packet stream. 65099451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 65199451b44SJordan Rupprecht self.assertIsNotNone(context) 65299451b44SJordan Rupprecht 65399451b44SJordan Rupprecht # Grab the message address. 65499451b44SJordan Rupprecht self.assertIsNotNone(context.get("message_address")) 65599451b44SJordan Rupprecht message_address = int(context.get("message_address"), 16) 65699451b44SJordan Rupprecht 65799451b44SJordan Rupprecht # Grab contents from the inferior. 65899451b44SJordan Rupprecht self.reset_test_sequence() 65999451b44SJordan Rupprecht self.test_sequence.add_log_lines( 6602238dcc3SJonas Devlieghere [ 6612238dcc3SJonas Devlieghere "read packet: $m{0:x},{1:x}#00".format( 6622238dcc3SJonas Devlieghere message_address, len(MEMORY_CONTENTS) 6632238dcc3SJonas Devlieghere ), 6642238dcc3SJonas Devlieghere { 6652238dcc3SJonas Devlieghere "direction": "send", 6662238dcc3SJonas Devlieghere "regex": r"^\$(.+)#[0-9a-fA-F]{2}$", 6672238dcc3SJonas Devlieghere "capture": {1: "read_contents"}, 6682238dcc3SJonas Devlieghere }, 6692238dcc3SJonas Devlieghere ], 6702238dcc3SJonas Devlieghere True, 6712238dcc3SJonas Devlieghere ) 67299451b44SJordan Rupprecht 67399451b44SJordan Rupprecht # Run the packet stream. 67499451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 67599451b44SJordan Rupprecht self.assertIsNotNone(context) 67699451b44SJordan Rupprecht 67799451b44SJordan Rupprecht # Ensure what we read from inferior memory is what we wrote. 67899451b44SJordan Rupprecht self.assertIsNotNone(context.get("read_contents")) 67999451b44SJordan Rupprecht read_contents = seven.unhexlify(context.get("read_contents")) 68099451b44SJordan Rupprecht self.assertEqual(read_contents, MEMORY_CONTENTS) 68199451b44SJordan Rupprecht 682d9ba8142SPavel Labath def test_qMemoryRegionInfo_is_supported(self): 68399451b44SJordan Rupprecht self.build() 68499451b44SJordan Rupprecht self.set_inferior_startup_launch() 68599451b44SJordan Rupprecht # Start up the inferior. 68699451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior() 68799451b44SJordan Rupprecht 68899451b44SJordan Rupprecht # Ask if it supports $qMemoryRegionInfo. 68999451b44SJordan Rupprecht self.test_sequence.add_log_lines( 6902238dcc3SJonas Devlieghere ["read packet: $qMemoryRegionInfo#00", "send packet: $OK#00"], True 6912238dcc3SJonas Devlieghere ) 69299451b44SJordan Rupprecht self.expect_gdbremote_sequence() 69399451b44SJordan Rupprecht 694d9ba8142SPavel Labath @skipIfWindows # No pty support to test any inferior output 695d9ba8142SPavel Labath def test_qMemoryRegionInfo_reports_code_address_as_executable(self): 69699451b44SJordan Rupprecht self.build() 69799451b44SJordan Rupprecht self.set_inferior_startup_launch() 69899451b44SJordan Rupprecht 69999451b44SJordan Rupprecht # Start up the inferior. 70099451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior( 7012238dcc3SJonas Devlieghere inferior_args=["get-code-address-hex:hello", "sleep:5"] 7022238dcc3SJonas Devlieghere ) 70399451b44SJordan Rupprecht 70499451b44SJordan Rupprecht # Run the process 70599451b44SJordan Rupprecht self.test_sequence.add_log_lines( 70699451b44SJordan Rupprecht [ 70799451b44SJordan Rupprecht # Start running after initial stop. 70899451b44SJordan Rupprecht "read packet: $c#63", 70999451b44SJordan Rupprecht # Match output line that prints the memory address of the message buffer within the inferior. 71099451b44SJordan Rupprecht # Note we require launch-only testing so we can get inferior otuput. 7112238dcc3SJonas Devlieghere { 7122238dcc3SJonas Devlieghere "type": "output_match", 7132238dcc3SJonas Devlieghere "regex": self.maybe_strict_output_regex( 7142238dcc3SJonas Devlieghere r"code address: 0x([0-9a-fA-F]+)\r\n" 7152238dcc3SJonas Devlieghere ), 7162238dcc3SJonas Devlieghere "capture": {1: "code_address"}, 7172238dcc3SJonas Devlieghere }, 71899451b44SJordan Rupprecht # Now stop the inferior. 71999451b44SJordan Rupprecht "read packet: {}".format(chr(3)), 72099451b44SJordan Rupprecht # And wait for the stop notification. 7212238dcc3SJonas Devlieghere { 7222238dcc3SJonas Devlieghere "direction": "send", 7232238dcc3SJonas Devlieghere "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", 7242238dcc3SJonas Devlieghere "capture": {1: "stop_signo", 2: "stop_thread_id"}, 7252238dcc3SJonas Devlieghere }, 7262238dcc3SJonas Devlieghere ], 7272238dcc3SJonas Devlieghere True, 7282238dcc3SJonas Devlieghere ) 72999451b44SJordan Rupprecht 73099451b44SJordan Rupprecht # Run the packet stream. 73199451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 73299451b44SJordan Rupprecht self.assertIsNotNone(context) 73399451b44SJordan Rupprecht 73499451b44SJordan Rupprecht # Grab the code address. 73599451b44SJordan Rupprecht self.assertIsNotNone(context.get("code_address")) 73699451b44SJordan Rupprecht code_address = int(context.get("code_address"), 16) 73799451b44SJordan Rupprecht 73899451b44SJordan Rupprecht # Grab memory region info from the inferior. 73999451b44SJordan Rupprecht self.reset_test_sequence() 74099451b44SJordan Rupprecht self.add_query_memory_region_packets(code_address) 74199451b44SJordan Rupprecht 74299451b44SJordan Rupprecht # Run the packet stream. 74399451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 74499451b44SJordan Rupprecht self.assertIsNotNone(context) 74599451b44SJordan Rupprecht mem_region_dict = self.parse_memory_region_packet(context) 74699451b44SJordan Rupprecht 74799451b44SJordan Rupprecht # Ensure there are no errors reported. 7483cc37622SDave Lee self.assertNotIn("error", mem_region_dict) 74999451b44SJordan Rupprecht 75099451b44SJordan Rupprecht # Ensure code address is readable and executable. 7513cc37622SDave Lee self.assertIn("permissions", mem_region_dict) 7523cc37622SDave Lee self.assertIn("r", mem_region_dict["permissions"]) 7533cc37622SDave Lee self.assertIn("x", mem_region_dict["permissions"]) 75499451b44SJordan Rupprecht 75599451b44SJordan Rupprecht # Ensure the start address and size encompass the address we queried. 75699451b44SJordan Rupprecht self.assert_address_within_memory_region(code_address, mem_region_dict) 75799451b44SJordan Rupprecht 75899451b44SJordan Rupprecht @skipIfWindows # No pty support to test any inferior output 759d9ba8142SPavel Labath def test_qMemoryRegionInfo_reports_stack_address_as_rw(self): 76099451b44SJordan Rupprecht self.build() 76199451b44SJordan Rupprecht self.set_inferior_startup_launch() 76299451b44SJordan Rupprecht 76399451b44SJordan Rupprecht # Start up the inferior. 76499451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior( 7652238dcc3SJonas Devlieghere inferior_args=["get-stack-address-hex:", "sleep:5"] 7662238dcc3SJonas Devlieghere ) 76799451b44SJordan Rupprecht 76899451b44SJordan Rupprecht # Run the process 76999451b44SJordan Rupprecht self.test_sequence.add_log_lines( 77099451b44SJordan Rupprecht [ 77199451b44SJordan Rupprecht # Start running after initial stop. 77299451b44SJordan Rupprecht "read packet: $c#63", 77399451b44SJordan Rupprecht # Match output line that prints the memory address of the message buffer within the inferior. 77499451b44SJordan Rupprecht # Note we require launch-only testing so we can get inferior otuput. 7752238dcc3SJonas Devlieghere { 7762238dcc3SJonas Devlieghere "type": "output_match", 7772238dcc3SJonas Devlieghere "regex": self.maybe_strict_output_regex( 7782238dcc3SJonas Devlieghere r"stack address: 0x([0-9a-fA-F]+)\r\n" 7792238dcc3SJonas Devlieghere ), 7802238dcc3SJonas Devlieghere "capture": {1: "stack_address"}, 7812238dcc3SJonas Devlieghere }, 78299451b44SJordan Rupprecht # Now stop the inferior. 78399451b44SJordan Rupprecht "read packet: {}".format(chr(3)), 78499451b44SJordan Rupprecht # And wait for the stop notification. 7852238dcc3SJonas Devlieghere { 7862238dcc3SJonas Devlieghere "direction": "send", 7872238dcc3SJonas Devlieghere "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", 7882238dcc3SJonas Devlieghere "capture": {1: "stop_signo", 2: "stop_thread_id"}, 7892238dcc3SJonas Devlieghere }, 7902238dcc3SJonas Devlieghere ], 7912238dcc3SJonas Devlieghere True, 7922238dcc3SJonas Devlieghere ) 79399451b44SJordan Rupprecht 79499451b44SJordan Rupprecht # Run the packet stream. 79599451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 79699451b44SJordan Rupprecht self.assertIsNotNone(context) 79799451b44SJordan Rupprecht 79899451b44SJordan Rupprecht # Grab the address. 79999451b44SJordan Rupprecht self.assertIsNotNone(context.get("stack_address")) 80099451b44SJordan Rupprecht stack_address = int(context.get("stack_address"), 16) 80199451b44SJordan Rupprecht 80299451b44SJordan Rupprecht # Grab memory region info from the inferior. 80399451b44SJordan Rupprecht self.reset_test_sequence() 80499451b44SJordan Rupprecht self.add_query_memory_region_packets(stack_address) 80599451b44SJordan Rupprecht 80699451b44SJordan Rupprecht # Run the packet stream. 80799451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 80899451b44SJordan Rupprecht self.assertIsNotNone(context) 80999451b44SJordan Rupprecht mem_region_dict = self.parse_memory_region_packet(context) 81099451b44SJordan Rupprecht 81199451b44SJordan Rupprecht # Ensure there are no errors reported. 8123cc37622SDave Lee self.assertNotIn("error", mem_region_dict) 81399451b44SJordan Rupprecht 81499451b44SJordan Rupprecht # Ensure address is readable and executable. 8153cc37622SDave Lee self.assertIn("permissions", mem_region_dict) 8163cc37622SDave Lee self.assertIn("r", mem_region_dict["permissions"]) 8173cc37622SDave Lee self.assertIn("w", mem_region_dict["permissions"]) 81899451b44SJordan Rupprecht 81999451b44SJordan Rupprecht # Ensure the start address and size encompass the address we queried. 8202238dcc3SJonas Devlieghere self.assert_address_within_memory_region(stack_address, mem_region_dict) 82199451b44SJordan Rupprecht 82299451b44SJordan Rupprecht @skipIfWindows # No pty support to test any inferior output 823d9ba8142SPavel Labath def test_qMemoryRegionInfo_reports_heap_address_as_rw(self): 82499451b44SJordan Rupprecht self.build() 82599451b44SJordan Rupprecht self.set_inferior_startup_launch() 82699451b44SJordan Rupprecht 82799451b44SJordan Rupprecht # Start up the inferior. 82899451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior( 8292238dcc3SJonas Devlieghere inferior_args=["get-heap-address-hex:", "sleep:5"] 8302238dcc3SJonas Devlieghere ) 83199451b44SJordan Rupprecht 83299451b44SJordan Rupprecht # Run the process 83399451b44SJordan Rupprecht self.test_sequence.add_log_lines( 83499451b44SJordan Rupprecht [ 83599451b44SJordan Rupprecht # Start running after initial stop. 83699451b44SJordan Rupprecht "read packet: $c#63", 83799451b44SJordan Rupprecht # Match output line that prints the memory address of the message buffer within the inferior. 83899451b44SJordan Rupprecht # Note we require launch-only testing so we can get inferior otuput. 8392238dcc3SJonas Devlieghere { 8402238dcc3SJonas Devlieghere "type": "output_match", 8412238dcc3SJonas Devlieghere "regex": self.maybe_strict_output_regex( 8422238dcc3SJonas Devlieghere r"heap address: 0x([0-9a-fA-F]+)\r\n" 8432238dcc3SJonas Devlieghere ), 8442238dcc3SJonas Devlieghere "capture": {1: "heap_address"}, 8452238dcc3SJonas Devlieghere }, 84699451b44SJordan Rupprecht # Now stop the inferior. 84799451b44SJordan Rupprecht "read packet: {}".format(chr(3)), 84899451b44SJordan Rupprecht # And wait for the stop notification. 8492238dcc3SJonas Devlieghere { 8502238dcc3SJonas Devlieghere "direction": "send", 8512238dcc3SJonas Devlieghere "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", 8522238dcc3SJonas Devlieghere "capture": {1: "stop_signo", 2: "stop_thread_id"}, 8532238dcc3SJonas Devlieghere }, 8542238dcc3SJonas Devlieghere ], 8552238dcc3SJonas Devlieghere True, 8562238dcc3SJonas Devlieghere ) 85799451b44SJordan Rupprecht 85899451b44SJordan Rupprecht # Run the packet stream. 85999451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 86099451b44SJordan Rupprecht self.assertIsNotNone(context) 86199451b44SJordan Rupprecht 86299451b44SJordan Rupprecht # Grab the address. 86399451b44SJordan Rupprecht self.assertIsNotNone(context.get("heap_address")) 86499451b44SJordan Rupprecht heap_address = int(context.get("heap_address"), 16) 86599451b44SJordan Rupprecht 86699451b44SJordan Rupprecht # Grab memory region info from the inferior. 86799451b44SJordan Rupprecht self.reset_test_sequence() 86899451b44SJordan Rupprecht self.add_query_memory_region_packets(heap_address) 86999451b44SJordan Rupprecht 87099451b44SJordan Rupprecht # Run the packet stream. 87199451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 87299451b44SJordan Rupprecht self.assertIsNotNone(context) 87399451b44SJordan Rupprecht mem_region_dict = self.parse_memory_region_packet(context) 87499451b44SJordan Rupprecht 87599451b44SJordan Rupprecht # Ensure there are no errors reported. 8763cc37622SDave Lee self.assertNotIn("error", mem_region_dict) 87799451b44SJordan Rupprecht 87899451b44SJordan Rupprecht # Ensure address is readable and executable. 8793cc37622SDave Lee self.assertIn("permissions", mem_region_dict) 8803cc37622SDave Lee self.assertIn("r", mem_region_dict["permissions"]) 8813cc37622SDave Lee self.assertIn("w", mem_region_dict["permissions"]) 88299451b44SJordan Rupprecht 88399451b44SJordan Rupprecht # Ensure the start address and size encompass the address we queried. 88499451b44SJordan Rupprecht self.assert_address_within_memory_region(heap_address, mem_region_dict) 88599451b44SJordan Rupprecht 886d9ba8142SPavel Labath def breakpoint_set_and_remove_work(self, want_hardware): 88799451b44SJordan Rupprecht # Start up the inferior. 88899451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior( 88999451b44SJordan Rupprecht inferior_args=[ 89099451b44SJordan Rupprecht "get-code-address-hex:hello", 89199451b44SJordan Rupprecht "sleep:1", 8922238dcc3SJonas Devlieghere "call-function:hello", 8932238dcc3SJonas Devlieghere ] 8942238dcc3SJonas Devlieghere ) 89599451b44SJordan Rupprecht 89699451b44SJordan Rupprecht # Run the process 89799451b44SJordan Rupprecht self.add_register_info_collection_packets() 89899451b44SJordan Rupprecht self.add_process_info_collection_packets() 89999451b44SJordan Rupprecht self.test_sequence.add_log_lines( 90099451b44SJordan Rupprecht [ # Start running after initial stop. 90199451b44SJordan Rupprecht "read packet: $c#63", 90299451b44SJordan Rupprecht # Match output line that prints the memory address of the function call entry point. 90399451b44SJordan Rupprecht # Note we require launch-only testing so we can get inferior otuput. 9042238dcc3SJonas Devlieghere { 9052238dcc3SJonas Devlieghere "type": "output_match", 9062238dcc3SJonas Devlieghere "regex": self.maybe_strict_output_regex( 9072238dcc3SJonas Devlieghere r"code address: 0x([0-9a-fA-F]+)\r\n" 9082238dcc3SJonas Devlieghere ), 9092238dcc3SJonas Devlieghere "capture": {1: "function_address"}, 9102238dcc3SJonas Devlieghere }, 91199451b44SJordan Rupprecht # Now stop the inferior. 91299451b44SJordan Rupprecht "read packet: {}".format(chr(3)), 91399451b44SJordan Rupprecht # And wait for the stop notification. 9142238dcc3SJonas Devlieghere { 9152238dcc3SJonas Devlieghere "direction": "send", 9162238dcc3SJonas Devlieghere "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", 9172238dcc3SJonas Devlieghere "capture": {1: "stop_signo", 2: "stop_thread_id"}, 9182238dcc3SJonas Devlieghere }, 9192238dcc3SJonas Devlieghere ], 9202238dcc3SJonas Devlieghere True, 9212238dcc3SJonas Devlieghere ) 92299451b44SJordan Rupprecht 92399451b44SJordan Rupprecht # Run the packet stream. 92499451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 92599451b44SJordan Rupprecht self.assertIsNotNone(context) 92699451b44SJordan Rupprecht 92799451b44SJordan Rupprecht # Gather process info - we need endian of target to handle register 92899451b44SJordan Rupprecht # value conversions. 92999451b44SJordan Rupprecht process_info = self.parse_process_info_response(context) 93099451b44SJordan Rupprecht endian = process_info.get("endian") 93199451b44SJordan Rupprecht self.assertIsNotNone(endian) 93299451b44SJordan Rupprecht 93399451b44SJordan Rupprecht # Gather register info entries. 93499451b44SJordan Rupprecht reg_infos = self.parse_register_info_packets(context) 93599451b44SJordan Rupprecht (pc_lldb_reg_index, pc_reg_info) = self.find_pc_reg_info(reg_infos) 93699451b44SJordan Rupprecht self.assertIsNotNone(pc_lldb_reg_index) 93799451b44SJordan Rupprecht self.assertIsNotNone(pc_reg_info) 93899451b44SJordan Rupprecht 93999451b44SJordan Rupprecht # Grab the function address. 94099451b44SJordan Rupprecht self.assertIsNotNone(context.get("function_address")) 94199451b44SJordan Rupprecht function_address = int(context.get("function_address"), 16) 94299451b44SJordan Rupprecht 94399451b44SJordan Rupprecht # Get current target architecture 94499451b44SJordan Rupprecht target_arch = self.getArchitecture() 94599451b44SJordan Rupprecht 94699451b44SJordan Rupprecht # Set the breakpoint. 947b9a30b69SJonas Devlieghere if target_arch in ["arm", "arm64", "aarch64"]: 94899451b44SJordan Rupprecht # TODO: Handle case when setting breakpoint in thumb code 94999451b44SJordan Rupprecht BREAKPOINT_KIND = 4 95099451b44SJordan Rupprecht else: 95199451b44SJordan Rupprecht BREAKPOINT_KIND = 1 95299451b44SJordan Rupprecht 95399451b44SJordan Rupprecht # Set default packet type to Z0 (software breakpoint) 95499451b44SJordan Rupprecht z_packet_type = 0 95599451b44SJordan Rupprecht 95699451b44SJordan Rupprecht # If hardware breakpoint is requested set packet type to Z1 957fd35a923SEisuke Kawashima if want_hardware: 95899451b44SJordan Rupprecht z_packet_type = 1 95999451b44SJordan Rupprecht 96099451b44SJordan Rupprecht self.reset_test_sequence() 96199451b44SJordan Rupprecht self.add_set_breakpoint_packets( 96299451b44SJordan Rupprecht function_address, 96399451b44SJordan Rupprecht z_packet_type, 96499451b44SJordan Rupprecht do_continue=True, 9652238dcc3SJonas Devlieghere breakpoint_kind=BREAKPOINT_KIND, 9662238dcc3SJonas Devlieghere ) 96799451b44SJordan Rupprecht 96899451b44SJordan Rupprecht # Run the packet stream. 96999451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 97099451b44SJordan Rupprecht self.assertIsNotNone(context) 97199451b44SJordan Rupprecht 97299451b44SJordan Rupprecht # Verify the stop signal reported was the breakpoint signal number. 97399451b44SJordan Rupprecht stop_signo = context.get("stop_signo") 97499451b44SJordan Rupprecht self.assertIsNotNone(stop_signo) 9752238dcc3SJonas Devlieghere self.assertEqual(int(stop_signo, 16), lldbutil.get_signal_number("SIGTRAP")) 97699451b44SJordan Rupprecht 97799451b44SJordan Rupprecht # Ensure we did not receive any output. If the breakpoint was not set, we would 97899451b44SJordan Rupprecht # see output (from a launched process with captured stdio) printing a hello, world message. 97999451b44SJordan Rupprecht # That would indicate the breakpoint didn't take. 98099451b44SJordan Rupprecht self.assertEqual(len(context["O_content"]), 0) 98199451b44SJordan Rupprecht 98299451b44SJordan Rupprecht # Verify that the PC for the main thread is where we expect it - right at the breakpoint address. 98399451b44SJordan Rupprecht # This acts as a another validation on the register reading code. 98499451b44SJordan Rupprecht self.reset_test_sequence() 98599451b44SJordan Rupprecht self.test_sequence.add_log_lines( 98699451b44SJordan Rupprecht [ 98799451b44SJordan Rupprecht # Print the PC. This should match the breakpoint address. 98899451b44SJordan Rupprecht "read packet: $p{0:x}#00".format(pc_lldb_reg_index), 98999451b44SJordan Rupprecht # Capture $p results. 9902238dcc3SJonas Devlieghere { 9912238dcc3SJonas Devlieghere "direction": "send", 99299451b44SJordan Rupprecht "regex": r"^\$([0-9a-fA-F]+)#", 9932238dcc3SJonas Devlieghere "capture": {1: "p_response"}, 9942238dcc3SJonas Devlieghere }, 9952238dcc3SJonas Devlieghere ], 9962238dcc3SJonas Devlieghere True, 9972238dcc3SJonas Devlieghere ) 99899451b44SJordan Rupprecht 99999451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 100099451b44SJordan Rupprecht self.assertIsNotNone(context) 100199451b44SJordan Rupprecht 100299451b44SJordan Rupprecht # Verify the PC is where we expect. Note response is in endianness of 100399451b44SJordan Rupprecht # the inferior. 100499451b44SJordan Rupprecht p_response = context.get("p_response") 100599451b44SJordan Rupprecht self.assertIsNotNone(p_response) 100699451b44SJordan Rupprecht 100799451b44SJordan Rupprecht # Convert from target endian to int. 100899451b44SJordan Rupprecht returned_pc = lldbgdbserverutils.unpack_register_hex_unsigned( 10092238dcc3SJonas Devlieghere endian, p_response 10102238dcc3SJonas Devlieghere ) 101199451b44SJordan Rupprecht self.assertEqual(returned_pc, function_address) 101299451b44SJordan Rupprecht 101399451b44SJordan Rupprecht # Verify that a breakpoint remove and continue gets us the expected 101499451b44SJordan Rupprecht # output. 101599451b44SJordan Rupprecht self.reset_test_sequence() 101699451b44SJordan Rupprecht 101799451b44SJordan Rupprecht # Add breakpoint remove packets 101899451b44SJordan Rupprecht self.add_remove_breakpoint_packets( 10192238dcc3SJonas Devlieghere function_address, z_packet_type, breakpoint_kind=BREAKPOINT_KIND 10202238dcc3SJonas Devlieghere ) 102199451b44SJordan Rupprecht 102299451b44SJordan Rupprecht self.test_sequence.add_log_lines( 102399451b44SJordan Rupprecht [ 102499451b44SJordan Rupprecht # Continue running. 102599451b44SJordan Rupprecht "read packet: $c#63", 102699451b44SJordan Rupprecht # We should now receive the output from the call. 102799451b44SJordan Rupprecht {"type": "output_match", "regex": r"^hello, world\r\n$"}, 102899451b44SJordan Rupprecht # And wait for program completion. 102999451b44SJordan Rupprecht {"direction": "send", "regex": r"^\$W00(.*)#[0-9a-fA-F]{2}$"}, 10302238dcc3SJonas Devlieghere ], 10312238dcc3SJonas Devlieghere True, 10322238dcc3SJonas Devlieghere ) 103399451b44SJordan Rupprecht 103499451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 103599451b44SJordan Rupprecht self.assertIsNotNone(context) 103699451b44SJordan Rupprecht 103799451b44SJordan Rupprecht @skipIfWindows # No pty support to test any inferior output 1038d9ba8142SPavel Labath def test_software_breakpoint_set_and_remove_work(self): 103999451b44SJordan Rupprecht if self.getArchitecture() == "arm": 104099451b44SJordan Rupprecht # TODO: Handle case when setting breakpoint in thumb code 10412238dcc3SJonas Devlieghere self.build(dictionary={"CFLAGS_EXTRAS": "-marm"}) 104299451b44SJordan Rupprecht else: 104399451b44SJordan Rupprecht self.build() 104499451b44SJordan Rupprecht self.set_inferior_startup_launch() 104599451b44SJordan Rupprecht self.breakpoint_set_and_remove_work(want_hardware=False) 104699451b44SJordan Rupprecht 10472238dcc3SJonas Devlieghere @skipUnlessPlatform(oslist=["linux"]) 10482238dcc3SJonas Devlieghere @skipIf(archs=no_match(["arm", "aarch64"])) 1049d9ba8142SPavel Labath def test_hardware_breakpoint_set_and_remove_work(self): 105099451b44SJordan Rupprecht if self.getArchitecture() == "arm": 105199451b44SJordan Rupprecht # TODO: Handle case when setting breakpoint in thumb code 10522238dcc3SJonas Devlieghere self.build(dictionary={"CFLAGS_EXTRAS": "-marm"}) 105399451b44SJordan Rupprecht else: 105499451b44SJordan Rupprecht self.build() 105599451b44SJordan Rupprecht self.set_inferior_startup_launch() 105699451b44SJordan Rupprecht self.breakpoint_set_and_remove_work(want_hardware=True) 105799451b44SJordan Rupprecht 105831225768SMichał Górny def get_qSupported_dict(self, features=[]): 105999451b44SJordan Rupprecht self.build() 106099451b44SJordan Rupprecht self.set_inferior_startup_launch() 106199451b44SJordan Rupprecht 106299451b44SJordan Rupprecht # Start up the stub and start/prep the inferior. 106399451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior() 106431225768SMichał Górny self.add_qSupported_packets(features) 106599451b44SJordan Rupprecht 106699451b44SJordan Rupprecht # Run the packet stream. 106799451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 106899451b44SJordan Rupprecht self.assertIsNotNone(context) 106999451b44SJordan Rupprecht 107099451b44SJordan Rupprecht # Retrieve the qSupported features. 107131225768SMichał Górny return self.parse_qSupported_response(context) 107231225768SMichał Górny 107331225768SMichał Górny def test_qSupported_returns_known_stub_features(self): 107431225768SMichał Górny supported_dict = self.get_qSupported_dict() 107599451b44SJordan Rupprecht self.assertIsNotNone(supported_dict) 10769c246882SJordan Rupprecht self.assertGreater(len(supported_dict), 0) 107799451b44SJordan Rupprecht 1078ca7824c2SMichał Górny def test_qSupported_auvx(self): 10792238dcc3SJonas Devlieghere expected = ( 10802238dcc3SJonas Devlieghere "+" 10812238dcc3SJonas Devlieghere if lldbplatformutil.getPlatform() in ["freebsd", "linux", "netbsd"] 10822238dcc3SJonas Devlieghere else "-" 10832238dcc3SJonas Devlieghere ) 1084ca7824c2SMichał Górny supported_dict = self.get_qSupported_dict() 10852238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("qXfer:auxv:read", "-"), expected) 1086ca7824c2SMichał Górny 1087ca7824c2SMichał Górny def test_qSupported_libraries_svr4(self): 10882238dcc3SJonas Devlieghere expected = ( 10892238dcc3SJonas Devlieghere "+" 10902238dcc3SJonas Devlieghere if lldbplatformutil.getPlatform() in ["freebsd", "linux", "netbsd"] 10912238dcc3SJonas Devlieghere else "-" 10922238dcc3SJonas Devlieghere ) 1093ca7824c2SMichał Górny supported_dict = self.get_qSupported_dict() 10942238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("qXfer:libraries-svr4:read", "-"), expected) 1095ca7824c2SMichał Górny 10961e74e5e9SMichał Górny def test_qSupported_siginfo_read(self): 10972238dcc3SJonas Devlieghere expected = ( 10982238dcc3SJonas Devlieghere "+" if lldbplatformutil.getPlatform() in ["freebsd", "linux"] else "-" 10992238dcc3SJonas Devlieghere ) 11001e74e5e9SMichał Górny supported_dict = self.get_qSupported_dict() 11012238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("qXfer:siginfo:read", "-"), expected) 11021e74e5e9SMichał Górny 1103ca7824c2SMichał Górny def test_qSupported_QPassSignals(self): 11042238dcc3SJonas Devlieghere expected = ( 11052238dcc3SJonas Devlieghere "+" 11062238dcc3SJonas Devlieghere if lldbplatformutil.getPlatform() in ["freebsd", "linux", "netbsd"] 11072238dcc3SJonas Devlieghere else "-" 11082238dcc3SJonas Devlieghere ) 1109ca7824c2SMichał Górny supported_dict = self.get_qSupported_dict() 11102238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("QPassSignals", "-"), expected) 1111ca7824c2SMichał Górny 111231225768SMichał Górny @add_test_categories(["fork"]) 111331225768SMichał Górny def test_qSupported_fork_events(self): 11142238dcc3SJonas Devlieghere supported_dict = self.get_qSupported_dict(["multiprocess+", "fork-events+"]) 11152238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("multiprocess", "-"), "+") 11162238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("fork-events", "-"), "+") 11172238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("vfork-events", "-"), "-") 111831225768SMichał Górny 111931225768SMichał Górny @add_test_categories(["fork"]) 112031225768SMichał Górny def test_qSupported_fork_events_without_multiprocess(self): 11212238dcc3SJonas Devlieghere supported_dict = self.get_qSupported_dict(["fork-events+"]) 11222238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("multiprocess", "-"), "-") 11232238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("fork-events", "-"), "-") 11242238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("vfork-events", "-"), "-") 112531225768SMichał Górny 112631225768SMichał Górny @add_test_categories(["fork"]) 112731225768SMichał Górny def test_qSupported_vfork_events(self): 11282238dcc3SJonas Devlieghere supported_dict = self.get_qSupported_dict(["multiprocess+", "vfork-events+"]) 11292238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("multiprocess", "-"), "+") 11302238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("fork-events", "-"), "-") 11312238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("vfork-events", "-"), "+") 113231225768SMichał Górny 113331225768SMichał Górny @add_test_categories(["fork"]) 113431225768SMichał Górny def test_qSupported_vfork_events_without_multiprocess(self): 11352238dcc3SJonas Devlieghere supported_dict = self.get_qSupported_dict(["vfork-events+"]) 11362238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("multiprocess", "-"), "-") 11372238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("fork-events", "-"), "-") 11382238dcc3SJonas Devlieghere self.assertEqual(supported_dict.get("vfork-events", "-"), "-") 113931225768SMichał Górny 11408d58fbd0SDavid Spickett # We need to be able to self.runCmd to get cpuinfo, 11418d58fbd0SDavid Spickett # which is not possible when using a remote platform. 11428d58fbd0SDavid Spickett @skipIfRemote 11438d58fbd0SDavid Spickett def test_qSupported_memory_tagging(self): 11448d58fbd0SDavid Spickett supported_dict = self.get_qSupported_dict() 11452238dcc3SJonas Devlieghere self.assertEqual( 11462238dcc3SJonas Devlieghere supported_dict.get("memory-tagging", "-"), 11472238dcc3SJonas Devlieghere "+" if self.isAArch64MTE() else "-", 11482238dcc3SJonas Devlieghere ) 11498d58fbd0SDavid Spickett 1150d9ba8142SPavel Labath @skipIfWindows # No pty support to test any inferior output 1151d9ba8142SPavel Labath def test_written_M_content_reads_back_correctly(self): 115299451b44SJordan Rupprecht self.build() 115399451b44SJordan Rupprecht self.set_inferior_startup_launch() 115499451b44SJordan Rupprecht 115599451b44SJordan Rupprecht TEST_MESSAGE = "Hello, memory" 115699451b44SJordan Rupprecht 115799451b44SJordan Rupprecht # Start up the stub and start/prep the inferior. 115899451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior( 115999451b44SJordan Rupprecht inferior_args=[ 116099451b44SJordan Rupprecht "set-message:xxxxxxxxxxxxxX", 116199451b44SJordan Rupprecht "get-data-address-hex:g_message", 116299451b44SJordan Rupprecht "sleep:1", 11632238dcc3SJonas Devlieghere "print-message:", 11642238dcc3SJonas Devlieghere ] 11652238dcc3SJonas Devlieghere ) 116699451b44SJordan Rupprecht self.test_sequence.add_log_lines( 116799451b44SJordan Rupprecht [ 116899451b44SJordan Rupprecht # Start running after initial stop. 116999451b44SJordan Rupprecht "read packet: $c#63", 117099451b44SJordan Rupprecht # Match output line that prints the memory address of the message buffer within the inferior. 117199451b44SJordan Rupprecht # Note we require launch-only testing so we can get inferior otuput. 11722238dcc3SJonas Devlieghere { 11732238dcc3SJonas Devlieghere "type": "output_match", 11742238dcc3SJonas Devlieghere "regex": self.maybe_strict_output_regex( 11752238dcc3SJonas Devlieghere r"data address: 0x([0-9a-fA-F]+)\r\n" 11762238dcc3SJonas Devlieghere ), 11772238dcc3SJonas Devlieghere "capture": {1: "message_address"}, 11782238dcc3SJonas Devlieghere }, 117999451b44SJordan Rupprecht # Now stop the inferior. 118099451b44SJordan Rupprecht "read packet: {}".format(chr(3)), 118199451b44SJordan Rupprecht # And wait for the stop notification. 11822238dcc3SJonas Devlieghere { 11832238dcc3SJonas Devlieghere "direction": "send", 11842238dcc3SJonas Devlieghere "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", 11852238dcc3SJonas Devlieghere "capture": {1: "stop_signo", 2: "stop_thread_id"}, 11862238dcc3SJonas Devlieghere }, 11872238dcc3SJonas Devlieghere ], 11882238dcc3SJonas Devlieghere True, 11892238dcc3SJonas Devlieghere ) 119099451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 119199451b44SJordan Rupprecht self.assertIsNotNone(context) 119299451b44SJordan Rupprecht 119399451b44SJordan Rupprecht # Grab the message address. 119499451b44SJordan Rupprecht self.assertIsNotNone(context.get("message_address")) 119599451b44SJordan Rupprecht message_address = int(context.get("message_address"), 16) 119699451b44SJordan Rupprecht 119799451b44SJordan Rupprecht # Hex-encode the test message, adding null termination. 119899451b44SJordan Rupprecht hex_encoded_message = seven.hexlify(TEST_MESSAGE) 119999451b44SJordan Rupprecht 120099451b44SJordan Rupprecht # Write the message to the inferior. Verify that we can read it with the hex-encoded (m) 120199451b44SJordan Rupprecht # and binary (x) memory read packets. 120299451b44SJordan Rupprecht self.reset_test_sequence() 120399451b44SJordan Rupprecht self.test_sequence.add_log_lines( 12042238dcc3SJonas Devlieghere [ 12052238dcc3SJonas Devlieghere "read packet: $M{0:x},{1:x}:{2}#00".format( 12062238dcc3SJonas Devlieghere message_address, len(TEST_MESSAGE), hex_encoded_message 12072238dcc3SJonas Devlieghere ), 120899451b44SJordan Rupprecht "send packet: $OK#00", 12092238dcc3SJonas Devlieghere "read packet: $m{0:x},{1:x}#00".format( 12102238dcc3SJonas Devlieghere message_address, len(TEST_MESSAGE) 12112238dcc3SJonas Devlieghere ), 121299451b44SJordan Rupprecht "send packet: ${0}#00".format(hex_encoded_message), 12132238dcc3SJonas Devlieghere "read packet: $x{0:x},{1:x}#00".format( 12142238dcc3SJonas Devlieghere message_address, len(TEST_MESSAGE) 12152238dcc3SJonas Devlieghere ), 121699451b44SJordan Rupprecht "send packet: ${0}#00".format(TEST_MESSAGE), 121799451b44SJordan Rupprecht "read packet: $m{0:x},4#00".format(message_address), 121899451b44SJordan Rupprecht "send packet: ${0}#00".format(hex_encoded_message[0:8]), 121999451b44SJordan Rupprecht "read packet: $x{0:x},4#00".format(message_address), 122099451b44SJordan Rupprecht "send packet: ${0}#00".format(TEST_MESSAGE[0:4]), 122199451b44SJordan Rupprecht "read packet: $c#63", 12222238dcc3SJonas Devlieghere { 12232238dcc3SJonas Devlieghere "type": "output_match", 12242238dcc3SJonas Devlieghere "regex": r"^message: (.+)\r\n$", 12252238dcc3SJonas Devlieghere "capture": {1: "printed_message"}, 12262238dcc3SJonas Devlieghere }, 122799451b44SJordan Rupprecht "send packet: $W00#00", 12282238dcc3SJonas Devlieghere ], 12292238dcc3SJonas Devlieghere True, 12302238dcc3SJonas Devlieghere ) 123199451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 123299451b44SJordan Rupprecht self.assertIsNotNone(context) 123399451b44SJordan Rupprecht 123499451b44SJordan Rupprecht # Ensure what we read from inferior memory is what we wrote. 123599451b44SJordan Rupprecht printed_message = context.get("printed_message") 123699451b44SJordan Rupprecht self.assertIsNotNone(printed_message) 123799451b44SJordan Rupprecht self.assertEqual(printed_message, TEST_MESSAGE + "X") 123899451b44SJordan Rupprecht 1239d9ba8142SPavel Labath # Note: as of this moment, a hefty number of the GPR writes are failing with E32 (everything except rax-rdx, rdi, rsi, rbp). 1240d9ba8142SPavel Labath # Come back to this. I have the test rigged to verify that at least some 1241d9ba8142SPavel Labath # of the bit-flip writes work. 1242d9ba8142SPavel Labath def test_P_writes_all_gpr_registers(self): 124399451b44SJordan Rupprecht self.build() 124499451b44SJordan Rupprecht self.set_inferior_startup_launch() 124599451b44SJordan Rupprecht 124699451b44SJordan Rupprecht # Start inferior debug session, grab all register info. 124799451b44SJordan Rupprecht procs = self.prep_debug_monitor_and_inferior(inferior_args=["sleep:2"]) 124899451b44SJordan Rupprecht self.add_register_info_collection_packets() 124999451b44SJordan Rupprecht self.add_process_info_collection_packets() 125099451b44SJordan Rupprecht 125199451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 125299451b44SJordan Rupprecht self.assertIsNotNone(context) 125399451b44SJordan Rupprecht 125499451b44SJordan Rupprecht # Process register infos. 125599451b44SJordan Rupprecht reg_infos = self.parse_register_info_packets(context) 125699451b44SJordan Rupprecht self.assertIsNotNone(reg_infos) 125799451b44SJordan Rupprecht self.add_lldb_register_index(reg_infos) 125899451b44SJordan Rupprecht 125999451b44SJordan Rupprecht # Process endian. 126099451b44SJordan Rupprecht process_info = self.parse_process_info_response(context) 126199451b44SJordan Rupprecht endian = process_info.get("endian") 126299451b44SJordan Rupprecht self.assertIsNotNone(endian) 126399451b44SJordan Rupprecht 126499451b44SJordan Rupprecht # Pull out the register infos that we think we can bit flip 126599451b44SJordan Rupprecht # successfully,. 126699451b44SJordan Rupprecht gpr_reg_infos = [ 12672238dcc3SJonas Devlieghere reg_info 12682238dcc3SJonas Devlieghere for reg_info in reg_infos 12692238dcc3SJonas Devlieghere if self.is_bit_flippable_register(reg_info) 12702238dcc3SJonas Devlieghere ] 12719c246882SJordan Rupprecht self.assertGreater(len(gpr_reg_infos), 0) 127299451b44SJordan Rupprecht 127399451b44SJordan Rupprecht # Write flipped bit pattern of existing value to each register. 127499451b44SJordan Rupprecht (successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value( 12752238dcc3SJonas Devlieghere gpr_reg_infos, endian 12762238dcc3SJonas Devlieghere ) 12772238dcc3SJonas Devlieghere self.trace( 12782238dcc3SJonas Devlieghere "successful writes: {}, failed writes: {}".format( 12792238dcc3SJonas Devlieghere successful_writes, failed_writes 12802238dcc3SJonas Devlieghere ) 12812238dcc3SJonas Devlieghere ) 12829c246882SJordan Rupprecht self.assertGreater(successful_writes, 0) 128399451b44SJordan Rupprecht 1284d9ba8142SPavel Labath # Note: as of this moment, a hefty number of the GPR writes are failing 1285d9ba8142SPavel Labath # with E32 (everything except rax-rdx, rdi, rsi, rbp). 1286d9ba8142SPavel Labath @skipIfWindows 1287d9ba8142SPavel Labath def test_P_and_p_thread_suffix_work(self): 128899451b44SJordan Rupprecht self.build() 128999451b44SJordan Rupprecht self.set_inferior_startup_launch() 129099451b44SJordan Rupprecht 129199451b44SJordan Rupprecht # Startup the inferior with three threads. 12925a4fe166SPavel Labath _, threads = self.launch_with_threads(3) 12935a4fe166SPavel Labath 12945a4fe166SPavel Labath self.reset_test_sequence() 129599451b44SJordan Rupprecht self.add_thread_suffix_request_packets() 129699451b44SJordan Rupprecht self.add_register_info_collection_packets() 129799451b44SJordan Rupprecht self.add_process_info_collection_packets() 129899451b44SJordan Rupprecht 129999451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 130099451b44SJordan Rupprecht self.assertIsNotNone(context) 130199451b44SJordan Rupprecht 130299451b44SJordan Rupprecht process_info = self.parse_process_info_response(context) 130399451b44SJordan Rupprecht self.assertIsNotNone(process_info) 130499451b44SJordan Rupprecht endian = process_info.get("endian") 130599451b44SJordan Rupprecht self.assertIsNotNone(endian) 130699451b44SJordan Rupprecht 130799451b44SJordan Rupprecht reg_infos = self.parse_register_info_packets(context) 130899451b44SJordan Rupprecht self.assertIsNotNone(reg_infos) 130999451b44SJordan Rupprecht self.add_lldb_register_index(reg_infos) 131099451b44SJordan Rupprecht 131199451b44SJordan Rupprecht reg_index = self.select_modifiable_register(reg_infos) 131299451b44SJordan Rupprecht self.assertIsNotNone(reg_index) 131399451b44SJordan Rupprecht reg_byte_size = int(reg_infos[reg_index]["bitsize"]) // 8 13149c246882SJordan Rupprecht self.assertGreater(reg_byte_size, 0) 131599451b44SJordan Rupprecht 131699451b44SJordan Rupprecht expected_reg_values = [] 131799451b44SJordan Rupprecht register_increment = 1 131899451b44SJordan Rupprecht next_value = None 131999451b44SJordan Rupprecht 132099451b44SJordan Rupprecht # Set the same register in each of 3 threads to a different value. 132199451b44SJordan Rupprecht # Verify each one has the unique value. 132299451b44SJordan Rupprecht for thread in threads: 132399451b44SJordan Rupprecht # If we don't have a next value yet, start it with the initial read 132499451b44SJordan Rupprecht # value + 1 132599451b44SJordan Rupprecht if not next_value: 132699451b44SJordan Rupprecht # Read pre-existing register value. 132799451b44SJordan Rupprecht self.reset_test_sequence() 132899451b44SJordan Rupprecht self.test_sequence.add_log_lines( 13292238dcc3SJonas Devlieghere [ 13302238dcc3SJonas Devlieghere "read packet: $p{0:x};thread:{1:x}#00".format( 13312238dcc3SJonas Devlieghere reg_index, thread 13322238dcc3SJonas Devlieghere ), 13332238dcc3SJonas Devlieghere { 13342238dcc3SJonas Devlieghere "direction": "send", 13352238dcc3SJonas Devlieghere "regex": r"^\$([0-9a-fA-F]+)#", 13362238dcc3SJonas Devlieghere "capture": {1: "p_response"}, 13372238dcc3SJonas Devlieghere }, 13382238dcc3SJonas Devlieghere ], 13392238dcc3SJonas Devlieghere True, 13402238dcc3SJonas Devlieghere ) 134199451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 134299451b44SJordan Rupprecht self.assertIsNotNone(context) 134399451b44SJordan Rupprecht 134499451b44SJordan Rupprecht # Set the next value to use for writing as the increment plus 134599451b44SJordan Rupprecht # current value. 134699451b44SJordan Rupprecht p_response = context.get("p_response") 134799451b44SJordan Rupprecht self.assertIsNotNone(p_response) 134899451b44SJordan Rupprecht next_value = lldbgdbserverutils.unpack_register_hex_unsigned( 13492238dcc3SJonas Devlieghere endian, p_response 13502238dcc3SJonas Devlieghere ) 135199451b44SJordan Rupprecht 135299451b44SJordan Rupprecht # Set new value using P and thread suffix. 135399451b44SJordan Rupprecht self.reset_test_sequence() 135499451b44SJordan Rupprecht self.test_sequence.add_log_lines( 135599451b44SJordan Rupprecht [ 135699451b44SJordan Rupprecht "read packet: $P{0:x}={1};thread:{2:x}#00".format( 135799451b44SJordan Rupprecht reg_index, 135899451b44SJordan Rupprecht lldbgdbserverutils.pack_register_hex( 13592238dcc3SJonas Devlieghere endian, next_value, byte_size=reg_byte_size 13602238dcc3SJonas Devlieghere ), 13612238dcc3SJonas Devlieghere thread, 13622238dcc3SJonas Devlieghere ), 136399451b44SJordan Rupprecht "send packet: $OK#00", 136499451b44SJordan Rupprecht ], 13652238dcc3SJonas Devlieghere True, 13662238dcc3SJonas Devlieghere ) 136799451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 136899451b44SJordan Rupprecht self.assertIsNotNone(context) 136999451b44SJordan Rupprecht 137099451b44SJordan Rupprecht # Save the value we set. 137199451b44SJordan Rupprecht expected_reg_values.append(next_value) 137299451b44SJordan Rupprecht 137399451b44SJordan Rupprecht # Increment value for next thread to use (we want them all 137499451b44SJordan Rupprecht # different so we can verify they wrote to each thread correctly 137599451b44SJordan Rupprecht # next.) 137699451b44SJordan Rupprecht next_value += register_increment 137799451b44SJordan Rupprecht 137899451b44SJordan Rupprecht # Revisit each thread and verify they have the expected value set for 137999451b44SJordan Rupprecht # the register we wrote. 138099451b44SJordan Rupprecht thread_index = 0 138199451b44SJordan Rupprecht for thread in threads: 138299451b44SJordan Rupprecht # Read pre-existing register value. 138399451b44SJordan Rupprecht self.reset_test_sequence() 138499451b44SJordan Rupprecht self.test_sequence.add_log_lines( 13852238dcc3SJonas Devlieghere [ 13862238dcc3SJonas Devlieghere "read packet: $p{0:x};thread:{1:x}#00".format(reg_index, thread), 13872238dcc3SJonas Devlieghere { 13882238dcc3SJonas Devlieghere "direction": "send", 13892238dcc3SJonas Devlieghere "regex": r"^\$([0-9a-fA-F]+)#", 13902238dcc3SJonas Devlieghere "capture": {1: "p_response"}, 13912238dcc3SJonas Devlieghere }, 13922238dcc3SJonas Devlieghere ], 13932238dcc3SJonas Devlieghere True, 13942238dcc3SJonas Devlieghere ) 139599451b44SJordan Rupprecht context = self.expect_gdbremote_sequence() 139699451b44SJordan Rupprecht self.assertIsNotNone(context) 139799451b44SJordan Rupprecht 139899451b44SJordan Rupprecht # Get the register value. 139999451b44SJordan Rupprecht p_response = context.get("p_response") 140099451b44SJordan Rupprecht self.assertIsNotNone(p_response) 140199451b44SJordan Rupprecht read_value = lldbgdbserverutils.unpack_register_hex_unsigned( 14022238dcc3SJonas Devlieghere endian, p_response 14032238dcc3SJonas Devlieghere ) 140499451b44SJordan Rupprecht 140599451b44SJordan Rupprecht # Make sure we read back what we wrote. 140699451b44SJordan Rupprecht self.assertEqual(read_value, expected_reg_values[thread_index]) 140799451b44SJordan Rupprecht thread_index += 1 14086ba3f723SMichał Górny 14091e74e5e9SMichał Górny @skipUnlessPlatform(oslist=["freebsd", "linux"]) 14101e74e5e9SMichał Górny @add_test_categories(["llgs"]) 14111e74e5e9SMichał Górny def test_qXfer_siginfo_read(self): 14121e74e5e9SMichał Górny self.build() 14131e74e5e9SMichał Górny self.set_inferior_startup_launch() 14141e74e5e9SMichał Górny procs = self.prep_debug_monitor_and_inferior( 14152238dcc3SJonas Devlieghere inferior_args=["thread:segfault", "thread:new", "sleep:10"] 14162238dcc3SJonas Devlieghere ) 14171e74e5e9SMichał Górny self.test_sequence.add_log_lines(["read packet: $c#63"], True) 14181e74e5e9SMichał Górny self.expect_gdbremote_sequence() 14191e74e5e9SMichał Górny 14201e74e5e9SMichał Górny # Run until SIGSEGV comes in. 14211e74e5e9SMichał Górny self.reset_test_sequence() 14221e74e5e9SMichał Górny self.test_sequence.add_log_lines( 14232238dcc3SJonas Devlieghere [ 14242238dcc3SJonas Devlieghere { 14252238dcc3SJonas Devlieghere "direction": "send", 14261e74e5e9SMichał Górny "regex": r"^\$T([0-9a-fA-F]{2})thread:([0-9a-fA-F]+);", 14271e74e5e9SMichał Górny "capture": {1: "signo", 2: "thread_id"}, 14282238dcc3SJonas Devlieghere } 14292238dcc3SJonas Devlieghere ], 14302238dcc3SJonas Devlieghere True, 14312238dcc3SJonas Devlieghere ) 14321e74e5e9SMichał Górny 14331e74e5e9SMichał Górny # Figure out which thread crashed. 14341e74e5e9SMichał Górny context = self.expect_gdbremote_sequence() 14351e74e5e9SMichał Górny self.assertIsNotNone(context) 14362238dcc3SJonas Devlieghere self.assertEqual( 14372238dcc3SJonas Devlieghere int(context["signo"], 16), lldbutil.get_signal_number("SIGSEGV") 14382238dcc3SJonas Devlieghere ) 14391e74e5e9SMichał Górny crashing_thread = int(context["thread_id"], 16) 14401e74e5e9SMichał Górny 14411e74e5e9SMichał Górny # Grab siginfo for the crashing thread. 14421e74e5e9SMichał Górny self.reset_test_sequence() 14431e74e5e9SMichał Górny self.add_process_info_collection_packets() 14441e74e5e9SMichał Górny self.test_sequence.add_log_lines( 14452238dcc3SJonas Devlieghere [ 14462238dcc3SJonas Devlieghere "read packet: $Hg{:x}#00".format(crashing_thread), 14471e74e5e9SMichał Górny "send packet: $OK#00", 14481e74e5e9SMichał Górny "read packet: $qXfer:siginfo:read::0,80:#00", 14492238dcc3SJonas Devlieghere { 14502238dcc3SJonas Devlieghere "direction": "send", 14512238dcc3SJonas Devlieghere "regex": re.compile( 14522238dcc3SJonas Devlieghere r"^\$([^E])(.*)#[0-9a-fA-F]{2}$", re.MULTILINE | re.DOTALL 14532238dcc3SJonas Devlieghere ), 14541e74e5e9SMichał Górny "capture": {1: "response_type", 2: "content_raw"}, 14552238dcc3SJonas Devlieghere }, 14562238dcc3SJonas Devlieghere ], 14572238dcc3SJonas Devlieghere True, 14582238dcc3SJonas Devlieghere ) 14591e74e5e9SMichał Górny context = self.expect_gdbremote_sequence() 14601e74e5e9SMichał Górny self.assertIsNotNone(context) 14611e74e5e9SMichał Górny 14621e74e5e9SMichał Górny # Ensure we end up with all data in one packet. 14631e74e5e9SMichał Górny self.assertEqual(context.get("response_type"), "l") 14641e74e5e9SMichał Górny 14651e74e5e9SMichał Górny # Decode binary data. 14661e74e5e9SMichał Górny content_raw = context.get("content_raw") 14671e74e5e9SMichał Górny self.assertIsNotNone(content_raw) 14681e74e5e9SMichał Górny content = self.decode_gdbremote_binary(content_raw).encode("latin1") 14691e74e5e9SMichał Górny 14701e74e5e9SMichał Górny # Decode siginfo_t. 14711e74e5e9SMichał Górny process_info = self.parse_process_info_response(context) 14721e74e5e9SMichał Górny pad = "" 14731e74e5e9SMichał Górny if process_info["ptrsize"] == "8": 14741e74e5e9SMichał Górny pad = "i" 14751e74e5e9SMichał Górny signo_idx = 0 14761e74e5e9SMichał Górny errno_idx = 1 14771e74e5e9SMichał Górny code_idx = 2 14781e74e5e9SMichał Górny addr_idx = -1 14791e74e5e9SMichał Górny SEGV_MAPERR = 1 14801e74e5e9SMichał Górny if process_info["ostype"] == "linux": 14811e74e5e9SMichał Górny # si_signo, si_errno, si_code, [pad], _sifields._sigfault.si_addr 14821e74e5e9SMichał Górny format_str = "iii{}P".format(pad) 14831e74e5e9SMichał Górny elif process_info["ostype"].startswith("freebsd"): 14841e74e5e9SMichał Górny # si_signo, si_errno, si_code, si_pid, si_uid, si_status, si_addr 14851e74e5e9SMichał Górny format_str = "iiiiiiP" 14861e74e5e9SMichał Górny elif process_info["ostype"].startswith("netbsd"): 14871e74e5e9SMichał Górny # _signo, _code, _errno, [pad], _reason._fault._addr 14881e74e5e9SMichał Górny format_str = "iii{}P".format(pad) 14891e74e5e9SMichał Górny errno_idx = 2 14901e74e5e9SMichał Górny code_idx = 1 14911e74e5e9SMichał Górny else: 14921e74e5e9SMichał Górny assert False, "unknown ostype" 14931e74e5e9SMichał Górny 14941e74e5e9SMichał Górny decoder = struct.Struct(format_str) 14951e74e5e9SMichał Górny decoded = decoder.unpack(content[: decoder.size]) 14962238dcc3SJonas Devlieghere self.assertEqual(decoded[signo_idx], lldbutil.get_signal_number("SIGSEGV")) 14971e74e5e9SMichał Górny self.assertEqual(decoded[errno_idx], 0) # si_errno 14981e74e5e9SMichał Górny self.assertEqual(decoded[code_idx], SEGV_MAPERR) # si_code 14991e74e5e9SMichał Górny self.assertEqual(decoded[addr_idx], 0) # si_addr 1500