1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
from __future__ import print_function
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestGdbRemoteRegisterState(gdbremote_testcase.GdbRemoteTestCaseBase):
"""Test QSaveRegisterState/QRestoreRegisterState support."""
mydir = TestBase.compute_mydir(__file__)
@skipIfDarwinEmbedded # <rdar://problem/34539270> lldb-server tests not updated to work on ios etc yet
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": self.maybe_strict_output_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)
|