1""" 2Test that lldb watchpoint works for multiple threads. 3""" 4 5from __future__ import print_function 6 7 8import re 9import lldb 10from lldbsuite.test.decorators import * 11from lldbsuite.test.lldbtest import * 12from lldbsuite.test import lldbutil 13 14 15class WatchpointForMultipleThreadsTestCase(TestBase): 16 17 mydir = TestBase.compute_mydir(__file__) 18 NO_DEBUG_INFO_TESTCASE = True 19 main_spec = lldb.SBFileSpec("main.cpp", False) 20 21 @skipIfWindows # This test is flaky on Windows 22 def test_watchpoint_before_thread_start(self): 23 """Test that we can hit a watchpoint we set before starting another thread""" 24 self.do_watchpoint_test("Before running the thread") 25 26 def test_watchpoint_after_thread_launch(self): 27 """Test that we can hit a watchpoint we set after launching another thread""" 28 self.do_watchpoint_test("After launching the thread") 29 30 def test_watchpoint_after_thread_start(self): 31 """Test that we can hit a watchpoint we set after another thread starts""" 32 self.do_watchpoint_test("After running the thread") 33 34 def do_watchpoint_test(self, line): 35 self.build() 36 lldbutil.run_to_source_breakpoint(self, line, self.main_spec) 37 38 # Now let's set a write-type watchpoint for variable 'g_val'. 39 self.expect( 40 "watchpoint set variable -w write g_val", 41 WATCHPOINT_CREATED, 42 substrs=[ 43 'Watchpoint created', 44 'size = 4', 45 'type = w']) 46 47 # Use the '-v' option to do verbose listing of the watchpoint. 48 # The hit count should be 0 initially. 49 self.expect("watchpoint list -v", 50 substrs=['hit_count = 0']) 51 52 self.runCmd("process continue") 53 54 self.runCmd("thread list") 55 if "stop reason = watchpoint" in self.res.GetOutput(): 56 # Good, we verified that the watchpoint works! 57 self.runCmd("thread backtrace all") 58 else: 59 self.fail("The stop reason should be either break or watchpoint") 60 61 # Use the '-v' option to do verbose listing of the watchpoint. 62 # The hit count should now be 1. 63 self.expect("watchpoint list -v", 64 substrs=['hit_count = 1']) 65 66 def test_watchpoint_multiple_threads_wp_set_and_then_delete(self): 67 """Test that lldb watchpoint works for multiple threads, and after the watchpoint is deleted, the watchpoint event should no longer fires.""" 68 self.build() 69 self.setTearDownCleanup() 70 71 lldbutil.run_to_source_breakpoint(self, "After running the thread", self.main_spec) 72 73 # Now let's set a write-type watchpoint for variable 'g_val'. 74 self.expect( 75 "watchpoint set variable -w write g_val", 76 WATCHPOINT_CREATED, 77 substrs=[ 78 'Watchpoint created', 79 'size = 4', 80 'type = w']) 81 82 # Use the '-v' option to do verbose listing of the watchpoint. 83 # The hit count should be 0 initially. 84 self.expect("watchpoint list -v", 85 substrs=['hit_count = 0']) 86 87 watchpoint_stops = 0 88 while True: 89 self.runCmd("process continue") 90 self.runCmd("process status") 91 if re.search("Process .* exited", self.res.GetOutput()): 92 # Great, we are done with this test! 93 break 94 95 self.runCmd("thread list") 96 if "stop reason = watchpoint" in self.res.GetOutput(): 97 self.runCmd("thread backtrace all") 98 watchpoint_stops += 1 99 if watchpoint_stops > 1: 100 self.fail( 101 "Watchpoint hits not supposed to exceed 1 by design!") 102 # Good, we verified that the watchpoint works! Now delete the 103 # watchpoint. 104 if self.TraceOn(): 105 print( 106 "watchpoint_stops=%d at the moment we delete the watchpoint" % 107 watchpoint_stops) 108 self.runCmd("watchpoint delete 1") 109 self.expect("watchpoint list -v", 110 substrs=['No watchpoints currently set.']) 111 continue 112 else: 113 self.fail("The stop reason should be either break or watchpoint") 114