1""" 2Test that a variable watchpoint should only hit when in scope. 3""" 4 5 6import lldb 7from lldbsuite.test.lldbtest import * 8import lldbsuite.test.lldbutil as lldbutil 9from lldbsuite.test.decorators import * 10 11 12class WatchedVariableHitWhenInScopeTestCase(TestBase): 13 NO_DEBUG_INFO_TESTCASE = True 14 15 # This test depends on not tracking watchpoint expression hits if we have 16 # left the watchpoint scope. We will provide such an ability at some point 17 # but the way this was done was incorrect, and it is unclear that for the 18 # most part that's not what folks mostly want, so we have to provide a 19 # clearer API to express this. 20 21 def setUp(self): 22 # Call super's setUp(). 23 TestBase.setUp(self) 24 # Our simple source filename. 25 self.source = "main.c" 26 self.exe_name = self.testMethodName 27 self.d = {"C_SOURCES": self.source, "EXE": self.exe_name} 28 29 # Test hangs due to a kernel bug, see fdfeff0f in the linux kernel for details 30 @skipIfTargetAndroid(api_levels=list(range(25 + 1)), archs=["aarch64", "arm"]) 31 @skipIf 32 def test_watched_var_should_only_hit_when_in_scope(self): 33 """Test that a variable watchpoint should only hit when in scope.""" 34 self.build(dictionary=self.d) 35 self.setTearDownCleanup(dictionary=self.d) 36 37 exe = self.getBuildArtifact(self.exe_name) 38 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 39 40 # Add a breakpoint to set a watchpoint when stopped in main. 41 lldbutil.run_break_set_by_symbol(self, "main", num_expected_locations=-1) 42 43 # Run the program. 44 self.runCmd("run", RUN_SUCCEEDED) 45 46 # We should be stopped again due to the breakpoint. 47 # The stop reason of the thread should be breakpoint. 48 self.expect( 49 "thread list", 50 STOPPED_DUE_TO_BREAKPOINT, 51 substrs=["stopped", "stop reason = breakpoint"], 52 ) 53 54 # Now let's set a watchpoint for 'c.a'. 55 # There should be only one watchpoint hit (see main.c). 56 self.expect( 57 "watchpoint set variable c.a", 58 WATCHPOINT_CREATED, 59 substrs=["Watchpoint created", "size = 4", "type = w"], 60 ) 61 62 # Use the '-v' option to do verbose listing of the watchpoint. 63 # The hit count should be 0 initially. 64 self.expect("watchpoint list -v", substrs=["hit_count = 0"]) 65 66 self.runCmd("process continue") 67 68 # We should be stopped again due to the watchpoint (write type), but 69 # only once. The stop reason of the thread should be watchpoint. 70 self.expect( 71 "thread list", 72 STOPPED_DUE_TO_WATCHPOINT, 73 substrs=["stopped", "stop reason = watchpoint"], 74 ) 75 76 self.runCmd("process continue") 77 # Don't expect the read of 'global' to trigger a stop exception. 78 # The process status should be 'exited'. 79 self.expect("process status", substrs=["exited"]) 80 81 # Use the '-v' option to do verbose listing of the watchpoint. 82 # The hit count should now be 1. 83 self.expect("watchpoint list -v", substrs=["hit_count = 1"]) 84