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