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 @expectedFailureDarwin(archs=["arm64"]) # <rdar://problem/37773624> 49 def test_target_variable_command(self): 50 """Test 'target variable' command before and after starting the inferior.""" 51 d = {'C_SOURCES': 'globals.c', 'EXE': self.getBuildArtifact('globals')} 52 self.build(dictionary=d) 53 self.addTearDownCleanup(dictionary=d) 54 55 self.do_target_variable_command('globals') 56 57 @expectedFailureAll(archs=['arm64e']) # <rdar://problem/37773624> 58 @expectedFailureDarwin(archs=["arm64"]) # <rdar://problem/37773624> 59 def test_target_variable_command_no_fail(self): 60 """Test 'target variable' command before and after starting the inferior.""" 61 d = {'C_SOURCES': 'globals.c', 'EXE': self.getBuildArtifact('globals')} 62 self.build(dictionary=d) 63 self.addTearDownCleanup(dictionary=d) 64 65 self.do_target_variable_command_no_fail('globals') 66 67 def do_target_command(self): 68 """Exercise 'target create', 'target list', 'target select' commands.""" 69 exe_a = self.getBuildArtifact("a.out") 70 exe_b = self.getBuildArtifact("b.out") 71 exe_c = self.getBuildArtifact("c.out") 72 73 self.runCmd("target list") 74 output = self.res.GetOutput() 75 if output.startswith("No targets"): 76 # We start from index 0. 77 base = 0 78 else: 79 # Find the largest index of the existing list. 80 import re 81 pattern = re.compile("target #(\d+):") 82 for line in reversed(output.split(os.linesep)): 83 match = pattern.search(line) 84 if match: 85 # We will start from (index + 1) .... 86 base = int(match.group(1), 10) + 1 87 self.trace("base is:", base) 88 break 89 90 self.runCmd("target create " + exe_a, CURRENT_EXECUTABLE_SET) 91 self.runCmd("run", RUN_SUCCEEDED) 92 93 self.runCmd("target create " + exe_b, CURRENT_EXECUTABLE_SET) 94 lldbutil.run_break_set_by_file_and_line( 95 self, 'b.c', self.line_b, num_expected_locations=1, loc_exact=True) 96 self.runCmd("run", RUN_SUCCEEDED) 97 98 self.runCmd("target create " + exe_c, CURRENT_EXECUTABLE_SET) 99 lldbutil.run_break_set_by_file_and_line( 100 self, 'c.c', self.line_c, num_expected_locations=1, loc_exact=True) 101 self.runCmd("run", RUN_SUCCEEDED) 102 103 self.runCmd("target list") 104 105 self.runCmd("target select %d" % base) 106 self.runCmd("thread backtrace") 107 108 self.runCmd("target select %d" % (base + 2)) 109 self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT, 110 substrs=['stop reason = breakpoint' ,'c.c:%d' % self.line_c 111 ]) 112 113 self.runCmd("target select %d" % (base + 1)) 114 self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT, 115 substrs=['stop reason = breakpoint', 'b.c:%d' % self.line_b 116 ]) 117 118 self.runCmd("target list") 119 120 @no_debug_info_test 121 def test_target_create_invalid_arch(self): 122 exe = self.getBuildArtifact("a.out") 123 self.expect("target create {} --arch doesntexist".format(exe), error=True, 124 patterns=["error: invalid triple 'doesntexist'"]) 125 126 @no_debug_info_test 127 def test_target_create_platform(self): 128 self.buildB() 129 exe = self.getBuildArtifact("b.out") 130 self.expect("target create {} --platform host".format(exe)) 131 132 @no_debug_info_test 133 def test_target_create_unsupported_platform(self): 134 yaml = os.path.join(self.getSourceDir(), "bogus.yaml") 135 exe = self.getBuildArtifact("bogus") 136 self.yaml2obj(yaml, exe) 137 self.expect("target create {}".format(exe), error=True, 138 patterns=['error: no matching platforms found for this file']) 139 140 @no_debug_info_test 141 def test_target_create_invalid_platform(self): 142 self.buildB() 143 exe = self.getBuildArtifact("b.out") 144 self.expect("target create {} --platform doesntexist".format(exe), error=True, 145 patterns=['error: unable to find a plug-in for the platform named "doesntexist"']) 146 147 def do_target_variable_command(self, exe_name): 148 """Exercise 'target variable' command before and after starting the inferior.""" 149 self.runCmd("file " + self.getBuildArtifact(exe_name), 150 CURRENT_EXECUTABLE_SET) 151 152 self.expect( 153 "target variable my_global_char", 154 VARIABLES_DISPLAYED_CORRECTLY, 155 substrs=[ 156 "my_global_char", 157 "'X'"]) 158 self.expect( 159 "target variable my_global_str", 160 VARIABLES_DISPLAYED_CORRECTLY, 161 substrs=[ 162 'my_global_str', 163 '"abc"']) 164 self.expect( 165 "target variable my_static_int", 166 VARIABLES_DISPLAYED_CORRECTLY, 167 substrs=[ 168 'my_static_int', 169 '228']) 170 self.expect("target variable my_global_str_ptr", matching=False, 171 substrs=['"abc"']) 172 self.expect("target variable *my_global_str_ptr", matching=True, 173 substrs=['"abc"']) 174 self.expect( 175 "target variable *my_global_str", 176 VARIABLES_DISPLAYED_CORRECTLY, 177 substrs=['a']) 178 179 self.runCmd("b main") 180 self.runCmd("run") 181 182 self.expect( 183 "target variable my_global_str", 184 VARIABLES_DISPLAYED_CORRECTLY, 185 substrs=[ 186 'my_global_str', 187 '"abc"']) 188 self.expect( 189 "target variable my_static_int", 190 VARIABLES_DISPLAYED_CORRECTLY, 191 substrs=[ 192 'my_static_int', 193 '228']) 194 self.expect("target variable my_global_str_ptr", matching=False, 195 substrs=['"abc"']) 196 self.expect("target variable *my_global_str_ptr", matching=True, 197 substrs=['"abc"']) 198 self.expect( 199 "target variable *my_global_str", 200 VARIABLES_DISPLAYED_CORRECTLY, 201 substrs=['a']) 202 self.expect( 203 "target variable my_global_char", 204 VARIABLES_DISPLAYED_CORRECTLY, 205 substrs=[ 206 "my_global_char", 207 "'X'"]) 208 209 self.runCmd("c") 210 211 self.expect( 212 "target variable my_global_str", 213 VARIABLES_DISPLAYED_CORRECTLY, 214 substrs=[ 215 'my_global_str', 216 '"abc"']) 217 self.expect( 218 "target variable my_static_int", 219 VARIABLES_DISPLAYED_CORRECTLY, 220 substrs=[ 221 'my_static_int', 222 '228']) 223 self.expect("target variable my_global_str_ptr", matching=False, 224 substrs=['"abc"']) 225 self.expect("target variable *my_global_str_ptr", matching=True, 226 substrs=['"abc"']) 227 self.expect( 228 "target variable *my_global_str", 229 VARIABLES_DISPLAYED_CORRECTLY, 230 substrs=['a']) 231 self.expect( 232 "target variable my_global_char", 233 VARIABLES_DISPLAYED_CORRECTLY, 234 substrs=[ 235 "my_global_char", 236 "'X'"]) 237 238 def do_target_variable_command_no_fail(self, exe_name): 239 """Exercise 'target variable' command before and after starting the inferior.""" 240 self.runCmd("file " + self.getBuildArtifact(exe_name), 241 CURRENT_EXECUTABLE_SET) 242 243 self.expect( 244 "target variable my_global_char", 245 VARIABLES_DISPLAYED_CORRECTLY, 246 substrs=[ 247 "my_global_char", 248 "'X'"]) 249 self.expect( 250 "target variable my_global_str", 251 VARIABLES_DISPLAYED_CORRECTLY, 252 substrs=[ 253 'my_global_str', 254 '"abc"']) 255 self.expect( 256 "target variable my_static_int", 257 VARIABLES_DISPLAYED_CORRECTLY, 258 substrs=[ 259 'my_static_int', 260 '228']) 261 self.expect("target variable my_global_str_ptr", matching=False, 262 substrs=['"abc"']) 263 self.expect("target variable *my_global_str_ptr", matching=True, 264 substrs=['"abc"']) 265 self.expect( 266 "target variable *my_global_str", 267 VARIABLES_DISPLAYED_CORRECTLY, 268 substrs=['a']) 269 270 self.runCmd("b main") 271 self.runCmd("run") 272 273 # New feature: you don't need to specify the variable(s) to 'target vaiable'. 274 # It will find all the global and static variables in the current 275 # compile unit. 276 self.expect("target variable", 277 ordered=False, 278 substrs=['my_global_char', 279 'my_static_int', 280 'my_global_str', 281 'my_global_str_ptr', 282 ]) 283 284 self.expect( 285 "target variable my_global_str", 286 VARIABLES_DISPLAYED_CORRECTLY, 287 substrs=[ 288 'my_global_str', 289 '"abc"']) 290 self.expect( 291 "target variable my_static_int", 292 VARIABLES_DISPLAYED_CORRECTLY, 293 substrs=[ 294 'my_static_int', 295 '228']) 296 self.expect("target variable my_global_str_ptr", matching=False, 297 substrs=['"abc"']) 298 self.expect("target variable *my_global_str_ptr", matching=True, 299 substrs=['"abc"']) 300 self.expect( 301 "target variable *my_global_str", 302 VARIABLES_DISPLAYED_CORRECTLY, 303 substrs=['a']) 304 self.expect( 305 "target variable my_global_char", 306 VARIABLES_DISPLAYED_CORRECTLY, 307 substrs=[ 308 "my_global_char", 309 "'X'"]) 310 311 @no_debug_info_test 312 def test_target_stop_hook_disable_enable(self): 313 self.buildB() 314 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 315 316 self.expect("target stop-hook disable 1", error=True, substrs=['unknown stop hook id: "1"']) 317 self.expect("target stop-hook disable blub", error=True, substrs=['invalid stop hook id: "blub"']) 318 self.expect("target stop-hook enable 1", error=True, substrs=['unknown stop hook id: "1"']) 319 self.expect("target stop-hook enable blub", error=True, substrs=['invalid stop hook id: "blub"']) 320 321 @no_debug_info_test 322 def test_target_stop_hook_delete(self): 323 self.buildB() 324 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 325 326 self.expect("target stop-hook delete 1", error=True, substrs=['unknown stop hook id: "1"']) 327 self.expect("target stop-hook delete blub", error=True, substrs=['invalid stop hook id: "blub"']) 328 329 @no_debug_info_test 330 def test_target_list_args(self): 331 self.expect("target list blub", error=True, 332 substrs=["the 'target list' command takes no arguments"]) 333 334 @no_debug_info_test 335 def test_target_select_no_index(self): 336 self.expect("target select", error=True, 337 substrs=["'target select' takes a single argument: a target index"]) 338 339 @no_debug_info_test 340 def test_target_select_invalid_index(self): 341 self.runCmd("target delete --all") 342 self.expect("target select 0", error=True, 343 substrs=["index 0 is out of range since there are no active targets"]) 344 self.buildB() 345 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 346 self.expect("target select 1", error=True, 347 substrs=["index 1 is out of range, valid target indexes are 0 - 0"]) 348 349 350 @no_debug_info_test 351 def test_target_create_multiple_args(self): 352 self.expect("target create a b", error=True, 353 substrs=["'target create' takes exactly one executable path"]) 354 355 @skipIfWindowsAndNonEnglish 356 @no_debug_info_test 357 def test_target_create_nonexistent_core_file(self): 358 self.expect("target create -c doesntexist", error=True, 359 patterns=["Cannot open 'doesntexist'", ": (No such file or directory|The system cannot find the file specified)"]) 360 361 # Write only files don't seem to be supported on Windows. 362 @skipIfWindows 363 @no_debug_info_test 364 def test_target_create_unreadable_core_file(self): 365 tf = tempfile.NamedTemporaryFile() 366 os.chmod(tf.name, stat.S_IWRITE) 367 self.expect("target create -c '" + tf.name + "'", error=True, 368 substrs=["Cannot open '", "': Permission denied"]) 369 370 @skipIfWindowsAndNonEnglish 371 @no_debug_info_test 372 def test_target_create_nonexistent_sym_file(self): 373 self.expect("target create -s doesntexist doesntexisteither", error=True, 374 patterns=["Cannot open '", ": (No such file or directory|The system cannot find the file specified)"]) 375 376 @skipIfWindows 377 @no_debug_info_test 378 def test_target_create_invalid_core_file(self): 379 invalid_core_path = os.path.join(self.getSourceDir(), "invalid_core_file") 380 self.expect("target create -c '" + invalid_core_path + "'", error=True, 381 substrs=["Unable to find process plug-in for core file '"]) 382 383 384 # Write only files don't seem to be supported on Windows. 385 @skipIfWindows 386 @no_debug_info_test 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