1""" 2Test watchpoint list, enable, disable, and delete commands. 3""" 4 5 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 11 12class WatchpointCommandsTestCase(TestBase): 13 NO_DEBUG_INFO_TESTCASE = True 14 15 def setUp(self): 16 # Call super's setUp(). 17 TestBase.setUp(self) 18 # Our simple source filename. 19 self.source = "main.c" 20 # Find the line number to break inside main(). 21 self.line = line_number(self.source, "// Set break point at this line.") 22 self.line2 = line_number( 23 self.source, "// Set 2nd break point for disable_then_enable test case." 24 ) 25 # And the watchpoint variable declaration line number. 26 self.decl = line_number(self.source, "// Watchpoint variable declaration.") 27 # Build dictionary to have unique executable names for each test 28 # method. 29 self.exe_name = self.testMethodName 30 self.d = {"C_SOURCES": self.source, "EXE": self.exe_name} 31 32 # Read-write watchpoints not supported on SystemZ 33 @expectedFailureAll(archs=["s390x"]) 34 def test_rw_watchpoint(self): 35 """Test read_write watchpoint and expect to stop two times.""" 36 self.build(dictionary=self.d) 37 self.setTearDownCleanup(dictionary=self.d) 38 39 exe = self.getBuildArtifact(self.exe_name) 40 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 41 42 # Add a breakpoint to set a watchpoint when stopped on the breakpoint. 43 lldbutil.run_break_set_by_file_and_line( 44 self, None, self.line, num_expected_locations=1 45 ) 46 47 # Run the program. 48 self.runCmd("run", RUN_SUCCEEDED) 49 50 # We should be stopped again due to the breakpoint. 51 # The stop reason of the thread should be breakpoint. 52 self.expect( 53 "thread list", 54 STOPPED_DUE_TO_BREAKPOINT, 55 substrs=["stopped", "stop reason = breakpoint"], 56 ) 57 58 # Now let's set a read_write-type watchpoint for 'global'. 59 # There should be two watchpoint hits (see main.c). 60 self.expect( 61 "watchpoint set variable -w read_write global", 62 WATCHPOINT_CREATED, 63 substrs=[ 64 "Watchpoint created", 65 "size = 4", 66 "type = rw", 67 "%s:%d" % (self.source, self.decl), 68 ], 69 ) 70 71 # Use the '-v' option to do verbose listing of the watchpoint. 72 # The hit count should be 0 initially. 73 self.expect( 74 "watchpoint list -v", 75 substrs=["Number of supported hardware watchpoints:", "hit_count = 0"], 76 ) 77 78 self.runCmd("process continue") 79 80 # We should be stopped again due to the watchpoint (read_write type). 81 # The stop reason of the thread should be watchpoint. 82 self.expect( 83 "thread backtrace", 84 STOPPED_DUE_TO_WATCHPOINT, 85 substrs=["stop reason = watchpoint"], 86 ) 87 88 self.runCmd("process continue") 89 90 # We should be stopped again due to the watchpoint (read_write type). 91 # The stop reason of the thread should be watchpoint. 92 self.expect( 93 "thread backtrace", 94 STOPPED_DUE_TO_WATCHPOINT, 95 substrs=["stop reason = watchpoint"], 96 ) 97 98 self.runCmd("process continue") 99 100 # There should be no more watchpoint hit and the process status should 101 # be 'exited'. 102 self.expect("process status", substrs=["exited"]) 103 104 # Use the '-v' option to do verbose listing of the watchpoint. 105 # The hit count should now be 2. 106 self.expect("watchpoint list -v", substrs=["hit_count = 2"]) 107 108 # Read-write watchpoints not supported on SystemZ 109 @expectedFailureAll(archs=["s390x"]) 110 def test_rw_watchpoint_delete(self): 111 """Test delete watchpoint and expect not to stop for watchpoint.""" 112 self.build() 113 lldbutil.run_to_line_breakpoint(self, lldb.SBFileSpec(self.source), self.line) 114 115 # Now let's set a read_write-type watchpoint for 'global'. 116 # There should be two watchpoint hits (see main.c). 117 self.expect( 118 "watchpoint set variable -w read_write global", 119 WATCHPOINT_CREATED, 120 substrs=[ 121 "Watchpoint created", 122 "size = 4", 123 "type = rw", 124 "%s:%d" % (self.source, self.decl), 125 ], 126 ) 127 128 # Delete the watchpoint immediately, but set auto-confirm to true 129 # first. 130 self.runCmd("settings set auto-confirm true") 131 self.expect("watchpoint delete", substrs=["All watchpoints removed."]) 132 # Restore the original setting of auto-confirm. 133 self.runCmd("settings clear auto-confirm") 134 135 target = self.dbg.GetSelectedTarget() 136 self.assertTrue(target and not target.GetNumWatchpoints()) 137 138 # Now let's set a read_write-type watchpoint for 'global'. 139 # There should be two watchpoint hits (see main.c). 140 self.expect( 141 "watchpoint set variable -w read_write global", 142 WATCHPOINT_CREATED, 143 substrs=[ 144 "Watchpoint created", 145 "size = 4", 146 "type = rw", 147 "%s:%d" % (self.source, self.decl), 148 ], 149 ) 150 151 # Delete the watchpoint immediately using the force option. 152 self.expect("watchpoint delete --force", substrs=["All watchpoints removed."]) 153 154 self.assertTrue(target and not target.GetNumWatchpoints()) 155 156 self.runCmd("process continue") 157 158 # There should be no more watchpoint hit and the process status should 159 # be 'exited'. 160 self.expect("process status", substrs=["exited"]) 161 162 # Read-write watchpoints not supported on SystemZ 163 @expectedFailureAll(archs=["s390x"]) 164 def test_rw_watchpoint_set_ignore_count(self): 165 """Test watchpoint ignore count and expect to not to stop at all.""" 166 self.build(dictionary=self.d) 167 self.setTearDownCleanup(dictionary=self.d) 168 169 exe = self.getBuildArtifact(self.exe_name) 170 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 171 172 # Add a breakpoint to set a watchpoint when stopped on the breakpoint. 173 lldbutil.run_break_set_by_file_and_line( 174 self, None, self.line, num_expected_locations=1 175 ) 176 177 # Run the program. 178 self.runCmd("run", RUN_SUCCEEDED) 179 180 # We should be stopped again due to the breakpoint. 181 # The stop reason of the thread should be breakpoint. 182 self.expect( 183 "thread list", 184 STOPPED_DUE_TO_BREAKPOINT, 185 substrs=["stopped", "stop reason = breakpoint"], 186 ) 187 188 # Now let's set a read_write-type watchpoint for 'global'. 189 # There should be two watchpoint hits (see main.c). 190 self.expect( 191 "watchpoint set variable -w read_write global", 192 WATCHPOINT_CREATED, 193 substrs=[ 194 "Watchpoint created", 195 "size = 4", 196 "type = rw", 197 "%s:%d" % (self.source, self.decl), 198 ], 199 ) 200 201 # Set the ignore count of the watchpoint immediately. 202 self.expect("watchpoint ignore -i 2", substrs=["All watchpoints ignored."]) 203 204 # Use the '-v' option to do verbose listing of the watchpoint. 205 # Expect to find an ignore_count of 2. 206 self.expect("watchpoint list -v", substrs=["hit_count = 0", "ignore_count = 2"]) 207 208 self.runCmd("process continue") 209 210 # There should be no more watchpoint hit and the process status should 211 # be 'exited'. 212 self.expect("process status", substrs=["exited"]) 213 214 # Use the '-v' option to do verbose listing of the watchpoint. 215 # Expect to find a hit_count of 2 as well. 216 self.expect("watchpoint list -v", substrs=["hit_count = 2", "ignore_count = 2"]) 217 218 # Read-write watchpoints not supported on SystemZ 219 @expectedFailureAll(archs=["s390x"]) 220 def test_rw_disable_after_first_stop(self): 221 """Test read_write watchpoint but disable it after the first stop.""" 222 self.build(dictionary=self.d) 223 self.setTearDownCleanup(dictionary=self.d) 224 225 exe = self.getBuildArtifact(self.exe_name) 226 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 227 228 # Add a breakpoint to set a watchpoint when stopped on the breakpoint. 229 lldbutil.run_break_set_by_file_and_line( 230 self, None, self.line, num_expected_locations=1 231 ) 232 233 # Run the program. 234 self.runCmd("run", RUN_SUCCEEDED) 235 236 # We should be stopped again due to the breakpoint. 237 # The stop reason of the thread should be breakpoint. 238 self.expect( 239 "thread list", 240 STOPPED_DUE_TO_BREAKPOINT, 241 substrs=["stopped", "stop reason = breakpoint"], 242 ) 243 244 # Now let's set a read_write-type watchpoint for 'global'. 245 # There should be two watchpoint hits (see main.c). 246 self.expect( 247 "watchpoint set variable -w read_write global", 248 WATCHPOINT_CREATED, 249 substrs=[ 250 "Watchpoint created", 251 "size = 4", 252 "type = rw", 253 "%s:%d" % (self.source, self.decl), 254 ], 255 ) 256 257 # Use the '-v' option to do verbose listing of the watchpoint. 258 # The hit count should be 0 initially. 259 self.expect("watchpoint list -v", substrs=["state = enabled", "hit_count = 0"]) 260 261 self.runCmd("process continue") 262 263 # We should be stopped again due to the watchpoint (read_write type). 264 # The stop reason of the thread should be watchpoint. 265 self.expect( 266 "thread backtrace", 267 STOPPED_DUE_TO_WATCHPOINT, 268 substrs=["stop reason = watchpoint"], 269 ) 270 271 # Before continuing, we'll disable the watchpoint, which means we won't 272 # stop again after this. 273 self.runCmd("watchpoint disable") 274 275 self.expect("watchpoint list -v", substrs=["state = disabled", "hit_count = 1"]) 276 277 self.runCmd("process continue") 278 279 # There should be no more watchpoint hit and the process status should 280 # be 'exited'. 281 self.expect("process status", substrs=["exited"]) 282 283 # Use the '-v' option to do verbose listing of the watchpoint. 284 # The hit count should be 1. 285 self.expect("watchpoint list -v", substrs=["hit_count = 1"]) 286 287 # Read-write watchpoints not supported on SystemZ 288 @expectedFailureAll(archs=["s390x"]) 289 def test_rw_disable_then_enable(self): 290 """Test read_write watchpoint, disable initially, then enable it.""" 291 self.build(dictionary=self.d) 292 self.setTearDownCleanup(dictionary=self.d) 293 294 exe = self.getBuildArtifact(self.exe_name) 295 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 296 297 # Add a breakpoint to set a watchpoint when stopped on the breakpoint. 298 lldbutil.run_break_set_by_file_and_line( 299 self, None, self.line, num_expected_locations=1 300 ) 301 lldbutil.run_break_set_by_file_and_line( 302 self, None, self.line2, num_expected_locations=1 303 ) 304 305 # Run the program. 306 self.runCmd("run", RUN_SUCCEEDED) 307 308 # We should be stopped again due to the breakpoint. 309 # The stop reason of the thread should be breakpoint. 310 self.expect( 311 "thread list", 312 STOPPED_DUE_TO_BREAKPOINT, 313 substrs=["stopped", "stop reason = breakpoint"], 314 ) 315 316 # Now let's set a read_write-type watchpoint for 'global'. 317 # There should be two watchpoint hits (see main.c). 318 self.expect( 319 "watchpoint set variable -w read_write global", 320 WATCHPOINT_CREATED, 321 substrs=[ 322 "Watchpoint created", 323 "size = 4", 324 "type = rw", 325 "%s:%d" % (self.source, self.decl), 326 ], 327 ) 328 329 # Immediately, we disable the watchpoint. We won't be stopping due to a 330 # watchpoint after this. 331 self.runCmd("watchpoint disable") 332 333 # Use the '-v' option to do verbose listing of the watchpoint. 334 # The hit count should be 0 initially. 335 self.expect("watchpoint list -v", substrs=["state = disabled", "hit_count = 0"]) 336 337 self.runCmd("process continue") 338 339 # We should be stopped again due to the breakpoint. 340 self.expect( 341 "thread backtrace", 342 STOPPED_DUE_TO_BREAKPOINT, 343 substrs=["stop reason = breakpoint"], 344 ) 345 346 # Before continuing, we'll enable the watchpoint, which means we will 347 # stop again after this. 348 self.runCmd("watchpoint enable") 349 350 self.expect("watchpoint list -v", substrs=["state = enabled", "hit_count = 0"]) 351 352 self.runCmd("process continue") 353 354 # We should be stopped again due to the watchpoint (read_write type). 355 # The stop reason of the thread should be watchpoint. 356 self.expect( 357 "thread backtrace", 358 STOPPED_DUE_TO_WATCHPOINT, 359 substrs=["stop reason = watchpoint"], 360 ) 361 362 self.runCmd("process continue") 363 364 # There should be no more watchpoint hit and the process status should 365 # be 'exited'. 366 self.expect("process status", substrs=["exited"]) 367 368 # Use the '-v' option to do verbose listing of the watchpoint. 369 # The hit count should be 1. 370 self.expect("watchpoint list -v", substrs=["hit_count = 1"]) 371