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 def test_target_variable_command(self): 48 """Test 'target variable' command before and after starting the inferior.""" 49 d = {'C_SOURCES': 'globals.c', 'EXE': self.getBuildArtifact('globals')} 50 self.build(dictionary=d) 51 self.addTearDownCleanup(dictionary=d) 52 53 self.do_target_variable_command('globals') 54 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 #print("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 def do_target_variable_command(self, exe_name): 117 """Exercise 'target variable' command before and after starting the inferior.""" 118 self.runCmd("file " + self.getBuildArtifact(exe_name), 119 CURRENT_EXECUTABLE_SET) 120 121 self.expect( 122 "target variable my_global_char", 123 VARIABLES_DISPLAYED_CORRECTLY, 124 substrs=[ 125 "my_global_char", 126 "'X'"]) 127 self.expect( 128 "target variable my_global_str", 129 VARIABLES_DISPLAYED_CORRECTLY, 130 substrs=[ 131 'my_global_str', 132 '"abc"']) 133 self.expect( 134 "target variable my_static_int", 135 VARIABLES_DISPLAYED_CORRECTLY, 136 substrs=[ 137 'my_static_int', 138 '228']) 139 self.expect("target variable my_global_str_ptr", matching=False, 140 substrs=['"abc"']) 141 self.expect("target variable *my_global_str_ptr", matching=True, 142 substrs=['"abc"']) 143 self.expect( 144 "target variable *my_global_str", 145 VARIABLES_DISPLAYED_CORRECTLY, 146 substrs=['a']) 147 148 self.runCmd("b main") 149 self.runCmd("run") 150 151 self.expect( 152 "target variable my_global_str", 153 VARIABLES_DISPLAYED_CORRECTLY, 154 substrs=[ 155 'my_global_str', 156 '"abc"']) 157 self.expect( 158 "target variable my_static_int", 159 VARIABLES_DISPLAYED_CORRECTLY, 160 substrs=[ 161 'my_static_int', 162 '228']) 163 self.expect("target variable my_global_str_ptr", matching=False, 164 substrs=['"abc"']) 165 self.expect("target variable *my_global_str_ptr", matching=True, 166 substrs=['"abc"']) 167 self.expect( 168 "target variable *my_global_str", 169 VARIABLES_DISPLAYED_CORRECTLY, 170 substrs=['a']) 171 self.expect( 172 "target variable my_global_char", 173 VARIABLES_DISPLAYED_CORRECTLY, 174 substrs=[ 175 "my_global_char", 176 "'X'"]) 177 178 self.runCmd("c") 179 180 # rdar://problem/9763907 181 # 'target variable' command fails if the target program has been run 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 substrs=["core file 'doesntexist' doesn't exist"]) 330 331 # Write only files don't seem to be supported on Windows. 332 @skipIfWindows 333 @no_debug_info_test 334 def test_target_create_unreadable_core_file(self): 335 tf = tempfile.NamedTemporaryFile() 336 os.chmod(tf.name, stat.S_IWRITE) 337 self.expect("target create -c '" + tf.name + "'", error=True, 338 substrs=["core file '", "' is not readable"]) 339 340 @no_debug_info_test 341 def test_target_create_nonexistent_sym_file(self): 342 self.expect("target create -s doesntexist doesntexisteither", error=True, 343 substrs=["invalid symbol file path 'doesntexist'"]) 344 345 @skipIfWindows 346 @no_debug_info_test 347 def test_target_create_invalid_core_file(self): 348 invalid_core_path = os.path.join(self.getSourceDir(), "invalid_core_file") 349 self.expect("target create -c '" + invalid_core_path + "'", error=True, 350 substrs=["Unable to find process plug-in for core file '"]) 351 352 353 # Write only files don't seem to be supported on Windows. 354 @skipIfWindows 355 @no_debug_info_test 356 def test_target_create_unreadable_sym_file(self): 357 tf = tempfile.NamedTemporaryFile() 358 os.chmod(tf.name, stat.S_IWRITE) 359 self.expect("target create -s '" + tf.name + "' no_exe", error=True, 360 substrs=["symbol file '", "' is not readable"]) 361 362 @no_debug_info_test 363 def test_target_delete_all(self): 364 self.buildAll() 365 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 366 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 367 self.expect("target delete --all") 368 self.expect("target list", substrs=["No targets."]) 369 370 @no_debug_info_test 371 def test_target_delete_by_index(self): 372 self.buildAll() 373 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 374 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 375 self.runCmd("file " + self.getBuildArtifact("c.out"), CURRENT_EXECUTABLE_SET) 376 self.expect("target delete 3", error=True, 377 substrs=["target index 3 is out of range, valid target indexes are 0 - 2"]) 378 379 self.runCmd("target delete 1") 380 self.expect("target list", matching=False, substrs=["b.out"]) 381 self.runCmd("target delete 1") 382 self.expect("target list", matching=False, substrs=["c.out"]) 383 384 self.expect("target delete 1", error=True, 385 substrs=["target index 1 is out of range, the only valid index is 0"]) 386 387 self.runCmd("target delete 0") 388 self.expect("target list", matching=False, substrs=["a.out"]) 389 390 self.expect("target delete 0", error=True, substrs=["no targets to delete"]) 391 self.expect("target delete 1", error=True, substrs=["no targets to delete"]) 392 393 @no_debug_info_test 394 def test_target_delete_by_index_multiple(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.runCmd("file " + self.getBuildArtifact("c.out"), CURRENT_EXECUTABLE_SET) 399 400 self.expect("target delete 0 1 2 3", error=True, 401 substrs=["target index 3 is out of range, valid target indexes are 0 - 2"]) 402 self.expect("target list", substrs=["a.out", "b.out", "c.out"]) 403 404 self.runCmd("target delete 0 1 2") 405 self.expect("target list", matching=False, substrs=["a.out", "c.out"]) 406 407 @no_debug_info_test 408 def test_target_delete_selected(self): 409 self.buildAll() 410 self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) 411 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 412 self.runCmd("file " + self.getBuildArtifact("c.out"), CURRENT_EXECUTABLE_SET) 413 self.runCmd("target select 1") 414 self.runCmd("target delete") 415 self.expect("target list", matching=False, substrs=["b.out"]) 416 self.runCmd("target delete") 417 self.runCmd("target delete") 418 self.expect("target list", substrs=["No targets."]) 419 self.expect("target delete", error=True, substrs=["no target is currently selected"]) 420 421 @no_debug_info_test 422 def test_target_modules_search_paths_clear(self): 423 self.buildB() 424 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 425 self.runCmd("target modules search-paths add foo bar") 426 self.runCmd("target modules search-paths add foz baz") 427 self.runCmd("target modules search-paths clear") 428 self.expect("target list", matching=False, substrs=["bar", "baz"]) 429 430 @no_debug_info_test 431 def test_target_modules_search_paths_query(self): 432 self.buildB() 433 self.runCmd("file " + self.getBuildArtifact("b.out"), CURRENT_EXECUTABLE_SET) 434 self.runCmd("target modules search-paths add foo bar") 435 self.expect("target modules search-paths query foo", substrs=["bar"]) 436 # Query something that doesn't exist. 437 self.expect("target modules search-paths query faz", substrs=["faz"]) 438 439 # Invalid arguments. 440 self.expect("target modules search-paths query faz baz", error=True, 441 substrs=["query requires one argument"]) 442