1""" 2Test the lldb command line completion mechanism. 3""" 4 5 6import os 7from multiprocessing import Process 8import lldb 9from lldbsuite.test.decorators import * 10from lldbsuite.test.lldbtest import * 11from lldbsuite.test import lldbplatform 12from lldbsuite.test import lldbutil 13 14 15class CommandLineCompletionTestCase(TestBase): 16 NO_DEBUG_INFO_TESTCASE = True 17 18 @classmethod 19 def classCleanup(cls): 20 """Cleanup the test byproducts.""" 21 try: 22 os.remove("child_send.txt") 23 os.remove("child_read.txt") 24 except: 25 pass 26 27 def test_at(self): 28 """Test that 'at' completes to 'attach '.""" 29 self.complete_from_to("at", "attach ") 30 31 def test_de(self): 32 """Test that 'de' completes to 'detach '.""" 33 self.complete_from_to("de", "detach ") 34 35 def test_frame_variable(self): 36 self.build() 37 38 _, process, _, _ = lldbutil.run_to_source_breakpoint( 39 self, "// Break here", lldb.SBFileSpec("main.cpp") 40 ) 41 self.assertState(process.GetState(), lldb.eStateStopped) 42 43 # Since CommandInterpreter has been corrected to update the current execution 44 # context at the beginning of HandleCompletion, we're here explicitly testing 45 # the scenario where "frame var" is completed without any preceding commands. 46 self.do_test_variable_completion("frame variable") 47 48 def test_dwim_print(self): 49 self.build() 50 51 _, process, _, _ = lldbutil.run_to_source_breakpoint( 52 self, "// Break here", lldb.SBFileSpec("main.cpp") 53 ) 54 self.assertState(process.GetState(), lldb.eStateStopped) 55 56 # Since CommandInterpreter has been corrected to update the current execution 57 # context at the beginning of HandleCompletion, we're here explicitly testing 58 # the scenario where "frame var" is completed without any preceding commands. 59 self.do_test_variable_completion("dwim-print") 60 61 def do_test_variable_completion(self, command): 62 self.complete_from_to(f"{command} fo", f"{command} fooo") 63 self.complete_from_to(f"{command} fooo.", f"{command} fooo.t") 64 self.complete_from_to(f"{command} fooo.t.", f"{command} fooo.t.x") 65 self.complete_from_to(f"{command} fooo.dd", f"{command} fooo.dd") 66 67 self.complete_from_to(f"{command} ptr_fooo->", f"{command} ptr_fooo->t") 68 self.complete_from_to(f"{command} ptr_fooo->t.", f"{command} ptr_fooo->t.x") 69 self.complete_from_to(f"{command} ptr_fooo->dd", f"{command} ptr_fooo->dd") 70 71 self.complete_from_to(f"{command} cont", f"{command} container") 72 self.complete_from_to(f"{command} container.", f"{command} container.MemberVar") 73 self.complete_from_to( 74 f"{command} container.Mem", f"{command} container.MemberVar" 75 ) 76 77 self.complete_from_to(f"{command} ptr_cont", f"{command} ptr_container") 78 self.complete_from_to( 79 f"{command} ptr_container->", f"{command} ptr_container->MemberVar" 80 ) 81 self.complete_from_to( 82 f"{command} ptr_container->Mem", f"{command} ptr_container->MemberVar" 83 ) 84 85 def test_process_attach_dash_dash_con(self): 86 """Test that 'process attach --con' completes to 'process attach --continue '.""" 87 self.complete_from_to("process attach --con", "process attach --continue ") 88 89 def test_process_launch_arch(self): 90 self.complete_from_to("process launch --arch ", ["mips", "arm64"]) 91 92 def test_process_load(self): 93 self.build() 94 lldbutil.run_to_source_breakpoint( 95 self, "// Break here", lldb.SBFileSpec("main.cpp") 96 ) 97 self.complete_from_to("process load Makef", "process load Makefile") 98 99 @skipUnlessPlatform(["linux"]) 100 def test_process_unload(self): 101 """Test the completion for "process unload <index>" """ 102 # This tab completion should not work without a running process. 103 self.complete_from_to("process unload ", "process unload ") 104 105 self.build() 106 lldbutil.run_to_source_breakpoint( 107 self, "// Break here", lldb.SBFileSpec("main.cpp") 108 ) 109 err = lldb.SBError() 110 local_spec = lldb.SBFileSpec(self.getBuildArtifact("libshared.so")) 111 if lldb.remote_platform: 112 self.process().LoadImage( 113 local_spec, 114 lldb.SBFileSpec( 115 lldbutil.append_to_process_working_directory(self, "libshared.so"), 116 False, 117 ), 118 err, 119 ) 120 else: 121 self.process().LoadImage(local_spec, err) 122 self.assertSuccess(err) 123 124 self.complete_from_to("process unload ", "process unload 0") 125 126 self.process().UnloadImage(0) 127 self.complete_from_to("process unload ", "process unload ") 128 129 def test_process_plugin_completion(self): 130 subcommands = ["attach -P", "connect -p", "launch -p"] 131 132 for subcommand in subcommands: 133 self.complete_from_to( 134 "process " + subcommand + " mac", 135 "process " + subcommand + " mach-o-core", 136 ) 137 138 def completions_contain_str(self, input, needle): 139 interp = self.dbg.GetCommandInterpreter() 140 match_strings = lldb.SBStringList() 141 num_matches = interp.HandleCompletion(input, len(input), 0, -1, match_strings) 142 found_needle = False 143 for match in match_strings: 144 if needle in match: 145 found_needle = True 146 break 147 self.assertTrue( 148 found_needle, "Returned completions: " + "\n".join(match_strings) 149 ) 150 151 @skipIfRemote 152 def test_common_completion_process_pid_and_name(self): 153 # The LLDB process itself and the process already attached to are both 154 # ignored by the process discovery mechanism, thus we need a process known 155 # to us here. 156 self.build() 157 server = self.spawnSubprocess( 158 self.getBuildArtifact("a.out"), 159 [ 160 "-x" 161 ], # Arg "-x" makes the subprocess wait for input thus it won't be terminated too early 162 install_remote=False, 163 ) 164 self.assertIsNotNone(server) 165 pid = server.pid 166 167 self.completions_contain("process attach -p ", [str(pid)]) 168 self.completions_contain("platform process attach -p ", [str(pid)]) 169 self.completions_contain("platform process info ", [str(pid)]) 170 171 self.completions_contain_str("process attach -n ", "a.out") 172 self.completions_contain_str("platform process attach -n ", "a.out") 173 174 def test_process_signal(self): 175 # The tab completion for "process signal" won't work without a running process. 176 self.complete_from_to("process signal ", "process signal ") 177 178 # Test with a running process. 179 self.build() 180 self.main_source = "main.cpp" 181 self.main_source_spec = lldb.SBFileSpec(self.main_source) 182 lldbutil.run_to_source_breakpoint(self, "// Break here", self.main_source_spec) 183 184 self.complete_from_to("process signal ", "process signal SIG") 185 self.complete_from_to("process signal SIGPIP", "process signal SIGPIPE") 186 self.complete_from_to("process signal SIGA", ["SIGABRT", "SIGALRM"]) 187 188 def test_ambiguous_long_opt(self): 189 self.completions_match( 190 "breakpoint modify --th", ["--thread-id", "--thread-index", "--thread-name"] 191 ) 192 193 def test_disassemble_dash_f(self): 194 self.completions_match("disassemble -F ", ["default", "intel", "att"]) 195 196 def test_plugin_load(self): 197 self.complete_from_to("plugin load ", []) 198 199 def test_log_enable(self): 200 self.complete_from_to("log disable ll", ["lldb"]) 201 self.complete_from_to("log disable dw", ["dwarf"]) 202 self.complete_from_to("log disable lldb al", ["all"]) 203 self.complete_from_to("log disable lldb sym", ["symbol"]) 204 205 def test_log_list(self): 206 self.complete_from_to("log list ll", ["lldb"]) 207 self.complete_from_to("log list dw", ["dwarf"]) 208 self.complete_from_to("log list ll", ["lldb"]) 209 self.complete_from_to("log list lldb dwa", ["dwarf"]) 210 211 def test_quoted_command(self): 212 self.complete_from_to('"set', ['"settings" ']) 213 214 def test_quoted_arg_with_quoted_command(self): 215 self.complete_from_to('"settings" "repl', ['"replace" ']) 216 217 def test_quoted_arg_without_quoted_command(self): 218 self.complete_from_to('settings "repl', ['"replace" ']) 219 220 def test_single_quote_command(self): 221 self.complete_from_to("'set", ["'settings' "]) 222 223 def test_terminated_quote_command(self): 224 # This should not crash, but we don't get any 225 # reasonable completions from this. 226 self.complete_from_to("'settings'", []) 227 228 def test_process_launch_arch_arm(self): 229 self.complete_from_to("process launch --arch arm", ["arm64"]) 230 231 def test_target_symbols_add_shlib(self): 232 # Doesn't seem to work, but at least it shouldn't crash. 233 self.complete_from_to("target symbols add --shlib ", []) 234 235 def test_log_file(self): 236 # Complete in our source directory which contains a 'main.cpp' file. 237 src_dir = self.getSourceDir() + "/" 238 self.complete_from_to("log enable lldb expr -f " + src_dir, ["main.cpp"]) 239 240 def test_log_dir(self): 241 # Complete our source directory. 242 src_dir = os.path.dirname(os.path.realpath(__file__)) 243 self.complete_from_to("log enable lldb expr -f " + src_dir, [src_dir + os.sep]) 244 245 # <rdar://problem/11052829> 246 def test_infinite_loop_while_completing(self): 247 """Test that 'process print hello\' completes to itself and does not infinite loop.""" 248 self.complete_from_to("process print hello\\", "process print hello\\") 249 250 def test_watchpoint_co(self): 251 """Test that 'watchpoint co' completes to 'watchpoint command '.""" 252 self.complete_from_to("watchpoint co", "watchpoint command ") 253 254 def test_watchpoint_command_space(self): 255 """Test that 'watchpoint command ' completes to ['add', 'delete', 'list'].""" 256 self.complete_from_to("watchpoint command ", ["add", "delete", "list"]) 257 258 def test_watchpoint_command_a(self): 259 """Test that 'watchpoint command a' completes to 'watchpoint command add '.""" 260 self.complete_from_to("watchpoint command a", "watchpoint command add ") 261 262 def test_watchpoint_set_ex(self): 263 """Test that 'watchpoint set ex' completes to 'watchpoint set expression '.""" 264 self.complete_from_to("watchpoint set ex", "watchpoint set expression ") 265 266 def test_watchpoint_set_var(self): 267 """Test that 'watchpoint set var' completes to 'watchpoint set variable '.""" 268 self.complete_from_to("watchpoint set var", "watchpoint set variable ") 269 270 def test_watchpoint_set_variable_foo(self): 271 self.build() 272 lldbutil.run_to_source_breakpoint( 273 self, "// Break here", lldb.SBFileSpec("main.cpp") 274 ) 275 self.complete_from_to( 276 "watchpoint set variable fo", "watchpoint set variable fooo" 277 ) 278 # Only complete the first argument. 279 self.complete_from_to( 280 "watchpoint set variable fooo ", "watchpoint set variable fooo " 281 ) 282 283 def test_help_fi(self): 284 """Test that 'help fi' completes to ['file', 'finish'].""" 285 self.complete_from_to("help fi", ["file", "finish"]) 286 287 def test_help_watchpoint_s(self): 288 """Test that 'help watchpoint s' completes to 'help watchpoint set '.""" 289 self.complete_from_to("help watchpoint s", "help watchpoint set ") 290 291 @expectedFailureNetBSD 292 @add_test_categories(["watchpoint"]) 293 def test_common_complete_watchpoint_ids(self): 294 subcommands = ["enable", "disable", "delete", "modify", "ignore"] 295 296 # Completion should not work without a target. 297 for subcommand in subcommands: 298 self.complete_from_to( 299 "watchpoint " + subcommand + " ", "watchpoint " + subcommand + " " 300 ) 301 302 # Create a process to provide a target and enable watchpoint setting. 303 self.build() 304 lldbutil.run_to_source_breakpoint( 305 self, "// Break here", lldb.SBFileSpec("main.cpp") 306 ) 307 308 self.runCmd("watchpoint set variable ptr_fooo") 309 for subcommand in subcommands: 310 self.complete_from_to("watchpoint " + subcommand + " ", ["1"]) 311 312 def test_settings_append_target_er(self): 313 """Test that 'settings append target.er' completes to 'settings append target.error-path'.""" 314 self.complete_from_to( 315 "settings append target.er", "settings append target.error-path" 316 ) 317 318 def test_settings_insert_after_target_en(self): 319 """Test that 'settings insert-after target.env' completes to 'settings insert-after target.env-vars'.""" 320 self.complete_from_to( 321 "settings insert-after target.env", "settings insert-after target.env-vars" 322 ) 323 324 def test_settings_insert_before_target_en(self): 325 """Test that 'settings insert-before target.env' completes to 'settings insert-before target.env-vars'.""" 326 self.complete_from_to( 327 "settings insert-before target.env", 328 "settings insert-before target.env-vars", 329 ) 330 331 def test_settings_replace_target_ru(self): 332 """Test that 'settings replace target.ru' completes to 'settings replace target.run-args'.""" 333 self.complete_from_to( 334 "settings replace target.ru", "settings replace target.run-args" 335 ) 336 337 def test_settings_show_term(self): 338 self.complete_from_to("settings show term-w", "settings show term-width") 339 340 def test_settings_list_term(self): 341 self.complete_from_to("settings list term-w", "settings list term-width") 342 343 def test_settings_show_term(self): 344 self.complete_from_to("settings show term-h", "settings show term-height") 345 346 def test_settings_list_term(self): 347 self.complete_from_to("settings list term-h", "settings list term-height") 348 349 def test_settings_remove_term(self): 350 self.complete_from_to("settings remove term-w", "settings remove term-width") 351 352 def test_settings_remove_term(self): 353 self.complete_from_to("settings remove term-h", "settings remove term-height") 354 355 def test_settings_s(self): 356 """Test that 'settings s' completes to ['set', 'show'].""" 357 self.complete_from_to("settings s", ["set", "show"]) 358 359 def test_settings_set_th(self): 360 """Test that 'settings set thread-f' completes to 'settings set thread-format'.""" 361 self.complete_from_to("settings set thread-f", "settings set thread-format") 362 363 def test_settings_s_dash(self): 364 """Test that 'settings set --g' completes to 'settings set --global'.""" 365 self.complete_from_to("settings set --g", "settings set --global") 366 367 def test_settings_clear_th(self): 368 """Test that 'settings clear thread-f' completes to 'settings clear thread-format'.""" 369 self.complete_from_to("settings clear thread-f", "settings clear thread-format") 370 371 def test_settings_set_ta(self): 372 """Test that 'settings set ta' completes to 'settings set target.'.""" 373 self.complete_from_to("settings set target.ma", "settings set target.max-") 374 375 def test_settings_set_target_exec(self): 376 """Test that 'settings set target.exec' completes to 'settings set target.exec-search-paths '.""" 377 self.complete_from_to( 378 "settings set target.exec", "settings set target.exec-search-paths" 379 ) 380 381 def test_settings_set_target_pr(self): 382 """Test that 'settings set target.pr' completes to [ 383 'target.prefer-dynamic-value', 'target.process.'].""" 384 self.complete_from_to( 385 "settings set target.pr", ["target.prefer-dynamic-value", "target.process."] 386 ) 387 388 def test_settings_set_target_process(self): 389 """Test that 'settings set target.process' completes to 'settings set target.process.'.""" 390 self.complete_from_to( 391 "settings set target.process", "settings set target.process." 392 ) 393 394 def test_settings_set_target_process_dot(self): 395 """Test that 'settings set target.process.t' completes to 'settings set target.process.thread.'.""" 396 self.complete_from_to( 397 "settings set target.process.thr", "settings set target.process.thread." 398 ) 399 400 def test_settings_set_target_process_thread_dot(self): 401 """Test that 'settings set target.process.thread.' completes to [ 402 'target.process.thread.step-avoid-regexp', 'target.process.thread.trace-thread']. 403 """ 404 self.complete_from_to( 405 "settings set target.process.thread.", 406 [ 407 "target.process.thread.step-avoid-regexp", 408 "target.process.thread.trace-thread", 409 ], 410 ) 411 412 def test_settings_set_can_complete_setting_enum_values(self): 413 """Checks that we can complete the values of an enum setting.""" 414 self.complete_from_to( 415 "settings set stop-disassembly-display ", 416 ["never", "always", "no-debuginfo", "no-source"], 417 ) 418 419 def test_thread_plan_discard(self): 420 self.build() 421 (_, _, thread, _) = lldbutil.run_to_source_breakpoint( 422 self, "ptr_foo", lldb.SBFileSpec("main.cpp") 423 ) 424 self.assertTrue(thread) 425 self.complete_from_to("thread plan discard ", "thread plan discard ") 426 427 source_path = os.path.join(self.getSourceDir(), "thread_plan_script.py") 428 self.runCmd("command script import '%s'" % (source_path)) 429 self.runCmd("thread step-scripted -C thread_plan_script.PushPlanStack") 430 self.complete_from_to("thread plan discard ", "thread plan discard 1") 431 self.runCmd("thread plan discard 1") 432 433 def test_target_space(self): 434 """Test that 'target ' completes to ['create', 'delete', 'list', 435 'modules', 'select', 'stop-hook', 'variable'].""" 436 self.complete_from_to( 437 "target ", 438 ["create", "delete", "list", "modules", "select", "stop-hook", "variable"], 439 ) 440 441 def test_target_modules_dump_line_table(self): 442 """Tests source file completion by completing the line-table argument.""" 443 self.build() 444 self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 445 self.complete_from_to("target modules dump line-table main.cp", ["main.cpp"]) 446 447 def test_custom_command_completion(self): 448 """Tests completion in custom user provided commands.""" 449 completion_types = [ 450 "none", 451 "source-file", 452 "disk-file", 453 "disk-directory", 454 "symbol", 455 "module", 456 "settings-name", 457 "platform-plugin", 458 "architecture", 459 "variable-path", 460 "register", 461 "breakpoint", 462 "process-plugin", 463 "disassembly-flavor", 464 "type-language", 465 "frame-index", 466 "module-uuid", 467 "stophook-id", 468 "thread-index", 469 "watchpoint-id", 470 "breakpoint-name", 471 "process-id", 472 "process-name", 473 "remote-disk-file", 474 "remote-disk-directory", 475 "type-category-name", 476 "custom", 477 ] 478 self.completions_contain("command script add -C ", completion_types) 479 480 source_path = os.path.join(self.getSourceDir(), "my_test_cmd.py") 481 self.runCmd("command script import '%s'" % (source_path)) 482 self.runCmd( 483 "command script add -C disk-file -f my_test_cmd.my_test_cmd my_test_cmd" 484 ) 485 self.complete_from_to("my_test_cmd main.cp", ["main.cpp"]) 486 self.expect("my_test_cmd main.cpp", substrs=["main.cpp"]) 487 488 @skipIf(hostoslist=["windows"]) 489 def test_completion_target_create_from_root_dir(self): 490 """Tests source file completion by completing .""" 491 root_dir = os.path.abspath(os.sep) 492 self.completions_contain( 493 "target create " + root_dir, 494 list( 495 filter( 496 lambda x: os.path.exists(x) and os.path.isdir(x), 497 map(lambda x: root_dir + x + os.sep, os.listdir(root_dir)), 498 ) 499 ), 500 ) 501 502 def test_target_modules_load_aout(self): 503 """Tests modules completion by completing the target modules load argument.""" 504 self.build() 505 self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 506 self.complete_from_to("target modules load a.ou", ["a.out"]) 507 508 def test_target_modules_search_paths_insert(self): 509 # Completion won't work without a valid target. 510 self.complete_from_to( 511 "target modules search-paths insert ", "target modules search-paths insert " 512 ) 513 self.build() 514 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 515 self.assertTrue(target, VALID_TARGET) 516 self.complete_from_to( 517 "target modules search-paths insert ", "target modules search-paths insert " 518 ) 519 self.runCmd("target modules search-paths add a b") 520 self.complete_from_to( 521 "target modules search-paths insert ", 522 "target modules search-paths insert 0", 523 ) 524 # Completion only works for the first arg. 525 self.complete_from_to( 526 "target modules search-paths insert 0 ", 527 "target modules search-paths insert 0 ", 528 ) 529 530 def test_target_create_dash_co(self): 531 """Test that 'target create --co' completes to 'target variable --core '.""" 532 self.complete_from_to("target create --co", "target create --core ") 533 534 def test_target_va(self): 535 """Test that 'target va' completes to 'target variable '.""" 536 self.complete_from_to("target va", "target variable ") 537 538 def test_common_completion_thread_index(self): 539 subcommands = [ 540 "continue", 541 "info", 542 "exception", 543 "select", 544 "step-in", 545 "step-inst", 546 "step-inst-over", 547 "step-out", 548 "step-over", 549 "step-script", 550 ] 551 552 # Completion should do nothing without threads. 553 for subcommand in subcommands: 554 self.complete_from_to( 555 "thread " + subcommand + " ", "thread " + subcommand + " " 556 ) 557 558 self.build() 559 lldbutil.run_to_source_breakpoint( 560 self, "// Break here", lldb.SBFileSpec("main.cpp") 561 ) 562 563 # At least we have the thread at the index of 1 now. 564 for subcommand in subcommands: 565 self.complete_from_to("thread " + subcommand + " ", ["1"]) 566 567 def test_common_completion_type_category_name(self): 568 subcommands = ["delete", "list", "enable", "disable", "define"] 569 for subcommand in subcommands: 570 self.complete_from_to("type category " + subcommand + " ", ["default"]) 571 self.complete_from_to("type filter add -w ", ["default"]) 572 573 def test_command_argument_completion(self): 574 """Test completion of command arguments""" 575 self.complete_from_to("watchpoint set variable -", ["-w", "-s"]) 576 self.complete_from_to( 577 "watchpoint set variable -w", "watchpoint set variable -w " 578 ) 579 self.complete_from_to("watchpoint set variable --", ["--watch", "--size"]) 580 self.complete_from_to( 581 "watchpoint set variable --w", "watchpoint set variable --watch" 582 ) 583 self.complete_from_to( 584 "watchpoint set variable -w ", ["read", "write", "read_write"] 585 ) 586 self.complete_from_to( 587 "watchpoint set variable --watch ", ["read", "write", "read_write"] 588 ) 589 self.complete_from_to( 590 "watchpoint set variable --watch w", "watchpoint set variable --watch write" 591 ) 592 self.complete_from_to( 593 "watchpoint set variable -w read_", "watchpoint set variable -w read_write" 594 ) 595 # Now try the same thing with a variable name (non-option argument) to 596 # test that getopts arg reshuffling doesn't confuse us. 597 self.complete_from_to("watchpoint set variable foo -", ["-w", "-s"]) 598 self.complete_from_to( 599 "watchpoint set variable foo -w", "watchpoint set variable foo -w " 600 ) 601 self.complete_from_to("watchpoint set variable foo --", ["--watch", "--size"]) 602 self.complete_from_to( 603 "watchpoint set variable foo --w", "watchpoint set variable foo --watch" 604 ) 605 self.complete_from_to( 606 "watchpoint set variable foo -w ", ["read", "write", "read_write"] 607 ) 608 self.complete_from_to( 609 "watchpoint set variable foo --watch ", ["read", "write", "read_write"] 610 ) 611 self.complete_from_to( 612 "watchpoint set variable foo --watch w", 613 "watchpoint set variable foo --watch write", 614 ) 615 self.complete_from_to( 616 "watchpoint set variable foo -w read_", 617 "watchpoint set variable foo -w read_write", 618 ) 619 620 def test_command_script_delete(self): 621 self.runCmd("command script add -h test_desc -f none -s current usercmd1") 622 self.check_completion_with_desc("command script delete ", [["usercmd1", ""]]) 623 624 def test_command_delete(self): 625 self.runCmd( 626 r"command regex test_command s/^$/finish/ 's/([0-9]+)/frame select %1/'" 627 ) 628 self.complete_from_to("command delete test_c", "command delete test_command") 629 630 def test_command_unalias(self): 631 self.complete_from_to("command unalias ima", "command unalias image") 632 633 def test_command_aliases(self): 634 self.runCmd("command alias brkpt breakpoint") 635 # Exact matches are chosen if possible, even if there are longer 636 # completions we could use. 637 self.complete_from_to("b", "b ") 638 # Aliases are included in possible completions. 639 self.complete_from_to("br", ["breakpoint", "brkpt"]) 640 # An alias can be the chosen completion. 641 self.complete_from_to("brk", "brkpt") 642 643 # The list can contain only aliases if there's no built-ins to match. 644 self.runCmd("command alias test_1 breakpoint") 645 self.runCmd("command alias test_2 breakpoint") 646 self.complete_from_to("test_", ["test_1", "test_2"]) 647 648 def test_completion_description_commands(self): 649 """Test descriptions of top-level command completions""" 650 self.check_completion_with_desc( 651 "", 652 [ 653 ["command", "Commands for managing custom LLDB commands."], 654 [ 655 "breakpoint", 656 "Commands for operating on breakpoints (see 'help b' for shorthand.)", 657 ], 658 ], 659 ) 660 661 self.check_completion_with_desc( 662 "pl", 663 [ 664 ["platform", "Commands to manage and create platforms."], 665 ["plugin", "Commands for managing LLDB plugins."], 666 ], 667 ) 668 669 # Just check that this doesn't crash. 670 self.check_completion_with_desc("comman", []) 671 self.check_completion_with_desc("non-existent-command", []) 672 673 def test_completion_description_command_options(self): 674 """Test descriptions of command options""" 675 # Short options 676 self.check_completion_with_desc( 677 "breakpoint set -", 678 [ 679 ["-h", "Set the breakpoint on exception catcH."], 680 ["-w", "Set the breakpoint on exception throW."], 681 ], 682 ) 683 684 # Long options. 685 self.check_completion_with_desc( 686 "breakpoint set --", 687 [ 688 ["--on-catch", "Set the breakpoint on exception catcH."], 689 ["--on-throw", "Set the breakpoint on exception throW."], 690 ], 691 ) 692 693 # Ambiguous long options. 694 self.check_completion_with_desc( 695 "breakpoint set --on-", 696 [ 697 ["--on-catch", "Set the breakpoint on exception catcH."], 698 ["--on-throw", "Set the breakpoint on exception throW."], 699 ], 700 ) 701 702 # Unknown long option. 703 self.check_completion_with_desc("breakpoint set --Z", []) 704 705 def test_common_completion_frame_index(self): 706 self.build() 707 lldbutil.run_to_source_breakpoint( 708 self, "// Break here", lldb.SBFileSpec("main.cpp") 709 ) 710 711 self.complete_from_to("frame select ", ["0"]) 712 self.complete_from_to("thread backtrace -s ", ["0"]) 713 714 def test_frame_recognizer_delete(self): 715 self.runCmd( 716 "frame recognizer add -l py_class -s module_name -n recognizer_name" 717 ) 718 self.check_completion_with_desc( 719 "frame recognizer delete ", 720 [["0", "py_class, module module_name, demangled symbol recognizer_name"]], 721 ) 722 723 def test_platform_install_local_file(self): 724 self.complete_from_to( 725 "platform target-install main.cp", "platform target-install main.cpp" 726 ) 727 728 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489") 729 def test_symbol_name(self): 730 self.build() 731 self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 732 self.complete_from_to( 733 "breakpoint set -n Fo", "breakpoint set -n Foo::Bar(int,\\ int)" 734 ) 735 # No completion for Qu because the candidate is 736 # (anonymous namespace)::Quux(). 737 self.complete_from_to("breakpoint set -n Qu", "") 738 739 def test_completion_type_formatter_delete(self): 740 self.runCmd("type filter add --child a Aoo") 741 self.complete_from_to("type filter delete ", ["Aoo"]) 742 self.runCmd("type filter add --child b -x Boo") 743 self.complete_from_to("type filter delete ", ["Boo"]) 744 745 self.runCmd("type format add -f hex Coo") 746 self.complete_from_to("type format delete ", ["Coo"]) 747 self.runCmd("type format add -f hex -x Doo") 748 self.complete_from_to("type format delete ", ["Doo"]) 749 750 self.runCmd("type summary add -c Eoo") 751 self.complete_from_to("type summary delete ", ["Eoo"]) 752 self.runCmd("type summary add -x -c Foo") 753 self.complete_from_to("type summary delete ", ["Foo"]) 754 755 self.runCmd("type synthetic add Goo -l test") 756 self.complete_from_to("type synthetic delete ", ["Goo"]) 757 self.runCmd("type synthetic add -x Hoo -l test") 758 self.complete_from_to("type synthetic delete ", ["Hoo"]) 759 760 def test_register_no_complete(self): 761 # The tab completion for "register read/write" won't work without a running process. 762 self.complete_from_to("register read ", "register read ") 763 self.complete_from_to("register write ", "register write ") 764 self.complete_from_to("register info ", "register info ") 765 766 self.build() 767 self.runCmd("target create {}".format(self.getBuildArtifact("a.out"))) 768 self.runCmd("run") 769 770 # Once a program has finished you have an execution context but no register 771 # context so completion cannot work. 772 self.complete_from_to("register read ", "register read ") 773 self.complete_from_to("register write ", "register write ") 774 self.complete_from_to("register info ", "register info ") 775 776 @skipIf(archs=no_match(["x86_64"])) 777 def test_register_read_and_write_on_x86(self): 778 """Test the completion of the commands register read and write on x86""" 779 780 self.build() 781 self.main_source_spec = lldb.SBFileSpec("main.cpp") 782 lldbutil.run_to_source_breakpoint(self, "// Break here", self.main_source_spec) 783 784 # test cases for register read 785 self.complete_from_to("register read ", ["rax", "rbx", "rcx"]) 786 self.complete_from_to("register read r", ["rax", "rbx", "rcx"]) 787 self.complete_from_to("register read ra", "register read rax") 788 # register read can take multiple register names as arguments 789 self.complete_from_to("register read rax ", ["rax", "rbx", "rcx"]) 790 # complete with prefix '$' 791 self.completions_match("register read $rb", ["$rbx", "$rbp"]) 792 self.completions_match("register read $ra", ["$rax"]) 793 self.complete_from_to("register read rax $", ["$rax", "$rbx", "$rcx"]) 794 self.complete_from_to("register read $rax ", ["rax", "rbx", "rcx"]) 795 796 # test cases for register write 797 self.complete_from_to("register write ", ["rax", "rbx", "rcx"]) 798 self.complete_from_to("register write r", ["rax", "rbx", "rcx"]) 799 self.complete_from_to("register write ra", "register write rax") 800 self.complete_from_to("register write rb", ["rbx", "rbp"]) 801 # register write can only take exact one register name as argument 802 self.complete_from_to("register write rbx ", []) 803 804 def test_common_completion_target_stophook_ids(self): 805 subcommands = ["delete", "enable", "disable"] 806 807 for subcommand in subcommands: 808 self.complete_from_to( 809 "target stop-hook " + subcommand + " ", 810 "target stop-hook " + subcommand + " ", 811 ) 812 813 self.build() 814 self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 815 self.runCmd("target stop-hook add -o test") 816 817 for subcommand in subcommands: 818 self.complete_from_to( 819 "target stop-hook " + subcommand + " ", 820 "target stop-hook " + subcommand + " 1", 821 ) 822 823 # Completion should work only on the first argument. 824 for subcommand in subcommands: 825 self.complete_from_to( 826 "target stop-hook " + subcommand + " 1 ", 827 "target stop-hook " + subcommand + " 1 ", 828 ) 829 830 def test_common_completion_type_language(self): 831 self.complete_from_to("type category -l ", ["c"]) 832 833 def test_target_modules_load_dash_u(self): 834 self.build() 835 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 836 self.complete_from_to( 837 "target modules load -u ", [target.GetModuleAtIndex(0).GetUUIDString()] 838 ) 839 840 def test_complete_breakpoint_with_ids(self): 841 """These breakpoint subcommands should be completed with a list of breakpoint ids""" 842 843 subcommands = [ 844 "enable", 845 "disable", 846 "delete", 847 "modify", 848 "name add", 849 "name delete", 850 "write", 851 ] 852 853 # The tab completion here is unavailable without a target 854 for subcommand in subcommands: 855 self.complete_from_to( 856 "breakpoint " + subcommand + " ", "breakpoint " + subcommand + " " 857 ) 858 859 self.build() 860 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 861 self.assertTrue(target, VALID_TARGET) 862 863 bp = target.BreakpointCreateByName("main", "a.out") 864 self.assertTrue(bp) 865 self.assertEqual(bp.GetNumLocations(), 1) 866 867 for subcommand in subcommands: 868 self.complete_from_to("breakpoint " + subcommand + " ", ["1"]) 869 870 bp2 = target.BreakpointCreateByName("Bar", "a.out") 871 self.assertTrue(bp2) 872 self.assertEqual(bp2.GetNumLocations(), 1) 873 874 for subcommand in subcommands: 875 self.complete_from_to("breakpoint " + subcommand + " ", ["1", "2"]) 876 877 for subcommand in subcommands: 878 self.complete_from_to("breakpoint " + subcommand + " 1 ", ["1", "2"]) 879 880 def test_complete_breakpoint_with_names(self): 881 self.build() 882 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 883 self.assertTrue(target, VALID_TARGET) 884 885 # test breakpoint read dedicated 886 self.complete_from_to("breakpoint read -N ", "breakpoint read -N ") 887 self.complete_from_to("breakpoint read -f breakpoints.json -N ", ["mm"]) 888 self.complete_from_to( 889 "breakpoint read -f breakpoints.json -N n", 890 "breakpoint read -f breakpoints.json -N n", 891 ) 892 self.complete_from_to( 893 "breakpoint read -f breakpoints_invalid.json -N ", 894 "breakpoint read -f breakpoints_invalid.json -N ", 895 ) 896 897 # test common breapoint name completion 898 bp1 = target.BreakpointCreateByName("main", "a.out") 899 self.assertTrue(bp1) 900 self.assertEqual(bp1.GetNumLocations(), 1) 901 self.complete_from_to("breakpoint set -N n", "breakpoint set -N n") 902 self.assertTrue(bp1.AddNameWithErrorHandling("nn")) 903 self.complete_from_to("breakpoint set -N ", "breakpoint set -N nn") 904 905 def test_ambiguous_command(self): 906 """Test completing an ambiguous commands""" 907 self.complete_from_to("settings s", ["set", "show"]) 908 909 def test_ambiguous_subcommand(self): 910 """Test completing a subcommand of an ambiguous command""" 911 self.complete_from_to("settings s ta", []) 912 913 def test_shlib_name(self): 914 self.build() 915 error = lldb.SBError() 916 # Create a target, but don't load dependent modules 917 target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"), None, None, False, error) 918 self.assertSuccess(error) 919 self.registerSharedLibrariesWithTarget(target, ["shared"]) 920 921 basenames = [] 922 paths = [] 923 for m in target.modules: 924 basenames.append(m.file.basename) 925 paths.append(m.file.fullpath) 926 927 # To see all the diffs 928 self.maxDiff = None 929 930 # An empty string completes to everything 931 self.completions_match("target symbols add -s ", basenames + paths) 932 933 # Base name completion 934 self.completions_match("target symbols add -s a.", ["a.out"]) 935 936 # Full path completion 937 prefix = os.path.commonpath(paths) 938 self.completions_match("target symbols add -s '" + prefix, paths) 939 940 # Full path, but ending with a path separator 941 prefix_sep = prefix + os.path.sep 942 self.completions_match("target symbols add -s '" + prefix_sep, paths) 943 944 # The completed path should match the spelling of the input, so if the 945 # input contains a double separator, so should the completions. 946 prefix_sep_sep = prefix_sep + os.path.sep 947 paths_sep = [prefix_sep_sep + p[len(prefix_sep) :] for p in paths] 948 self.completions_match("target symbols add -s '" + prefix_sep_sep, paths_sep) 949