""" Watch contiguous memory regions with separate watchpoints, check that lldb correctly detect which watchpoint was hit for each one. """ import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil class ConsecutiveWatchpointsTestCase(TestBase): NO_DEBUG_INFO_TESTCASE = True def continue_and_report_stop_reason(self, process, iter_str): process.Continue() self.assertIn( process.GetState(), [lldb.eStateStopped, lldb.eStateExited], iter_str ) thread = process.GetSelectedThread() return thread.GetStopReason() # debugserver only gained the ability to watch larger regions # with this patch. @skipIfOutOfTreeDebugserver def test_consecutive_watchpoints(self): """Test watchpoint that covers a large region of memory.""" self.build() self.main_source_file = lldb.SBFileSpec("main.c") (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( self, "break here", self.main_source_file ) frame = thread.GetFrameAtIndex(0) field2_wp = ( frame.locals["var"][0] .GetChildMemberWithName("field2") .Watch(True, False, True) ) field3_wp = ( frame.locals["var"][0] .GetChildMemberWithName("field3") .Watch(True, False, True) ) field4_wp = ( frame.locals["var"][0] .GetChildMemberWithName("field4") .Watch(True, False, True) ) field5_wp = ( frame.locals["var"][0] .GetChildMemberWithName("field5") .Watch(True, False, True) ) # Require that the first two watchpoints # are set -- hopefully every machine running # the testsuite can support two watchpoints. self.assertTrue(field2_wp.IsValid()) self.assertTrue(field3_wp.IsValid()) reason = self.continue_and_report_stop_reason(process, "continue to field2 wp") self.assertEqual(reason, lldb.eStopReasonWatchpoint) stop_reason_watchpoint_id = ( process.GetSelectedThread().GetStopReasonDataAtIndex(0) ) self.assertEqual(stop_reason_watchpoint_id, field2_wp.GetID()) reason = self.continue_and_report_stop_reason(process, "continue to field3 wp") self.assertEqual(reason, lldb.eStopReasonWatchpoint) stop_reason_watchpoint_id = ( process.GetSelectedThread().GetStopReasonDataAtIndex(0) ) self.assertEqual(stop_reason_watchpoint_id, field3_wp.GetID()) # If we were able to set the second two watchpoints, # check that they are hit. Some CI bots can only # create two watchpoints. if field4_wp.IsValid() and field5_wp.IsValid(): reason = self.continue_and_report_stop_reason( process, "continue to field4 wp" ) self.assertEqual(reason, lldb.eStopReasonWatchpoint) stop_reason_watchpoint_id = ( process.GetSelectedThread().GetStopReasonDataAtIndex(0) ) self.assertEqual(stop_reason_watchpoint_id, field4_wp.GetID()) reason = self.continue_and_report_stop_reason( process, "continue to field5 wp" ) self.assertEqual(reason, lldb.eStopReasonWatchpoint) stop_reason_watchpoint_id = ( process.GetSelectedThread().GetStopReasonDataAtIndex(0) ) self.assertEqual(stop_reason_watchpoint_id, field5_wp.GetID())