949 lines · python
1"""2Test the lldb command line completion mechanism.3"""4 5 6import os7from multiprocessing import Process8import lldb9from lldbsuite.test.decorators import *10from lldbsuite.test.lldbtest import *11from lldbsuite.test import lldbplatform12from lldbsuite.test import lldbutil13 14 15class CommandLineCompletionTestCase(TestBase):16 NO_DEBUG_INFO_TESTCASE = True17 18 @classmethod19 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 pass26 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 execution44 # context at the beginning of HandleCompletion, we're here explicitly testing45 # 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 execution57 # context at the beginning of HandleCompletion, we're here explicitly testing58 # 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 = False143 for match in match_strings:144 if needle in match:145 found_needle = True146 break147 self.assertTrue(148 found_needle, "Returned completions: " + "\n".join(match_strings)149 )150 151 @skipIfRemote152 def test_common_completion_process_pid_and_name(self):153 # The LLDB process itself and the process already attached to are both154 # ignored by the process discovery mechanism, thus we need a process known155 # 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 early162 install_remote=False,163 )164 self.assertIsNotNone(server)165 pid = server.pid166 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 any225 # 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 @expectedFailureNetBSD292 @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_width(self):338 self.complete_from_to("settings show term-w", "settings show term-width")339 340 def test_settings_list_term_width(self):341 self.complete_from_to("settings list term-w", "settings list term-width")342 343 def test_settings_show_term_height(self):344 self.complete_from_to("settings show term-h", "settings show term-height")345 346 def test_settings_list_term_height(self):347 self.complete_from_to("settings list term-h", "settings list term-height")348 349 def test_settings_remove_term_width(self):350 self.complete_from_to("settings remove term-w", "settings remove term-width")351 352 def test_settings_remove_term_height(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) to596 # 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 longer636 # 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 options676 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 is736 # (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 register771 # 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 read785 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 arguments789 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 write797 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 argument802 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 target854 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 dedicated886 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 completion898 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 modules917 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 diffs928 self.maxDiff = None929 930 # An empty string completes to everything931 self.completions_match("target symbols add -s ", basenames + paths)932 933 # Base name completion934 self.completions_match("target symbols add -s a.", ["a.out"])935 936 # Full path completion937 prefix = os.path.commonpath(paths)938 self.completions_match("target symbols add -s '" + prefix, paths)939 940 # Full path, but ending with a path separator941 prefix_sep = prefix + os.path.sep942 self.completions_match("target symbols add -s '" + prefix_sep, paths)943 944 # The completed path should match the spelling of the input, so if the945 # input contains a double separator, so should the completions.946 prefix_sep_sep = prefix_sep + os.path.sep947 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