1""" 2Test lldb watchpoint that uses 'watchpoint set -w write -s size' to watch a pointed location with size. 3""" 4 5 6 7import lldb 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10from lldbsuite.test import lldbutil 11 12 13class WatchLocationUsingWatchpointSetTestCase(TestBase): 14 15 mydir = TestBase.compute_mydir(__file__) 16 NO_DEBUG_INFO_TESTCASE = True 17 18 def setUp(self): 19 # Call super's setUp(). 20 TestBase.setUp(self) 21 # Our simple source filename. 22 self.source = 'main.cpp' 23 # Find the line number to break inside main(). 24 self.line = line_number( 25 self.source, '// Set break point at this line.') 26 # This is for verifying that watch location works. 27 self.violating_func = "do_bad_thing_with_location" 28 # Build dictionary to have unique executable names for each test 29 # method. 30 31 @skipIf( 32 oslist=["linux"], 33 archs=[ 34 'aarch64', 35 'arm'], 36 bugnumber="llvm.org/pr26031") 37 @skipIfWindows # This test is flaky on Windows 38 def test_watchlocation_using_watchpoint_set(self): 39 """Test watching a location with 'watchpoint set expression -w write -s size' option.""" 40 self.build() 41 self.setTearDownCleanup() 42 43 exe = self.getBuildArtifact("a.out") 44 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 45 46 # Add a breakpoint to set a watchpoint when stopped on the breakpoint. 47 lldbutil.run_break_set_by_file_and_line( 48 self, None, self.line, num_expected_locations=1) 49 50 # Run the program. 51 self.runCmd("run", RUN_SUCCEEDED) 52 53 # We should be stopped again due to the breakpoint. 54 # The stop reason of the thread should be breakpoint. 55 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 56 substrs=['stopped', 57 'stop reason = breakpoint']) 58 59 # Now let's set a write-type watchpoint pointed to by 'g_char_ptr' and 60 # with offset as 7. 61 # The main.cpp, by design, misbehaves by not following the agreed upon 62 # protocol of only accessing the allowable index range of [0, 6]. 63 self.expect( 64 "watchpoint set expression -w write -s 1 -- g_char_ptr + 7", 65 WATCHPOINT_CREATED, 66 substrs=[ 67 'Watchpoint created', 68 'size = 1', 69 'type = w']) 70 self.runCmd("expr unsigned val = g_char_ptr[7]; val") 71 self.expect(self.res.GetOutput().splitlines()[0], exe=False, 72 endstr=' = 0') 73 74 # Use the '-v' option to do verbose listing of the watchpoint. 75 # The hit count should be 0 initially. 76 self.expect("watchpoint list -v", 77 substrs=['hit_count = 0']) 78 79 self.runCmd("process continue") 80 81 # We should be stopped again due to the watchpoint (write type), but 82 # only once. The stop reason of the thread should be watchpoint. 83 self.expect( 84 "thread list", 85 STOPPED_DUE_TO_WATCHPOINT, 86 substrs=[ 87 'stopped', 88 self.violating_func, 89 'stop reason = watchpoint', 90 ]) 91 92 # Switch to the thread stopped due to watchpoint and issue some 93 # commands. 94 self.switch_to_thread_with_stop_reason(lldb.eStopReasonWatchpoint) 95 self.runCmd("thread backtrace") 96 self.runCmd("expr unsigned val = g_char_ptr[7]; val") 97 self.expect(self.res.GetOutput().splitlines()[0], exe=False, 98 endstr=' = 99') 99 100 # Use the '-v' option to do verbose listing of the watchpoint. 101 # The hit count should now be the same as the number of threads that 102 # stopped on a watchpoint. 103 threads = lldbutil.get_stopped_threads( 104 self.process(), lldb.eStopReasonWatchpoint) 105 self.expect("watchpoint list -v", 106 substrs=['hit_count = %d' % len(threads)]) 107 108 self.runCmd("thread backtrace all") 109