
Summary: On some android targets, a binary can produce additional garbage (e.g. warning messages from the dynamic linker) on the standard error, which confuses some tests. This relaxes the stderr expectations for targets known for their chattyness. Reviewers: tfiala, ovyalov Subscribers: tberghammer, danalbert, srhines, lldb-commits Differential Revision: http://reviews.llvm.org/D19114 llvm-svn: 266326
129 lines
5.0 KiB
Python
129 lines
5.0 KiB
Python
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__)
|
|
|
|
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)
|