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 def do_target_variable_command(self, exe_name): 119 """Exercise 'target variable' command before and after starting the inferior.""" 120 self.runCmd("file " + self.getBuildArtifact(exe_name), 121 CURRENT_EXECUTABLE_SET) 122 123 self.expect( 124 "target variable my_global_char", 125 VARIABLES_DISPLAYED_CORRECTLY, 126 substrs=[ 127 "my_global_char", 128 "'X'"]) 129 self.expect( 130 "target variable my_global_str", 131 VARIABLES_DISPLAYED_CORRECTLY, 132 substrs=[ 133 'my_global_str', 134 '"abc"']) 135 self.expect( 136 "target variable my_static_int", 137 VARIABLES_DISPLAYED_CORRECTLY, 138 substrs=[ 139 'my_static_int', 140 '228']) 141 self.expect("target variable my_global_str_ptr", matching=False, 142 substrs=['"abc"']) 143 self.expect("target variable *my_global_str_ptr", matching=True, 144 substrs=['"abc"']) 145 self.expect( 146 "target variable *my_global_str", 147 VARIABLES_DISPLAYED_CORRECTLY, 148 substrs=['a']) 149 150 self.runCmd("b main") 151 self.runCmd("run") 152 153 self.expect( 154 "target variable my_global_str", 155 VARIABLES_DISPLAYED_CORRECTLY, 156 substrs=[ 157 'my_global_str', 158 '"abc"']) 159 self.expect( 160 "target variable my_static_int", 161 VARIABLES_DISPLAYED_CORRECTLY, 162 substrs=[ 163 'my_static_int', 164 '228']) 165 self.expect("target variable my_global_str_ptr", matching=False, 166 substrs=['"abc"']) 167 self.expect("target variable *my_global_str_ptr", matching=True, 168 substrs=['"abc"']) 169 self.expect( 170 "target variable *my_global_str", 171 VARIABLES_DISPLAYED_CORRECTLY, 172 substrs=['a']) 173 self.expect( 174 "target variable my_global_char", 175 VARIABLES_DISPLAYED_CORRECTLY, 176 substrs=[ 177 "my_global_char", 178 "'X'"]) 179 180 self.runCmd("c") 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 def do_target_variable_command_no_fail(self, exe_name): 210 """Exercise 'target variable' command before and after starting the inferior.""" 211 self.runCmd("file " + self.getBuildArtifact(exe_name), 212 CURRENT_EXECUTABLE_SET) 213 214 self.expect( 215 "target variable my_global_char", 216 VARIABLES_DISPLAYED_CORRECTLY, 217 substrs=[ 218 "my_global_char", 219 "'X'"]) 220 self.expect( 221 "target variable my_global_str", 222 VARIABLES_DISPLAYED_CORRECTLY, 223 substrs=[ 224 'my_global_str', 225 '"abc"']) 226 self.expect( 227 "target variable my_static_int", 228 VARIABLES_DISPLAYED_CORRECTLY, 229 substrs=[ 230 'my_static_int', 231 '228']) 232 self.expect("target variable my_global_str_ptr", matching=False, 233 substrs=['"abc"']) 234 self.expect("target variable *my_global_str_ptr", matching=True, 235 substrs=['"abc"']) 236 self.expect( 237 "target variable *my_global_str", 238 VARIABLES_DISPLAYED_CORRECTLY, 239 substrs=['a']) 240 241 self.runCmd("b main") 242 self.runCmd("run") 243 244 # New feature: you don't need to specify the variable(s) to 'target vaiable'. 245 # It will find all the global and static variables in the current 246 # compile unit. 247 self.expect("target variable", 248 ordered=False, 249 substrs=['my_global_char', 250 'my_static_int', 251 'my_global_str', 252 'my_global_str_ptr', 253 ]) 254 255 self.expect( 256 "target variable my_global_str", 257 VARIABLES_DISPLAYED_CORRECTLY, 258 substrs=[ 259 'my_global_str', 260 '"abc"']) 261 self.expect( 262 "target variable my_static_int", 263 VARIABLES_DISPLAYED_CORRECTLY, 264 substrs=[ 265 'my_static_int', 266 '228']) 267 self.expect("target variable my_global_str_ptr", matching=False, 268 substrs=['"abc"']) 269 self.expect("target variable *my_global_str_ptr", matching=True, 270 substrs=['"abc"']) 271 self.expect( 272 "target variable *my_global_str", 273 VARIABLES_DISPLAYED_CORRECTLY, 274 substrs=['a']) 275 self.expect( 276 "target variable my_global_char", 277 VARIABLES_DISPLAYED_CORRECTLY, 278 substrs=[ 279 "my_global_char", 280 "'X'"]) 281 282 @no_debug_info_test 283 def test_target_stop_hook_disable_enable(self): 284 self.buildB() 285 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 286 287 self.expect("target stop-hook disable 1", error=True, substrs=['unknown stop hook id: "1"']) 288 self.expect("target stop-hook disable blub", error=True, substrs=['invalid stop hook id: "blub"']) 289 self.expect("target stop-hook enable 1", error=True, substrs=['unknown stop hook id: "1"']) 290 self.expect("target stop-hook enable blub", error=True, substrs=['invalid stop hook id: "blub"']) 291 292 @no_debug_info_test 293 def test_target_stop_hook_delete(self): 294 self.buildB() 295 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 296 297 self.expect("target stop-hook delete 1", error=True, substrs=['unknown stop hook id: "1"']) 298 self.expect("target stop-hook delete blub", error=True, substrs=['invalid stop hook id: "blub"']) 299 300 @no_debug_info_test 301 def test_target_list_args(self): 302 self.expect("target list blub", error=True, 303 substrs=["the 'target list' command takes no arguments"]) 304 305 @no_debug_info_test 306 def test_target_select_no_index(self): 307 self.expect("target select", error=True, 308 substrs=["'target select' takes a single argument: a target index"]) 309 310 @no_debug_info_test 311 def test_target_select_invalid_index(self): 312 self.runCmd("target delete --all") 313 self.expect("target select 0", error=True, 314 substrs=["index 0 is out of range since there are no active targets"]) 315 self.buildB() 316 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 317 self.expect("target select 1", error=True, 318 substrs=["index 1 is out of range, valid target indexes are 0 - 0"]) 319 320 321 @no_debug_info_test 322 def test_target_create_multiple_args(self): 323 self.expect("target create a b", error=True, 324 substrs=["'target create' takes exactly one executable path"]) 325 326 @no_debug_info_test 327 def test_target_create_nonexistent_core_file(self): 328 self.expect("target create -c doesntexist", error=True, 329 patterns=["Cannot open 'doesntexist'", ": (No such file or directory|The system cannot find the file specified)"]) 330 331 # Write only files don't seem to be supported on Windows. 332 @skipIfWindows 333 @skipIfReproducer # Cannot be captured in the VFS. 334 @no_debug_info_test 335 def test_target_create_unreadable_core_file(self): 336 tf = tempfile.NamedTemporaryFile() 337 os.chmod(tf.name, stat.S_IWRITE) 338 self.expect("target create -c '" + tf.name + "'", error=True, 339 substrs=["Cannot open '", "': Permission denied"]) 340 341 @no_debug_info_test 342 def test_target_create_nonexistent_sym_file(self): 343 self.expect("target create -s doesntexist doesntexisteither", error=True, 344 patterns=["Cannot open '", ": (No such file or directory|The system cannot find the file specified)"]) 345 346 @skipIfWindows 347 @no_debug_info_test 348 def test_target_create_invalid_core_file(self): 349 invalid_core_path = os.path.join(self.getSourceDir(), "invalid_core_file") 350 self.expect("target create -c '" + invalid_core_path + "'", error=True, 351 substrs=["Unable to find process plug-in for core file '"]) 352 353 354 # Write only files don't seem to be supported on Windows. 355 @skipIfWindows 356 @no_debug_info_test 357 @skipIfReproducer # Cannot be captured in the VFS. 358 def test_target_create_unreadable_sym_file(self): 359 tf = tempfile.NamedTemporaryFile() 360 os.chmod(tf.name, stat.S_IWRITE) 361 self.expect("target create -s '" + tf.name + "' no_exe", error=True, 362 substrs=["Cannot open '", "': Permission denied"]) 363 364 @no_debug_info_test 365 def test_target_delete_all(self): 366 self.buildAll() 367 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 368 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 369 self.expect("target delete --all") 370 self.expect("target list", substrs=["No targets."]) 371 372 @no_debug_info_test 373 def test_target_delete_by_index(self): 374 self.buildAll() 375 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 376 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 377 self.runCmd("file " + self.getBuildArtifact("c.out"), CURRENT_EXECUTABLE_SET) 378 self.expect("target delete 3", error=True, 379 substrs=["target index 3 is out of range, valid target indexes are 0 - 2"]) 380 381 self.runCmd("target delete 1") 382 self.expect("target list", matching=False, substrs=["b.out"]) 383 self.runCmd("target delete 1") 384 self.expect("target list", matching=False, substrs=["c.out"]) 385 386 self.expect("target delete 1", error=True, 387 substrs=["target index 1 is out of range, the only valid index is 0"]) 388 389 self.runCmd("target delete 0") 390 self.expect("target list", matching=False, substrs=["a.out"]) 391 392 self.expect("target delete 0", error=True, substrs=["no targets to delete"]) 393 self.expect("target delete 1", error=True, substrs=["no targets to delete"]) 394 395 @no_debug_info_test 396 def test_target_delete_by_index_multiple(self): 397 self.buildAll() 398 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 399 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 400 self.runCmd("file " + self.getBuildArtifact("c.out"), CURRENT_EXECUTABLE_SET) 401 402 self.expect("target delete 0 1 2 3", error=True, 403 substrs=["target index 3 is out of range, valid target indexes are 0 - 2"]) 404 self.expect("target list", substrs=["a.out", "b.out", "c.out"]) 405 406 self.runCmd("target delete 0 1 2") 407 self.expect("target list", matching=False, substrs=["a.out", "c.out"]) 408 409 @no_debug_info_test 410 def test_target_delete_selected(self): 411 self.buildAll() 412 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 413 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 414 self.runCmd("file " + self.getBuildArtifact("c.out"), CURRENT_EXECUTABLE_SET) 415 self.runCmd("target select 1") 416 self.runCmd("target delete") 417 self.expect("target list", matching=False, substrs=["b.out"]) 418 self.runCmd("target delete") 419 self.runCmd("target delete") 420 self.expect("target list", substrs=["No targets."]) 421 self.expect("target delete", error=True, substrs=["no target is currently selected"]) 422 423 @no_debug_info_test 424 def test_target_modules_search_paths_clear(self): 425 self.buildB() 426 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 427 self.runCmd("target modules search-paths add foo bar") 428 self.runCmd("target modules search-paths add foz baz") 429 self.runCmd("target modules search-paths clear") 430 self.expect("target list", matching=False, substrs=["bar", "baz"]) 431 432 @no_debug_info_test 433 def test_target_modules_search_paths_query(self): 434 self.buildB() 435 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 436 self.runCmd("target modules search-paths add foo bar") 437 self.expect("target modules search-paths query foo", substrs=["bar"]) 438 # Query something that doesn't exist. 439 self.expect("target modules search-paths query faz", substrs=["faz"]) 440 441 # Invalid arguments. 442 self.expect("target modules search-paths query faz baz", error=True, 443 substrs=["query requires one argument"]) 444