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 @no_debug_info_test 362 def test_target_create_unreadable_core_file(self): 363 tf = tempfile.NamedTemporaryFile() 364 os.chmod(tf.name, stat.S_IWRITE) 365 self.expect("target create -c '" + tf.name + "'", error=True, 366 substrs=["Cannot open '", "': Permission denied"]) 367 368 @skipIfWindowsAndNonEnglish 369 @no_debug_info_test 370 def test_target_create_nonexistent_sym_file(self): 371 self.expect("target create -s doesntexist doesntexisteither", error=True, 372 patterns=["Cannot open '", ": (No such file or directory|The system cannot find the file specified)"]) 373 374 @skipIfWindows 375 @no_debug_info_test 376 def test_target_create_invalid_core_file(self): 377 invalid_core_path = os.path.join(self.getSourceDir(), "invalid_core_file") 378 self.expect("target create -c '" + invalid_core_path + "'", error=True, 379 substrs=["Unable to find process plug-in for core file '"]) 380 381 382 # Write only files don't seem to be supported on Windows. 383 @skipIfWindows 384 @no_debug_info_test 385 def test_target_create_unreadable_sym_file(self): 386 tf = tempfile.NamedTemporaryFile() 387 os.chmod(tf.name, stat.S_IWRITE) 388 self.expect("target create -s '" + tf.name + "' no_exe", error=True, 389 substrs=["Cannot open '", "': Permission denied"]) 390 391 @no_debug_info_test 392 def test_target_delete_all(self): 393 self.buildAll() 394 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 395 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 396 self.expect("target delete --all") 397 self.expect("target list", substrs=["No targets."]) 398 399 @no_debug_info_test 400 def test_target_delete_by_index(self): 401 self.buildAll() 402 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 403 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 404 self.runCmd("file " + self.getBuildArtifact("c.out"), CURRENT_EXECUTABLE_SET) 405 self.expect("target delete 3", error=True, 406 substrs=["target index 3 is out of range, valid target indexes are 0 - 2"]) 407 408 self.runCmd("target delete 1") 409 self.expect("target list", matching=False, substrs=["b.out"]) 410 self.runCmd("target delete 1") 411 self.expect("target list", matching=False, substrs=["c.out"]) 412 413 self.expect("target delete 1", error=True, 414 substrs=["target index 1 is out of range, the only valid index is 0"]) 415 416 self.runCmd("target delete 0") 417 self.expect("target list", matching=False, substrs=["a.out"]) 418 419 self.expect("target delete 0", error=True, substrs=["no targets to delete"]) 420 self.expect("target delete 1", error=True, substrs=["no targets to delete"]) 421 422 @no_debug_info_test 423 def test_target_delete_by_index_multiple(self): 424 self.buildAll() 425 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 426 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 427 self.runCmd("file " + self.getBuildArtifact("c.out"), CURRENT_EXECUTABLE_SET) 428 429 self.expect("target delete 0 1 2 3", error=True, 430 substrs=["target index 3 is out of range, valid target indexes are 0 - 2"]) 431 self.expect("target list", substrs=["a.out", "b.out", "c.out"]) 432 433 self.runCmd("target delete 0 1 2") 434 self.expect("target list", matching=False, substrs=["a.out", "c.out"]) 435 436 @no_debug_info_test 437 def test_target_delete_selected(self): 438 self.buildAll() 439 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 440 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 441 self.runCmd("file " + self.getBuildArtifact("c.out"), CURRENT_EXECUTABLE_SET) 442 self.runCmd("target select 1") 443 self.runCmd("target delete") 444 self.expect("target list", matching=False, substrs=["b.out"]) 445 self.runCmd("target delete") 446 self.runCmd("target delete") 447 self.expect("target list", substrs=["No targets."]) 448 self.expect("target delete", error=True, substrs=["no target is currently selected"]) 449 450 @no_debug_info_test 451 def test_target_modules_search_paths_clear(self): 452 self.buildB() 453 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 454 self.runCmd("target modules search-paths add foo bar") 455 self.runCmd("target modules search-paths add foz baz") 456 self.runCmd("target modules search-paths clear") 457 self.expect("target list", matching=False, substrs=["bar", "baz"]) 458 459 @no_debug_info_test 460 def test_target_modules_search_paths_query(self): 461 self.buildB() 462 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 463 self.runCmd("target modules search-paths add foo bar") 464 self.expect("target modules search-paths query foo", substrs=["bar"]) 465 # Query something that doesn't exist. 466 self.expect("target modules search-paths query faz", substrs=["faz"]) 467 468 # Invalid arguments. 469 self.expect("target modules search-paths query faz baz", error=True, 470 substrs=["query requires one argument"]) 471