1 from __future__ import print_function
4 import gdbremote_testcase
5 from lldbsuite.test.decorators import *
6 from lldbsuite.test.lldbtest import *
7 from lldbsuite.test import lldbutil
10 class TestGdbRemoteRegisterState(gdbremote_testcase.GdbRemoteTestCaseBase):
11 """Test QSaveRegisterState/QRestoreRegisterState support."""
13 mydir = TestBase.compute_mydir(__file__)
15 def grp_register_save_restore_works(self, with_suffix):
16 # Start up the process, use thread suffix, grab main thread id.
17 inferior_args = ["message:main entered", "sleep:5"]
18 procs = self.prep_debug_monitor_and_inferior(
19 inferior_args=inferior_args)
21 self.add_process_info_collection_packets()
22 self.add_register_info_collection_packets()
24 self.add_thread_suffix_request_packets()
25 self.add_threadinfo_collection_packets()
26 self.test_sequence.add_log_lines([
27 # Start the inferior...
29 # ... match output....
30 {"type": "output_match", "regex": self.maybe_strict_output_regex(
31 r"message:main entered\r\n")},
34 self.add_interrupt_packets()
36 context = self.expect_gdbremote_sequence()
37 self.assertIsNotNone(context)
39 # Gather process info.
40 process_info = self.parse_process_info_response(context)
41 endian = process_info.get("endian")
42 self.assertIsNotNone(endian)
44 # Gather register info.
45 reg_infos = self.parse_register_info_packets(context)
46 self.assertIsNotNone(reg_infos)
47 self.add_lldb_register_index(reg_infos)
49 # Pull out the register infos that we think we can bit flip
52 reg_info for reg_info in reg_infos if self.is_bit_flippable_register(reg_info)]
53 self.assertTrue(len(gpr_reg_infos) > 0)
57 threads = self.parse_threadinfo_packets(context)
58 self.assertIsNotNone(threads)
59 thread_id = threads[0]
60 self.assertIsNotNone(thread_id)
61 # print("Running on thread: 0x{:x}".format(thread_id))
65 # Save register state.
66 self.reset_test_sequence()
67 self.add_QSaveRegisterState_packets(thread_id)
69 context = self.expect_gdbremote_sequence()
70 self.assertIsNotNone(context)
72 (success, state_id) = self.parse_QSaveRegisterState_response(context)
73 self.assertTrue(success)
74 self.assertIsNotNone(state_id)
75 # print("saved register state id: {}".format(state_id))
77 # Remember initial register values.
78 initial_reg_values = self.read_register_values(
79 gpr_reg_infos, endian, thread_id=thread_id)
80 # print("initial_reg_values: {}".format(initial_reg_values))
82 # Flip gpr register values.
83 (successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value(
84 gpr_reg_infos, endian, thread_id=thread_id)
85 # print("successful writes: {}, failed writes: {}".format(successful_writes, failed_writes))
86 self.assertTrue(successful_writes > 0)
88 flipped_reg_values = self.read_register_values(
89 gpr_reg_infos, endian, thread_id=thread_id)
90 # print("flipped_reg_values: {}".format(flipped_reg_values))
92 # Restore register values.
93 self.reset_test_sequence()
94 self.add_QRestoreRegisterState_packets(state_id, thread_id)
96 context = self.expect_gdbremote_sequence()
97 self.assertIsNotNone(context)
99 # Verify registers match initial register values.
100 final_reg_values = self.read_register_values(
101 gpr_reg_infos, endian, thread_id=thread_id)
102 # print("final_reg_values: {}".format(final_reg_values))
103 self.assertIsNotNone(final_reg_values)
104 self.assertEqual(final_reg_values, initial_reg_values)
107 def test_grp_register_save_restore_works_with_suffix_debugserver(self):
108 USE_THREAD_SUFFIX = True
109 self.init_debugserver_test()
111 self.set_inferior_startup_launch()
112 self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
115 def test_grp_register_save_restore_works_with_suffix_llgs(self):
116 USE_THREAD_SUFFIX = True
117 self.init_llgs_test()
119 self.set_inferior_startup_launch()
120 self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
123 def test_grp_register_save_restore_works_no_suffix_debugserver(self):
124 USE_THREAD_SUFFIX = False
125 self.init_debugserver_test()
127 self.set_inferior_startup_launch()
128 self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
131 def test_grp_register_save_restore_works_no_suffix_llgs(self):
132 USE_THREAD_SUFFIX = False
133 self.init_llgs_test()
135 self.set_inferior_startup_launch()
136 self.grp_register_save_restore_works(USE_THREAD_SUFFIX)