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