199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest that lldb watchpoint works for multiple threads. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprechtfrom __future__ import print_function 699451b44SJordan Rupprecht 799451b44SJordan Rupprecht 899451b44SJordan Rupprechtimport re 999451b44SJordan Rupprechtimport lldb 1099451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 1199451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1299451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 1399451b44SJordan Rupprecht 1499451b44SJordan Rupprecht 1599451b44SJordan Rupprechtclass WatchpointForMultipleThreadsTestCase(TestBase): 1699451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1799451b44SJordan Rupprecht main_spec = lldb.SBFileSpec("main.cpp", False) 1899451b44SJordan Rupprecht 198fec756cSStella Stamenova @skipIfWindows # This test is flaky on Windows 2099451b44SJordan Rupprecht def test_watchpoint_before_thread_start(self): 2199451b44SJordan Rupprecht """Test that we can hit a watchpoint we set before starting another thread""" 2299451b44SJordan Rupprecht self.do_watchpoint_test("Before running the thread") 2399451b44SJordan Rupprecht 24*df13239cSMuhammad Omair Javaid @skipIfWindows # This test is flaky on Windows 257e2ef84fSMichał Górny def test_watchpoint_after_thread_launch(self): 267e2ef84fSMichał Górny """Test that we can hit a watchpoint we set after launching another thread""" 277e2ef84fSMichał Górny self.do_watchpoint_test("After launching the thread") 287e2ef84fSMichał Górny 2999451b44SJordan Rupprecht def test_watchpoint_after_thread_start(self): 307e2ef84fSMichał Górny """Test that we can hit a watchpoint we set after another thread starts""" 3199451b44SJordan Rupprecht self.do_watchpoint_test("After running the thread") 3299451b44SJordan Rupprecht 3399451b44SJordan Rupprecht def do_watchpoint_test(self, line): 3499451b44SJordan Rupprecht self.build() 3599451b44SJordan Rupprecht lldbutil.run_to_source_breakpoint(self, line, self.main_spec) 3699451b44SJordan Rupprecht 3799451b44SJordan Rupprecht # Now let's set a write-type watchpoint for variable 'g_val'. 3899451b44SJordan Rupprecht self.expect( 3999451b44SJordan Rupprecht "watchpoint set variable -w write g_val", 4099451b44SJordan Rupprecht WATCHPOINT_CREATED, 4199451b44SJordan Rupprecht substrs=[ 4299451b44SJordan Rupprecht 'Watchpoint created', 4399451b44SJordan Rupprecht 'size = 4', 4499451b44SJordan Rupprecht 'type = w']) 4599451b44SJordan Rupprecht 4699451b44SJordan Rupprecht # Use the '-v' option to do verbose listing of the watchpoint. 4799451b44SJordan Rupprecht # The hit count should be 0 initially. 4899451b44SJordan Rupprecht self.expect("watchpoint list -v", 4999451b44SJordan Rupprecht substrs=['hit_count = 0']) 5099451b44SJordan Rupprecht 5199451b44SJordan Rupprecht self.runCmd("process continue") 5299451b44SJordan Rupprecht 5399451b44SJordan Rupprecht self.runCmd("thread list") 5499451b44SJordan Rupprecht if "stop reason = watchpoint" in self.res.GetOutput(): 5599451b44SJordan Rupprecht # Good, we verified that the watchpoint works! 5699451b44SJordan Rupprecht self.runCmd("thread backtrace all") 5799451b44SJordan Rupprecht else: 5899451b44SJordan Rupprecht self.fail("The stop reason should be either break or watchpoint") 5999451b44SJordan Rupprecht 6099451b44SJordan Rupprecht # Use the '-v' option to do verbose listing of the watchpoint. 6199451b44SJordan Rupprecht # The hit count should now be 1. 6299451b44SJordan Rupprecht self.expect("watchpoint list -v", 6399451b44SJordan Rupprecht substrs=['hit_count = 1']) 6499451b44SJordan Rupprecht 6599451b44SJordan Rupprecht def test_watchpoint_multiple_threads_wp_set_and_then_delete(self): 6699451b44SJordan Rupprecht """Test that lldb watchpoint works for multiple threads, and after the watchpoint is deleted, the watchpoint event should no longer fires.""" 6799451b44SJordan Rupprecht self.build() 6899451b44SJordan Rupprecht self.setTearDownCleanup() 6999451b44SJordan Rupprecht 7099451b44SJordan Rupprecht lldbutil.run_to_source_breakpoint(self, "After running the thread", self.main_spec) 7199451b44SJordan Rupprecht 7299451b44SJordan Rupprecht # Now let's set a write-type watchpoint for variable 'g_val'. 7399451b44SJordan Rupprecht self.expect( 7499451b44SJordan Rupprecht "watchpoint set variable -w write g_val", 7599451b44SJordan Rupprecht WATCHPOINT_CREATED, 7699451b44SJordan Rupprecht substrs=[ 7799451b44SJordan Rupprecht 'Watchpoint created', 7899451b44SJordan Rupprecht 'size = 4', 7999451b44SJordan Rupprecht 'type = w']) 8099451b44SJordan Rupprecht 8199451b44SJordan Rupprecht # Use the '-v' option to do verbose listing of the watchpoint. 8299451b44SJordan Rupprecht # The hit count should be 0 initially. 8399451b44SJordan Rupprecht self.expect("watchpoint list -v", 8499451b44SJordan Rupprecht substrs=['hit_count = 0']) 8599451b44SJordan Rupprecht 8699451b44SJordan Rupprecht watchpoint_stops = 0 8799451b44SJordan Rupprecht while True: 8899451b44SJordan Rupprecht self.runCmd("process continue") 8999451b44SJordan Rupprecht self.runCmd("process status") 9099451b44SJordan Rupprecht if re.search("Process .* exited", self.res.GetOutput()): 9199451b44SJordan Rupprecht # Great, we are done with this test! 9299451b44SJordan Rupprecht break 9399451b44SJordan Rupprecht 9499451b44SJordan Rupprecht self.runCmd("thread list") 9599451b44SJordan Rupprecht if "stop reason = watchpoint" in self.res.GetOutput(): 9699451b44SJordan Rupprecht self.runCmd("thread backtrace all") 9799451b44SJordan Rupprecht watchpoint_stops += 1 9899451b44SJordan Rupprecht if watchpoint_stops > 1: 9999451b44SJordan Rupprecht self.fail( 10099451b44SJordan Rupprecht "Watchpoint hits not supposed to exceed 1 by design!") 10199451b44SJordan Rupprecht # Good, we verified that the watchpoint works! Now delete the 10299451b44SJordan Rupprecht # watchpoint. 10399451b44SJordan Rupprecht if self.TraceOn(): 10499451b44SJordan Rupprecht print( 10599451b44SJordan Rupprecht "watchpoint_stops=%d at the moment we delete the watchpoint" % 10699451b44SJordan Rupprecht watchpoint_stops) 10799451b44SJordan Rupprecht self.runCmd("watchpoint delete 1") 10899451b44SJordan Rupprecht self.expect("watchpoint list -v", 10999451b44SJordan Rupprecht substrs=['No watchpoints currently set.']) 11099451b44SJordan Rupprecht continue 11199451b44SJordan Rupprecht else: 11299451b44SJordan Rupprecht self.fail("The stop reason should be either break or watchpoint") 113