1""" 2Test the lldb command line completion mechanism. 3""" 4 5 6 7import os 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 17 mydir = TestBase.compute_mydir(__file__) 18 19 NO_DEBUG_INFO_TESTCASE = True 20 21 @classmethod 22 def classCleanup(cls): 23 """Cleanup the test byproducts.""" 24 try: 25 os.remove("child_send.txt") 26 os.remove("child_read.txt") 27 except: 28 pass 29 30 def test_at(self): 31 """Test that 'at' completes to 'attach '.""" 32 self.complete_from_to('at', 'attach ') 33 34 def test_de(self): 35 """Test that 'de' completes to 'detach '.""" 36 self.complete_from_to('de', 'detach ') 37 38 def test_frame_variable(self): 39 self.build() 40 self.main_source = "main.cpp" 41 self.main_source_spec = lldb.SBFileSpec(self.main_source) 42 43 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, 44 '// Break here', self.main_source_spec) 45 self.assertEquals(process.GetState(), lldb.eStateStopped) 46 47 # Since CommandInterpreter has been corrected to update the current execution 48 # context at the beginning of HandleCompletion, we're here explicitly testing 49 # the scenario where "frame var" is completed without any preceding commands. 50 51 self.complete_from_to('frame variable fo', 52 'frame variable fooo') 53 self.complete_from_to('frame variable fooo.', 54 'frame variable fooo.') 55 self.complete_from_to('frame variable fooo.dd', 56 'frame variable fooo.dd') 57 58 self.complete_from_to('frame variable ptr_fooo->', 59 'frame variable ptr_fooo->') 60 self.complete_from_to('frame variable ptr_fooo->dd', 61 'frame variable ptr_fooo->dd') 62 63 self.complete_from_to('frame variable cont', 64 'frame variable container') 65 self.complete_from_to('frame variable container.', 66 'frame variable container.MemberVar') 67 self.complete_from_to('frame variable container.Mem', 68 'frame variable container.MemberVar') 69 70 self.complete_from_to('frame variable ptr_cont', 71 'frame variable ptr_container') 72 self.complete_from_to('frame variable ptr_container->', 73 'frame variable ptr_container->MemberVar') 74 self.complete_from_to('frame variable ptr_container->Mem', 75 'frame variable ptr_container->MemberVar') 76 77 def test_process_attach_dash_dash_con(self): 78 """Test that 'process attach --con' completes to 'process attach --continue '.""" 79 self.complete_from_to( 80 'process attach --con', 81 'process attach --continue ') 82 83 def test_process_launch_arch(self): 84 self.complete_from_to('process launch --arch ', 85 ['mips', 86 'arm64']) 87 88 def test_process_signal(self): 89 # The tab completion for "process signal" won't work without a running process. 90 self.complete_from_to('process signal ', 91 'process signal ') 92 93 # Test with a running process. 94 self.build() 95 self.main_source = "main.cpp" 96 self.main_source_spec = lldb.SBFileSpec(self.main_source) 97 lldbutil.run_to_source_breakpoint(self, '// Break here', self.main_source_spec) 98 99 self.complete_from_to('process signal ', 100 'process signal SIG') 101 self.complete_from_to('process signal SIGA', 102 ['SIGABRT', 103 'SIGALRM']) 104 105 def test_ambiguous_long_opt(self): 106 self.completions_match('breakpoint modify --th', 107 ['--thread-id', 108 '--thread-index', 109 '--thread-name']) 110 111 def test_plugin_load(self): 112 self.complete_from_to('plugin load ', []) 113 114 def test_log_enable(self): 115 self.complete_from_to('log enable ll', ['lldb']) 116 self.complete_from_to('log enable dw', ['dwarf']) 117 self.complete_from_to('log enable lldb al', ['all']) 118 self.complete_from_to('log enable lldb sym', ['symbol']) 119 120 def test_log_enable(self): 121 self.complete_from_to('log disable ll', ['lldb']) 122 self.complete_from_to('log disable dw', ['dwarf']) 123 self.complete_from_to('log disable lldb al', ['all']) 124 self.complete_from_to('log disable lldb sym', ['symbol']) 125 126 def test_log_list(self): 127 self.complete_from_to('log list ll', ['lldb']) 128 self.complete_from_to('log list dw', ['dwarf']) 129 self.complete_from_to('log list ll', ['lldb']) 130 self.complete_from_to('log list lldb dwa', ['dwarf']) 131 132 def test_quoted_command(self): 133 self.complete_from_to('"set', 134 ['"settings" ']) 135 136 def test_quoted_arg_with_quoted_command(self): 137 self.complete_from_to('"settings" "repl', 138 ['"replace" ']) 139 140 def test_quoted_arg_without_quoted_command(self): 141 self.complete_from_to('settings "repl', 142 ['"replace" ']) 143 144 def test_single_quote_command(self): 145 self.complete_from_to("'set", 146 ["'settings' "]) 147 148 def test_terminated_quote_command(self): 149 # This should not crash, but we don't get any 150 # reasonable completions from this. 151 self.complete_from_to("'settings'", []) 152 153 def test_process_launch_arch_arm(self): 154 self.complete_from_to('process launch --arch arm', 155 ['arm64']) 156 157 def test_target_symbols_add_shlib(self): 158 # Doesn't seem to work, but at least it shouldn't crash. 159 self.complete_from_to('target symbols add --shlib ', []) 160 161 def test_log_file(self): 162 # Complete in our source directory which contains a 'main.cpp' file. 163 src_dir = os.path.dirname(os.path.realpath(__file__)) + '/' 164 self.complete_from_to('log enable lldb expr -f ' + src_dir, 165 ['main.cpp']) 166 167 def test_log_dir(self): 168 # Complete our source directory. 169 src_dir = os.path.dirname(os.path.realpath(__file__)) 170 self.complete_from_to('log enable lldb expr -f ' + src_dir, 171 [src_dir + os.sep], turn_off_re_match=True) 172 173 # <rdar://problem/11052829> 174 def test_infinite_loop_while_completing(self): 175 """Test that 'process print hello\' completes to itself and does not infinite loop.""" 176 self.complete_from_to('process print hello\\', 'process print hello\\', 177 turn_off_re_match=True) 178 179 def test_watchpoint_co(self): 180 """Test that 'watchpoint co' completes to 'watchpoint command '.""" 181 self.complete_from_to('watchpoint co', 'watchpoint command ') 182 183 def test_watchpoint_command_space(self): 184 """Test that 'watchpoint command ' completes to ['add', 'delete', 'list'].""" 185 self.complete_from_to( 186 'watchpoint command ', [ 187 'add', 'delete', 'list']) 188 189 def test_watchpoint_command_a(self): 190 """Test that 'watchpoint command a' completes to 'watchpoint command add '.""" 191 self.complete_from_to( 192 'watchpoint command a', 193 'watchpoint command add ') 194 195 def test_watchpoint_set_ex(self): 196 """Test that 'watchpoint set ex' completes to 'watchpoint set expression '.""" 197 self.complete_from_to( 198 'watchpoint set ex', 199 'watchpoint set expression ') 200 201 def test_watchpoint_set_var(self): 202 """Test that 'watchpoint set var' completes to 'watchpoint set variable '.""" 203 self.complete_from_to('watchpoint set var', 'watchpoint set variable ') 204 205 def test_help_fi(self): 206 """Test that 'help fi' completes to ['file', 'finish'].""" 207 self.complete_from_to( 208 'help fi', [ 209 'file', 'finish']) 210 211 def test_help_watchpoint_s(self): 212 """Test that 'help watchpoint s' completes to 'help watchpoint set '.""" 213 self.complete_from_to('help watchpoint s', 'help watchpoint set ') 214 215 def test_settings_append_target_er(self): 216 """Test that 'settings append target.er' completes to 'settings append target.error-path'.""" 217 self.complete_from_to( 218 'settings append target.er', 219 'settings append target.error-path') 220 221 def test_settings_insert_after_target_en(self): 222 """Test that 'settings insert-after target.env' completes to 'settings insert-after target.env-vars'.""" 223 self.complete_from_to( 224 'settings insert-after target.env', 225 'settings insert-after target.env-vars') 226 227 def test_settings_insert_before_target_en(self): 228 """Test that 'settings insert-before target.env' completes to 'settings insert-before target.env-vars'.""" 229 self.complete_from_to( 230 'settings insert-before target.env', 231 'settings insert-before target.env-vars') 232 233 def test_settings_replace_target_ru(self): 234 """Test that 'settings replace target.ru' completes to 'settings replace target.run-args'.""" 235 self.complete_from_to( 236 'settings replace target.ru', 237 'settings replace target.run-args') 238 239 def test_settings_show_term(self): 240 self.complete_from_to( 241 'settings show term-', 242 'settings show term-width') 243 244 def test_settings_list_term(self): 245 self.complete_from_to( 246 'settings list term-', 247 'settings list term-width') 248 249 def test_settings_remove_term(self): 250 self.complete_from_to( 251 'settings remove term-', 252 'settings remove term-width') 253 254 def test_settings_s(self): 255 """Test that 'settings s' completes to ['set', 'show'].""" 256 self.complete_from_to( 257 'settings s', [ 258 'set', 'show']) 259 260 def test_settings_set_th(self): 261 """Test that 'settings set thread-f' completes to 'settings set thread-format'.""" 262 self.complete_from_to('settings set thread-f', 'settings set thread-format') 263 264 def test_settings_s_dash(self): 265 """Test that 'settings set --g' completes to 'settings set --global'.""" 266 self.complete_from_to('settings set --g', 'settings set --global') 267 268 def test_settings_clear_th(self): 269 """Test that 'settings clear thread-f' completes to 'settings clear thread-format'.""" 270 self.complete_from_to( 271 'settings clear thread-f', 272 'settings clear thread-format') 273 274 def test_settings_set_ta(self): 275 """Test that 'settings set ta' completes to 'settings set target.'.""" 276 self.complete_from_to( 277 'settings set target.ma', 278 'settings set target.max-') 279 280 def test_settings_set_target_exec(self): 281 """Test that 'settings set target.exec' completes to 'settings set target.exec-search-paths '.""" 282 self.complete_from_to( 283 'settings set target.exec', 284 'settings set target.exec-search-paths') 285 286 def test_settings_set_target_pr(self): 287 """Test that 'settings set target.pr' completes to [ 288 'target.prefer-dynamic-value', 'target.process.'].""" 289 self.complete_from_to('settings set target.pr', 290 ['target.prefer-dynamic-value', 291 'target.process.']) 292 293 def test_settings_set_target_process(self): 294 """Test that 'settings set target.process' completes to 'settings set target.process.'.""" 295 self.complete_from_to( 296 'settings set target.process', 297 'settings set target.process.') 298 299 def test_settings_set_target_process_dot(self): 300 """Test that 'settings set target.process.t' completes to 'settings set target.process.thread.'.""" 301 self.complete_from_to( 302 'settings set target.process.t', 303 'settings set target.process.thread.') 304 305 def test_settings_set_target_process_thread_dot(self): 306 """Test that 'settings set target.process.thread.' completes to [ 307 'target.process.thread.step-avoid-regexp', 'target.process.thread.trace-thread'].""" 308 self.complete_from_to('settings set target.process.thread.', 309 ['target.process.thread.step-avoid-regexp', 310 'target.process.thread.trace-thread']) 311 312 def test_target_space(self): 313 """Test that 'target ' completes to ['create', 'delete', 'list', 314 'modules', 'select', 'stop-hook', 'variable'].""" 315 self.complete_from_to('target ', 316 ['create', 317 'delete', 318 'list', 319 'modules', 320 'select', 321 'stop-hook', 322 'variable']) 323 324 def test_target_modules_dump_line_table(self): 325 """Tests source file completion by completing the line-table argument.""" 326 self.build() 327 self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 328 self.complete_from_to('target modules dump line-table main.cp', 329 ['main.cpp']) 330 331 def test_target_modules_load_aout(self): 332 """Tests modules completion by completing the target modules load argument.""" 333 self.build() 334 self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 335 self.complete_from_to('target modules load a.ou', 336 ['a.out']) 337 338 def test_target_create_dash_co(self): 339 """Test that 'target create --co' completes to 'target variable --core '.""" 340 self.complete_from_to('target create --co', 'target create --core ') 341 342 def test_target_va(self): 343 """Test that 'target va' completes to 'target variable '.""" 344 self.complete_from_to('target va', 'target variable ') 345 346 def test_command_argument_completion(self): 347 """Test completion of command arguments""" 348 self.complete_from_to("watchpoint set variable -", ["-w", "-s"]) 349 self.complete_from_to('watchpoint set variable -w', 'watchpoint set variable -w ') 350 self.complete_from_to("watchpoint set variable --", ["--watch", "--size"]) 351 self.complete_from_to("watchpoint set variable --w", "watchpoint set variable --watch") 352 self.complete_from_to('watchpoint set variable -w ', ['read', 'write', 'read_write']) 353 self.complete_from_to("watchpoint set variable --watch ", ["read", "write", "read_write"]) 354 self.complete_from_to("watchpoint set variable --watch w", "watchpoint set variable --watch write") 355 self.complete_from_to('watchpoint set variable -w read_', 'watchpoint set variable -w read_write') 356 # Now try the same thing with a variable name (non-option argument) to 357 # test that getopts arg reshuffling doesn't confuse us. 358 self.complete_from_to("watchpoint set variable foo -", ["-w", "-s"]) 359 self.complete_from_to('watchpoint set variable foo -w', 'watchpoint set variable foo -w ') 360 self.complete_from_to("watchpoint set variable foo --", ["--watch", "--size"]) 361 self.complete_from_to("watchpoint set variable foo --w", "watchpoint set variable foo --watch") 362 self.complete_from_to('watchpoint set variable foo -w ', ['read', 'write', 'read_write']) 363 self.complete_from_to("watchpoint set variable foo --watch ", ["read", "write", "read_write"]) 364 self.complete_from_to("watchpoint set variable foo --watch w", "watchpoint set variable foo --watch write") 365 self.complete_from_to('watchpoint set variable foo -w read_', 'watchpoint set variable foo -w read_write') 366 367 def test_completion_description_commands(self): 368 """Test descriptions of top-level command completions""" 369 self.check_completion_with_desc("", [ 370 ["command", "Commands for managing custom LLDB commands."], 371 ["breakpoint", "Commands for operating on breakpoints (see 'help b' for shorthand.)"] 372 ]) 373 374 self.check_completion_with_desc("pl", [ 375 ["platform", "Commands to manage and create platforms."], 376 ["plugin", "Commands for managing LLDB plugins."] 377 ]) 378 379 # Just check that this doesn't crash. 380 self.check_completion_with_desc("comman", []) 381 self.check_completion_with_desc("non-existent-command", []) 382 383 def test_completion_description_command_options(self): 384 """Test descriptions of command options""" 385 # Short options 386 self.check_completion_with_desc("breakpoint set -", [ 387 ["-h", "Set the breakpoint on exception catcH."], 388 ["-w", "Set the breakpoint on exception throW."] 389 ]) 390 391 # Long options. 392 self.check_completion_with_desc("breakpoint set --", [ 393 ["--on-catch", "Set the breakpoint on exception catcH."], 394 ["--on-throw", "Set the breakpoint on exception throW."] 395 ]) 396 397 # Ambiguous long options. 398 self.check_completion_with_desc("breakpoint set --on-", [ 399 ["--on-catch", "Set the breakpoint on exception catcH."], 400 ["--on-throw", "Set the breakpoint on exception throW."] 401 ]) 402 403 # Unknown long option. 404 self.check_completion_with_desc("breakpoint set --Z", [ 405 ]) 406 407 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489") 408 def test_symbol_name(self): 409 self.build() 410 self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 411 self.complete_from_to('breakpoint set -n Fo', 412 'breakpoint set -n Foo::Bar(int,\\ int)', 413 turn_off_re_match=True) 414 # No completion for Qu because the candidate is 415 # (anonymous namespace)::Quux(). 416 self.complete_from_to('breakpoint set -n Qu', '') 417 418 @skipIf(archs=no_match(['x86_64'])) 419 def test_register_read_and_write_on_x86(self): 420 """Test the completion of the commands register read and write on x86""" 421 422 # The tab completion for "register read/write" won't work without a running process. 423 self.complete_from_to('register read ', 424 'register read ') 425 self.complete_from_to('register write ', 426 'register write ') 427 428 self.build() 429 self.main_source_spec = lldb.SBFileSpec("main.cpp") 430 lldbutil.run_to_source_breakpoint(self, '// Break here', self.main_source_spec) 431 432 # test cases for register read 433 self.complete_from_to('register read ', 434 ['rax', 435 'rbx', 436 'rcx']) 437 self.complete_from_to('register read r', 438 ['rax', 439 'rbx', 440 'rcx']) 441 self.complete_from_to('register read ra', 442 'register read rax') 443 # register read can take multiple register names as arguments 444 self.complete_from_to('register read rax ', 445 ['rax', 446 'rbx', 447 'rcx']) 448 # complete with prefix '$' 449 self.completions_match('register read $rb', 450 ['$rbx', 451 '$rbp']) 452 self.completions_match('register read $ra', 453 ['$rax']) 454 self.complete_from_to('register read rax $', 455 ['\$rax', 456 '\$rbx', 457 '\$rcx']) 458 self.complete_from_to('register read $rax ', 459 ['rax', 460 'rbx', 461 'rcx']) 462 463 # test cases for register write 464 self.complete_from_to('register write ', 465 ['rax', 466 'rbx', 467 'rcx']) 468 self.complete_from_to('register write r', 469 ['rax', 470 'rbx', 471 'rcx']) 472 self.complete_from_to('register write ra', 473 'register write rax') 474 self.complete_from_to('register write rb', 475 ['rbx', 476 'rbp']) 477 # register write can only take exact one register name as argument 478 self.complete_from_to('register write rbx ', 479 []) 480 481 def test_complete_breakpoint_with_ids(self): 482 """These breakpoint subcommands should be completed with a list of breakpoint ids""" 483 484 subcommands = ['enable', 'disable', 'delete', 'modify', 'name add', 'name delete', 'write'] 485 486 # The tab completion here is unavailable without a target 487 for subcommand in subcommands: 488 self.complete_from_to('breakpoint ' + subcommand + ' ', 489 'breakpoint ' + subcommand + ' ') 490 491 self.build() 492 target = self.dbg.CreateTarget(self.getBuildArtifact('a.out')) 493 self.assertTrue(target, VALID_TARGET) 494 495 bp = target.BreakpointCreateByName('main', 'a.out') 496 self.assertTrue(bp) 497 self.assertEqual(bp.GetNumLocations(), 1) 498 499 for subcommand in subcommands: 500 self.complete_from_to('breakpoint ' + subcommand + ' ', 501 ['1']) 502 503 bp2 = target.BreakpointCreateByName('Bar', 'a.out') 504 self.assertTrue(bp2) 505 self.assertEqual(bp2.GetNumLocations(), 1) 506 507 for subcommand in subcommands: 508 self.complete_from_to('breakpoint ' + subcommand + ' ', 509 ['1', 510 '2']) 511 512 for subcommand in subcommands: 513 self.complete_from_to('breakpoint ' + subcommand + ' 1 ', 514 ['1', 515 '2']) 516 517