aboutsummaryrefslogtreecommitdiff
path: root/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py')
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py126
1 files changed, 126 insertions, 0 deletions
diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py
new file mode 100644
index 000000000000..a36b4ae781ad
--- /dev/null
+++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteRegisterState.py
@@ -0,0 +1,126 @@
+from __future__ import print_function
+
+
+
+import gdbremote_testcase
+from lldbsuite.test.lldbtest import *
+
+class TestGdbRemoteRegisterState(gdbremote_testcase.GdbRemoteTestCaseBase):
+ """Test QSaveRegisterState/QRestoreRegisterState support."""
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ def grp_register_save_restore_works(self, with_suffix):
+ # Start up the process, use thread suffix, grab main thread id.
+ inferior_args = ["message:main entered", "sleep:5"]
+ procs = self.prep_debug_monitor_and_inferior(inferior_args=inferior_args)
+
+ self.add_process_info_collection_packets()
+ self.add_register_info_collection_packets()
+ if with_suffix:
+ self.add_thread_suffix_request_packets()
+ self.add_threadinfo_collection_packets()
+ self.test_sequence.add_log_lines([
+ # Start the inferior...
+ "read packet: $c#63",
+ # ... match output....
+ { "type":"output_match", "regex":r"^message:main entered\r\n$" },
+ ], True)
+ # ... then interrupt.
+ self.add_interrupt_packets()
+
+ context = self.expect_gdbremote_sequence()
+ self.assertIsNotNone(context)
+
+ # Gather process info.
+ process_info = self.parse_process_info_response(context)
+ endian = process_info.get("endian")
+ self.assertIsNotNone(endian)
+
+ # Gather register info.
+ reg_infos = self.parse_register_info_packets(context)
+ self.assertIsNotNone(reg_infos)
+ self.add_lldb_register_index(reg_infos)
+
+ # Pull out the register infos that we think we can bit flip successfully.
+ gpr_reg_infos = [reg_info for reg_info in reg_infos if self.is_bit_flippable_register(reg_info)]
+ self.assertTrue(len(gpr_reg_infos) > 0)
+
+ # Gather thread info.
+ if with_suffix:
+ threads = self.parse_threadinfo_packets(context)
+ self.assertIsNotNone(threads)
+ thread_id = threads[0]
+ self.assertIsNotNone(thread_id)
+ # print("Running on thread: 0x{:x}".format(thread_id))
+ else:
+ thread_id = None
+
+ # Save register state.
+ self.reset_test_sequence()
+ self.add_QSaveRegisterState_packets(thread_id)
+
+ context = self.expect_gdbremote_sequence()
+ self.assertIsNotNone(context)
+
+ (success, state_id) = self.parse_QSaveRegisterState_response(context)
+ self.assertTrue(success)
+ self.assertIsNotNone(state_id)
+ # print("saved register state id: {}".format(state_id))
+
+ # Remember initial register values.
+ initial_reg_values = self.read_register_values(gpr_reg_infos, endian, thread_id=thread_id)
+ # print("initial_reg_values: {}".format(initial_reg_values))
+
+ # Flip gpr register values.
+ (successful_writes, failed_writes) = self.flip_all_bits_in_each_register_value(gpr_reg_infos, endian, thread_id=thread_id)
+ # print("successful writes: {}, failed writes: {}".format(successful_writes, failed_writes))
+ self.assertTrue(successful_writes > 0)
+
+ flipped_reg_values = self.read_register_values(gpr_reg_infos, endian, thread_id=thread_id)
+ # print("flipped_reg_values: {}".format(flipped_reg_values))
+
+ # Restore register values.
+ self.reset_test_sequence()
+ self.add_QRestoreRegisterState_packets(state_id, thread_id)
+
+ context = self.expect_gdbremote_sequence()
+ self.assertIsNotNone(context)
+
+ # Verify registers match initial register values.
+ final_reg_values = self.read_register_values(gpr_reg_infos, endian, thread_id=thread_id)
+ # print("final_reg_values: {}".format(final_reg_values))
+ self.assertIsNotNone(final_reg_values)
+ self.assertEqual(final_reg_values, initial_reg_values)
+
+ @debugserver_test
+ def test_grp_register_save_restore_works_with_suffix_debugserver(self):
+ USE_THREAD_SUFFIX = True
+ self.init_debugserver_test()
+ self.build()
+ self.set_inferior_startup_launch()
+ self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
+
+ @llgs_test
+ def test_grp_register_save_restore_works_with_suffix_llgs(self):
+ USE_THREAD_SUFFIX = True
+ self.init_llgs_test()
+ self.build()
+ self.set_inferior_startup_launch()
+ self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
+
+ @debugserver_test
+ def test_grp_register_save_restore_works_no_suffix_debugserver(self):
+ USE_THREAD_SUFFIX = False
+ self.init_debugserver_test()
+ self.build()
+ self.set_inferior_startup_launch()
+ self.grp_register_save_restore_works(USE_THREAD_SUFFIX)
+
+ @llgs_test
+ def test_grp_register_save_restore_works_no_suffix_llgs(self):
+ USE_THREAD_SUFFIX = False
+ self.init_llgs_test()
+ self.build()
+ self.set_inferior_startup_launch()
+ self.grp_register_save_restore_works(USE_THREAD_SUFFIX)