1""" 2Test some target commands: create, list, select, variable. 3""" 4 5import os 6import stat 7import tempfile 8 9import lldb 10from lldbsuite.test.decorators import * 11from lldbsuite.test.lldbtest import * 12from lldbsuite.test import lldbutil 13 14 15class targetCommandTestCase(TestBase): 16 17 mydir = TestBase.compute_mydir(__file__) 18 19 def setUp(self): 20 # Call super's setUp(). 21 TestBase.setUp(self) 22 # Find the line numbers for our breakpoints. 23 self.line_b = line_number('b.c', '// Set break point at this line.') 24 self.line_c = line_number('c.c', '// Set break point at this line.') 25 26 def buildB(self): 27 db = {'C_SOURCES': 'b.c', 'EXE': self.getBuildArtifact('b.out')} 28 self.build(dictionary=db) 29 self.addTearDownCleanup(dictionary=db) 30 31 def buildAll(self): 32 da = {'C_SOURCES': 'a.c', 'EXE': self.getBuildArtifact('a.out')} 33 self.build(dictionary=da) 34 self.addTearDownCleanup(dictionary=da) 35 36 self.buildB() 37 38 dc = {'C_SOURCES': 'c.c', 'EXE': self.getBuildArtifact('c.out')} 39 self.build(dictionary=dc) 40 self.addTearDownCleanup(dictionary=dc) 41 42 def test_target_command(self): 43 """Test some target commands: create, list, select.""" 44 self.buildAll() 45 self.do_target_command() 46 47 @expectedFailureAll(archs=['arm64e']) # <rdar://problem/37773624> 48 def test_target_variable_command(self): 49 """Test 'target variable' command before and after starting the inferior.""" 50 d = {'C_SOURCES': 'globals.c', 'EXE': self.getBuildArtifact('globals')} 51 self.build(dictionary=d) 52 self.addTearDownCleanup(dictionary=d) 53 54 self.do_target_variable_command('globals') 55 56 @expectedFailureAll(archs=['arm64e']) # <rdar://problem/37773624> 57 def test_target_variable_command_no_fail(self): 58 """Test 'target variable' command before and after starting the inferior.""" 59 d = {'C_SOURCES': 'globals.c', 'EXE': self.getBuildArtifact('globals')} 60 self.build(dictionary=d) 61 self.addTearDownCleanup(dictionary=d) 62 63 self.do_target_variable_command_no_fail('globals') 64 65 def do_target_command(self): 66 """Exercise 'target create', 'target list', 'target select' commands.""" 67 exe_a = self.getBuildArtifact("a.out") 68 exe_b = self.getBuildArtifact("b.out") 69 exe_c = self.getBuildArtifact("c.out") 70 71 self.runCmd("target list") 72 output = self.res.GetOutput() 73 if output.startswith("No targets"): 74 # We start from index 0. 75 base = 0 76 else: 77 # Find the largest index of the existing list. 78 import re 79 pattern = re.compile("target #(\d+):") 80 for line in reversed(output.split(os.linesep)): 81 match = pattern.search(line) 82 if match: 83 # We will start from (index + 1) .... 84 base = int(match.group(1), 10) + 1 85 self.trace("base is:", base) 86 break 87 88 self.runCmd("target create " + exe_a, CURRENT_EXECUTABLE_SET) 89 self.runCmd("run", RUN_SUCCEEDED) 90 91 self.runCmd("target create " + exe_b, CURRENT_EXECUTABLE_SET) 92 lldbutil.run_break_set_by_file_and_line( 93 self, 'b.c', self.line_b, num_expected_locations=1, loc_exact=True) 94 self.runCmd("run", RUN_SUCCEEDED) 95 96 self.runCmd("target create " + exe_c, CURRENT_EXECUTABLE_SET) 97 lldbutil.run_break_set_by_file_and_line( 98 self, 'c.c', self.line_c, num_expected_locations=1, loc_exact=True) 99 self.runCmd("run", RUN_SUCCEEDED) 100 101 self.runCmd("target list") 102 103 self.runCmd("target select %d" % base) 104 self.runCmd("thread backtrace") 105 106 self.runCmd("target select %d" % (base + 2)) 107 self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT, 108 substrs=['stop reason = breakpoint' ,'c.c:%d' % self.line_c 109 ]) 110 111 self.runCmd("target select %d" % (base + 1)) 112 self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT, 113 substrs=['stop reason = breakpoint', 'b.c:%d' % self.line_b 114 ]) 115 116 self.runCmd("target list") 117 118 @no_debug_info_test 119 def test_target_create_invalid_arch(self): 120 exe = self.getBuildArtifact("a.out") 121 self.expect("target create {} --arch doesntexist".format(exe), error=True, 122 patterns=["error: invalid triple 'doesntexist'"]) 123 124 @no_debug_info_test 125 def test_target_create_platform(self): 126 self.buildB() 127 exe = self.getBuildArtifact("b.out") 128 self.expect("target create {} --platform host".format(exe)) 129 130 @no_debug_info_test 131 def test_target_create_unsupported_platform(self): 132 yaml = os.path.join(self.getSourceDir(), "bogus.yaml") 133 exe = self.getBuildArtifact("bogus") 134 self.yaml2obj(yaml, exe) 135 self.expect("target create {}".format(exe), error=True, 136 patterns=['error: no matching platforms found for this file']) 137 138 @no_debug_info_test 139 def test_target_create_invalid_platform(self): 140 self.buildB() 141 exe = self.getBuildArtifact("b.out") 142 self.expect("target create {} --platform doesntexist".format(exe), error=True, 143 patterns=['error: unable to find a plug-in for the platform named "doesntexist"']) 144 145 def do_target_variable_command(self, exe_name): 146 """Exercise 'target variable' command before and after starting the inferior.""" 147 self.runCmd("file " + self.getBuildArtifact(exe_name), 148 CURRENT_EXECUTABLE_SET) 149 150 self.expect( 151 "target variable my_global_char", 152 VARIABLES_DISPLAYED_CORRECTLY, 153 substrs=[ 154 "my_global_char", 155 "'X'"]) 156 self.expect( 157 "target variable my_global_str", 158 VARIABLES_DISPLAYED_CORRECTLY, 159 substrs=[ 160 'my_global_str', 161 '"abc"']) 162 self.expect( 163 "target variable my_static_int", 164 VARIABLES_DISPLAYED_CORRECTLY, 165 substrs=[ 166 'my_static_int', 167 '228']) 168 self.expect("target variable my_global_str_ptr", matching=False, 169 substrs=['"abc"']) 170 self.expect("target variable *my_global_str_ptr", matching=True, 171 substrs=['"abc"']) 172 self.expect( 173 "target variable *my_global_str", 174 VARIABLES_DISPLAYED_CORRECTLY, 175 substrs=['a']) 176 177 self.runCmd("b main") 178 self.runCmd("run") 179 180 self.expect( 181 "target variable my_global_str", 182 VARIABLES_DISPLAYED_CORRECTLY, 183 substrs=[ 184 'my_global_str', 185 '"abc"']) 186 self.expect( 187 "target variable my_static_int", 188 VARIABLES_DISPLAYED_CORRECTLY, 189 substrs=[ 190 'my_static_int', 191 '228']) 192 self.expect("target variable my_global_str_ptr", matching=False, 193 substrs=['"abc"']) 194 self.expect("target variable *my_global_str_ptr", matching=True, 195 substrs=['"abc"']) 196 self.expect( 197 "target variable *my_global_str", 198 VARIABLES_DISPLAYED_CORRECTLY, 199 substrs=['a']) 200 self.expect( 201 "target variable my_global_char", 202 VARIABLES_DISPLAYED_CORRECTLY, 203 substrs=[ 204 "my_global_char", 205 "'X'"]) 206 207 self.runCmd("c") 208 209 self.expect( 210 "target variable my_global_str", 211 VARIABLES_DISPLAYED_CORRECTLY, 212 substrs=[ 213 'my_global_str', 214 '"abc"']) 215 self.expect( 216 "target variable my_static_int", 217 VARIABLES_DISPLAYED_CORRECTLY, 218 substrs=[ 219 'my_static_int', 220 '228']) 221 self.expect("target variable my_global_str_ptr", matching=False, 222 substrs=['"abc"']) 223 self.expect("target variable *my_global_str_ptr", matching=True, 224 substrs=['"abc"']) 225 self.expect( 226 "target variable *my_global_str", 227 VARIABLES_DISPLAYED_CORRECTLY, 228 substrs=['a']) 229 self.expect( 230 "target variable my_global_char", 231 VARIABLES_DISPLAYED_CORRECTLY, 232 substrs=[ 233 "my_global_char", 234 "'X'"]) 235 236 def do_target_variable_command_no_fail(self, exe_name): 237 """Exercise 'target variable' command before and after starting the inferior.""" 238 self.runCmd("file " + self.getBuildArtifact(exe_name), 239 CURRENT_EXECUTABLE_SET) 240 241 self.expect( 242 "target variable my_global_char", 243 VARIABLES_DISPLAYED_CORRECTLY, 244 substrs=[ 245 "my_global_char", 246 "'X'"]) 247 self.expect( 248 "target variable my_global_str", 249 VARIABLES_DISPLAYED_CORRECTLY, 250 substrs=[ 251 'my_global_str', 252 '"abc"']) 253 self.expect( 254 "target variable my_static_int", 255 VARIABLES_DISPLAYED_CORRECTLY, 256 substrs=[ 257 'my_static_int', 258 '228']) 259 self.expect("target variable my_global_str_ptr", matching=False, 260 substrs=['"abc"']) 261 self.expect("target variable *my_global_str_ptr", matching=True, 262 substrs=['"abc"']) 263 self.expect( 264 "target variable *my_global_str", 265 VARIABLES_DISPLAYED_CORRECTLY, 266 substrs=['a']) 267 268 self.runCmd("b main") 269 self.runCmd("run") 270 271 # New feature: you don't need to specify the variable(s) to 'target vaiable'. 272 # It will find all the global and static variables in the current 273 # compile unit. 274 self.expect("target variable", 275 ordered=False, 276 substrs=['my_global_char', 277 'my_static_int', 278 'my_global_str', 279 'my_global_str_ptr', 280 ]) 281 282 self.expect( 283 "target variable my_global_str", 284 VARIABLES_DISPLAYED_CORRECTLY, 285 substrs=[ 286 'my_global_str', 287 '"abc"']) 288 self.expect( 289 "target variable my_static_int", 290 VARIABLES_DISPLAYED_CORRECTLY, 291 substrs=[ 292 'my_static_int', 293 '228']) 294 self.expect("target variable my_global_str_ptr", matching=False, 295 substrs=['"abc"']) 296 self.expect("target variable *my_global_str_ptr", matching=True, 297 substrs=['"abc"']) 298 self.expect( 299 "target variable *my_global_str", 300 VARIABLES_DISPLAYED_CORRECTLY, 301 substrs=['a']) 302 self.expect( 303 "target variable my_global_char", 304 VARIABLES_DISPLAYED_CORRECTLY, 305 substrs=[ 306 "my_global_char", 307 "'X'"]) 308 309 @no_debug_info_test 310 def test_target_stop_hook_disable_enable(self): 311 self.buildB() 312 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 313 314 self.expect("target stop-hook disable 1", error=True, substrs=['unknown stop hook id: "1"']) 315 self.expect("target stop-hook disable blub", error=True, substrs=['invalid stop hook id: "blub"']) 316 self.expect("target stop-hook enable 1", error=True, substrs=['unknown stop hook id: "1"']) 317 self.expect("target stop-hook enable blub", error=True, substrs=['invalid stop hook id: "blub"']) 318 319 @no_debug_info_test 320 def test_target_stop_hook_delete(self): 321 self.buildB() 322 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 323 324 self.expect("target stop-hook delete 1", error=True, substrs=['unknown stop hook id: "1"']) 325 self.expect("target stop-hook delete blub", error=True, substrs=['invalid stop hook id: "blub"']) 326 327 @no_debug_info_test 328 def test_target_list_args(self): 329 self.expect("target list blub", error=True, 330 substrs=["the 'target list' command takes no arguments"]) 331 332 @no_debug_info_test 333 def test_target_select_no_index(self): 334 self.expect("target select", error=True, 335 substrs=["'target select' takes a single argument: a target index"]) 336 337 @no_debug_info_test 338 def test_target_select_invalid_index(self): 339 self.runCmd("target delete --all") 340 self.expect("target select 0", error=True, 341 substrs=["index 0 is out of range since there are no active targets"]) 342 self.buildB() 343 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 344 self.expect("target select 1", error=True, 345 substrs=["index 1 is out of range, valid target indexes are 0 - 0"]) 346 347 348 @no_debug_info_test 349 def test_target_create_multiple_args(self): 350 self.expect("target create a b", error=True, 351 substrs=["'target create' takes exactly one executable path"]) 352 353 @skipIfWindowsAndNonEnglish 354 @no_debug_info_test 355 def test_target_create_nonexistent_core_file(self): 356 self.expect("target create -c doesntexist", error=True, 357 patterns=["Cannot open 'doesntexist'", ": (No such file or directory|The system cannot find the file specified)"]) 358 359 # Write only files don't seem to be supported on Windows. 360 @skipIfWindows 361 @skipIfReproducer # Cannot be captured in the VFS. 362 @no_debug_info_test 363 def test_target_create_unreadable_core_file(self): 364 tf = tempfile.NamedTemporaryFile() 365 os.chmod(tf.name, stat.S_IWRITE) 366 self.expect("target create -c '" + tf.name + "'", error=True, 367 substrs=["Cannot open '", "': Permission denied"]) 368 369 @skipIfWindowsAndNonEnglish 370 @no_debug_info_test 371 def test_target_create_nonexistent_sym_file(self): 372 self.expect("target create -s doesntexist doesntexisteither", error=True, 373 patterns=["Cannot open '", ": (No such file or directory|The system cannot find the file specified)"]) 374 375 @skipIfWindows 376 @no_debug_info_test 377 def test_target_create_invalid_core_file(self): 378 invalid_core_path = os.path.join(self.getSourceDir(), "invalid_core_file") 379 self.expect("target create -c '" + invalid_core_path + "'", error=True, 380 substrs=["Unable to find process plug-in for core file '"]) 381 382 383 # Write only files don't seem to be supported on Windows. 384 @skipIfWindows 385 @no_debug_info_test 386 @skipIfReproducer # Cannot be captured in the VFS. 387 def test_target_create_unreadable_sym_file(self): 388 tf = tempfile.NamedTemporaryFile() 389 os.chmod(tf.name, stat.S_IWRITE) 390 self.expect("target create -s '" + tf.name + "' no_exe", error=True, 391 substrs=["Cannot open '", "': Permission denied"]) 392 393 @no_debug_info_test 394 def test_target_delete_all(self): 395 self.buildAll() 396 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 397 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 398 self.expect("target delete --all") 399 self.expect("target list", substrs=["No targets."]) 400 401 @no_debug_info_test 402 def test_target_delete_by_index(self): 403 self.buildAll() 404 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 405 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 406 self.runCmd("file " + self.getBuildArtifact("c.out"), CURRENT_EXECUTABLE_SET) 407 self.expect("target delete 3", error=True, 408 substrs=["target index 3 is out of range, valid target indexes are 0 - 2"]) 409 410 self.runCmd("target delete 1") 411 self.expect("target list", matching=False, substrs=["b.out"]) 412 self.runCmd("target delete 1") 413 self.expect("target list", matching=False, substrs=["c.out"]) 414 415 self.expect("target delete 1", error=True, 416 substrs=["target index 1 is out of range, the only valid index is 0"]) 417 418 self.runCmd("target delete 0") 419 self.expect("target list", matching=False, substrs=["a.out"]) 420 421 self.expect("target delete 0", error=True, substrs=["no targets to delete"]) 422 self.expect("target delete 1", error=True, substrs=["no targets to delete"]) 423 424 @no_debug_info_test 425 def test_target_delete_by_index_multiple(self): 426 self.buildAll() 427 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 428 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 429 self.runCmd("file " + self.getBuildArtifact("c.out"), CURRENT_EXECUTABLE_SET) 430 431 self.expect("target delete 0 1 2 3", error=True, 432 substrs=["target index 3 is out of range, valid target indexes are 0 - 2"]) 433 self.expect("target list", substrs=["a.out", "b.out", "c.out"]) 434 435 self.runCmd("target delete 0 1 2") 436 self.expect("target list", matching=False, substrs=["a.out", "c.out"]) 437 438 @no_debug_info_test 439 def test_target_delete_selected(self): 440 self.buildAll() 441 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 442 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 443 self.runCmd("file " + self.getBuildArtifact("c.out"), CURRENT_EXECUTABLE_SET) 444 self.runCmd("target select 1") 445 self.runCmd("target delete") 446 self.expect("target list", matching=False, substrs=["b.out"]) 447 self.runCmd("target delete") 448 self.runCmd("target delete") 449 self.expect("target list", substrs=["No targets."]) 450 self.expect("target delete", error=True, substrs=["no target is currently selected"]) 451 452 @no_debug_info_test 453 def test_target_modules_search_paths_clear(self): 454 self.buildB() 455 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 456 self.runCmd("target modules search-paths add foo bar") 457 self.runCmd("target modules search-paths add foz baz") 458 self.runCmd("target modules search-paths clear") 459 self.expect("target list", matching=False, substrs=["bar", "baz"]) 460 461 @no_debug_info_test 462 def test_target_modules_search_paths_query(self): 463 self.buildB() 464 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 465 self.runCmd("target modules search-paths add foo bar") 466 self.expect("target modules search-paths query foo", substrs=["bar"]) 467 # Query something that doesn't exist. 468 self.expect("target modules search-paths query faz", substrs=["faz"]) 469 470 # Invalid arguments. 471 self.expect("target modules search-paths query faz baz", error=True, 472 substrs=["query requires one argument"]) 473