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