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