1import gdbremote_testcase 2from lldbsuite.test.decorators import * 3from lldbsuite.test.lldbtest import * 4from lldbsuite.test import lldbutil 5 6 7class TestGdbRemoteRegisterState(gdbremote_testcase.GdbRemoteTestCaseBase): 8 """Test QSaveRegisterState/QRestoreRegisterState support.""" 9 10 mydir = TestBase.compute_mydir(__file__) 11 12 @skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet 13 def grp_register_save_restore_works(self, with_suffix): 14 # Start up the process, use thread suffix, grab main thread id. 15 inferior_args = ["message:main entered", "sleep:5"] 16 procs = self.prep_debug_monitor_and_inferior( 17 inferior_args=inferior_args) 18 19 self.add_process_info_collection_packets() 20 self.add_register_info_collection_packets() 21 if with_suffix: 22 self.add_thread_suffix_request_packets() 23 self.add_threadinfo_collection_packets() 24 25 context = self.expect_gdbremote_sequence() 26 self.assertIsNotNone(context) 27 28 # Gather process info. 29 process_info = self.parse_process_info_response(context) 30 endian = process_info.get("endian") 31 self.assertIsNotNone(endian) 32 33 # Gather register info. 34 reg_infos = self.parse_register_info_packets(context) 35 self.assertIsNotNone(reg_infos) 36 self.add_lldb_register_index(reg_infos) 37 38 # Pull out the register infos that we think we can bit flip 39 # successfully. 40 gpr_reg_infos = [ 41 reg_info for reg_info in reg_infos if self.is_bit_flippable_register(reg_info)] 42 self.assertTrue(len(gpr_reg_infos) > 0) 43 44 # Gather thread info. 45 if with_suffix: 46 threads = self.parse_threadinfo_packets(context) 47 self.assertIsNotNone(threads) 48 thread_id = threads[0] 49 self.assertIsNotNone(thread_id) 50 self.trace("Running on thread: 0x{:x}".format(thread_id)) 51 else: 52 thread_id = None 53 54 # Save register state. 55 self.reset_test_sequence() 56 self.add_QSaveRegisterState_packets(thread_id) 57 58 context = self.expect_gdbremote_sequence() 59 self.assertIsNotNone(context) 60 61 (success, state_id) = self.parse_QSaveRegisterState_response(context) 62 self.assertTrue(success) 63 self.assertIsNotNone(state_id) 64 self.trace("saved register state id: {}".format(state_id)) 65 66 # Remember initial register values. 67 initial_reg_values = self.read_register_values( 68 gpr_reg_infos, endian, thread_id=thread_id) 69 self.trace("initial_reg_values: {}".format(initial_reg_values)) 70 71 # Flip gpr register values. 72 (successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value( 73 gpr_reg_infos, endian, thread_id=thread_id) 74 self.trace("successful writes: {}, failed writes: {}".format(successful_writes, failed_writes)) 75 self.assertTrue(successful_writes > 0) 76 77 flipped_reg_values = self.read_register_values( 78 gpr_reg_infos, endian, thread_id=thread_id) 79 self.trace("flipped_reg_values: {}".format(flipped_reg_values)) 80 81 # Restore register values. 82 self.reset_test_sequence() 83 self.add_QRestoreRegisterState_packets(state_id, thread_id) 84 85 context = self.expect_gdbremote_sequence() 86 self.assertIsNotNone(context) 87 88 # Verify registers match initial register values. 89 final_reg_values = self.read_register_values( 90 gpr_reg_infos, endian, thread_id=thread_id) 91 self.trace("final_reg_values: {}".format(final_reg_values)) 92 self.assertIsNotNone(final_reg_values) 93 self.assertEqual(final_reg_values, initial_reg_values) 94 95 @debugserver_test 96 def test_grp_register_save_restore_works_with_suffix_debugserver(self): 97 USE_THREAD_SUFFIX = True 98 self.init_debugserver_test() 99 self.build() 100 self.set_inferior_startup_launch() 101 self.grp_register_save_restore_works(USE_THREAD_SUFFIX) 102 103 @llgs_test 104 def test_grp_register_save_restore_works_with_suffix_llgs(self): 105 USE_THREAD_SUFFIX = True 106 self.init_llgs_test() 107 self.build() 108 self.set_inferior_startup_launch() 109 self.grp_register_save_restore_works(USE_THREAD_SUFFIX) 110 111 @debugserver_test 112 def test_grp_register_save_restore_works_no_suffix_debugserver(self): 113 USE_THREAD_SUFFIX = False 114 self.init_debugserver_test() 115 self.build() 116 self.set_inferior_startup_launch() 117 self.grp_register_save_restore_works(USE_THREAD_SUFFIX) 118 119 @llgs_test 120 def test_grp_register_save_restore_works_no_suffix_llgs(self): 121 USE_THREAD_SUFFIX = False 122 self.init_llgs_test() 123 self.build() 124 self.set_inferior_startup_launch() 125 self.grp_register_save_restore_works(USE_THREAD_SUFFIX) 126