1"""Test that adding, deleting and modifying watchpoints sends the appropriate events.""" 2 3import lldb 4from lldbsuite.test.decorators import * 5from lldbsuite.test.lldbtest import * 6from lldbsuite.test import lldbutil 7 8 9class TestWatchpointEvents(TestBase): 10 NO_DEBUG_INFO_TESTCASE = True 11 12 def setUp(self): 13 # Call super's setUp(). 14 TestBase.setUp(self) 15 # Find the line numbers that we will step to in main: 16 self.main_source = "main.c" 17 18 @add_test_categories(["pyapi"]) 19 def test_with_python_api(self): 20 """Test that adding, deleting and modifying watchpoints sends the appropriate events.""" 21 self.build() 22 target = self.createTestTarget() 23 24 self.main_source_spec = lldb.SBFileSpec(self.main_source) 25 26 break_in_main = target.BreakpointCreateBySourceRegex( 27 "// Put a breakpoint here.", self.main_source_spec 28 ) 29 self.assertTrue(break_in_main, VALID_BREAKPOINT) 30 31 # Now launch the process, and do not stop at entry point. 32 process = target.LaunchSimple(None, None, self.get_process_working_directory()) 33 34 self.assertTrue(process, PROCESS_IS_VALID) 35 36 # The stop reason of the thread should be breakpoint. 37 threads = lldbutil.get_threads_stopped_at_breakpoint(process, break_in_main) 38 39 if len(threads) != 1: 40 self.fail("Failed to stop at first breakpoint in main.") 41 42 thread = threads[0] 43 frame = thread.GetFrameAtIndex(0) 44 local_var = frame.FindVariable("local_var") 45 self.assertTrue(local_var.IsValid()) 46 47 self.listener = lldb.SBListener("com.lldb.testsuite_listener") 48 self.target_bcast = target.GetBroadcaster() 49 self.target_bcast.AddListener( 50 self.listener, lldb.SBTarget.eBroadcastBitWatchpointChanged 51 ) 52 self.listener.StartListeningForEvents( 53 self.target_bcast, lldb.SBTarget.eBroadcastBitWatchpointChanged 54 ) 55 56 error = lldb.SBError() 57 local_watch = local_var.Watch(True, False, True, error) 58 if not error.Success(): 59 self.fail( 60 "Failed to make watchpoint for local_var: %s" % (error.GetCString()) 61 ) 62 63 self.GetWatchpointEvent(lldb.eWatchpointEventTypeAdded) 64 # Now change some of the features of this watchpoint and make sure we 65 # get events: 66 local_watch.SetEnabled(False) 67 self.GetWatchpointEvent(lldb.eWatchpointEventTypeDisabled) 68 69 local_watch.SetEnabled(True) 70 self.GetWatchpointEvent(lldb.eWatchpointEventTypeEnabled) 71 72 local_watch.SetIgnoreCount(10) 73 self.GetWatchpointEvent(lldb.eWatchpointEventTypeIgnoreChanged) 74 75 condition = "1 == 2" 76 local_watch.SetCondition(condition) 77 self.GetWatchpointEvent(lldb.eWatchpointEventTypeConditionChanged) 78 79 self.assertEqual( 80 local_watch.GetCondition(), 81 condition, 82 'make sure watchpoint condition is "' + condition + '"', 83 ) 84 85 def GetWatchpointEvent(self, event_type): 86 # We added a watchpoint so we should get a watchpoint added event. 87 event = lldb.SBEvent() 88 success = self.listener.WaitForEvent(1, event) 89 self.assertTrue(success, "Successfully got watchpoint event") 90 self.assertTrue( 91 lldb.SBWatchpoint.EventIsWatchpointEvent(event), 92 "Event is a watchpoint event.", 93 ) 94 found_type = lldb.SBWatchpoint.GetWatchpointEventTypeFromEvent(event) 95 self.assertEqual( 96 found_type, 97 event_type, 98 "Event is not correct type, expected: %d, found: %d" 99 % (event_type, found_type), 100 ) 101 # There shouldn't be another event waiting around: 102 found_event = self.listener.PeekAtNextEventForBroadcasterWithType( 103 self.target_bcast, lldb.SBTarget.eBroadcastBitBreakpointChanged, event 104 ) 105 if found_event: 106 print("Found an event I didn't expect: ", event) 107 108 self.assertTrue(not found_event, "Only one event per change.") 109