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