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