1 //===-- CommandObject.cpp ---------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Interpreter/CommandObject.h" 11 12 #include <string> 13 #include <sstream> 14 #include <map> 15 16 #include <stdlib.h> 17 #include <ctype.h> 18 19 #include "lldb/Core/Address.h" 20 #include "lldb/Core/ArchSpec.h" 21 #include "lldb/Interpreter/Options.h" 22 23 // These are for the Sourcename completers. 24 // FIXME: Make a separate file for the completers. 25 #include "lldb/Host/FileSpec.h" 26 #include "lldb/Core/FileSpecList.h" 27 #include "lldb/DataFormatters/FormatManager.h" 28 #include "lldb/Target/Process.h" 29 #include "lldb/Target/Target.h" 30 31 #include "lldb/Target/Language.h" 32 33 #include "lldb/Interpreter/CommandInterpreter.h" 34 #include "lldb/Interpreter/CommandReturnObject.h" 35 36 using namespace lldb; 37 using namespace lldb_private; 38 39 //------------------------------------------------------------------------- 40 // CommandObject 41 //------------------------------------------------------------------------- 42 43 CommandObject::CommandObject 44 ( 45 CommandInterpreter &interpreter, 46 const char *name, 47 const char *help, 48 const char *syntax, 49 uint32_t flags 50 ) : 51 m_interpreter (interpreter), 52 m_cmd_name (name ? name : ""), 53 m_cmd_help_short (), 54 m_cmd_help_long (), 55 m_cmd_syntax (), 56 m_flags (flags), 57 m_arguments(), 58 m_deprecated_command_override_callback (nullptr), 59 m_command_override_callback (nullptr), 60 m_command_override_baton (nullptr) 61 { 62 if (help && help[0]) 63 m_cmd_help_short = help; 64 if (syntax && syntax[0]) 65 m_cmd_syntax = syntax; 66 } 67 68 CommandObject::~CommandObject () 69 { 70 } 71 72 const char * 73 CommandObject::GetHelp () 74 { 75 return m_cmd_help_short.c_str(); 76 } 77 78 const char * 79 CommandObject::GetHelpLong () 80 { 81 return m_cmd_help_long.c_str(); 82 } 83 84 const char * 85 CommandObject::GetSyntax () 86 { 87 if (m_cmd_syntax.length() == 0) 88 { 89 StreamString syntax_str; 90 syntax_str.Printf ("%s", GetCommandName()); 91 if (!IsDashDashCommand() && GetOptions() != nullptr) 92 syntax_str.Printf (" <cmd-options>"); 93 if (m_arguments.size() > 0) 94 { 95 syntax_str.Printf (" "); 96 if (!IsDashDashCommand() && WantsRawCommandString() && GetOptions() && GetOptions()->NumCommandOptions()) 97 syntax_str.Printf("-- "); 98 GetFormattedCommandArguments (syntax_str); 99 } 100 m_cmd_syntax = syntax_str.GetData (); 101 } 102 103 return m_cmd_syntax.c_str(); 104 } 105 106 const char * 107 CommandObject::GetCommandName () 108 { 109 return m_cmd_name.c_str(); 110 } 111 112 void 113 CommandObject::SetCommandName (const char *name) 114 { 115 m_cmd_name = name; 116 } 117 118 void 119 CommandObject::SetHelp (const char *cstr) 120 { 121 if (cstr) 122 m_cmd_help_short = cstr; 123 else 124 m_cmd_help_short.assign(""); 125 } 126 127 void 128 CommandObject::SetHelpLong (const char *cstr) 129 { 130 if (cstr) 131 m_cmd_help_long = cstr; 132 else 133 m_cmd_help_long.assign(""); 134 } 135 136 void 137 CommandObject::SetSyntax (const char *cstr) 138 { 139 m_cmd_syntax = cstr; 140 } 141 142 Options * 143 CommandObject::GetOptions () 144 { 145 // By default commands don't have options unless this virtual function 146 // is overridden by base classes. 147 return nullptr; 148 } 149 150 bool 151 CommandObject::ParseOptions 152 ( 153 Args& args, 154 CommandReturnObject &result 155 ) 156 { 157 // See if the subclass has options? 158 Options *options = GetOptions(); 159 if (options != nullptr) 160 { 161 Error error; 162 163 auto exe_ctx = GetCommandInterpreter().GetExecutionContext(); 164 options->NotifyOptionParsingStarting(&exe_ctx); 165 166 // ParseOptions calls getopt_long_only, which always skips the zero'th item in the array and starts at position 1, 167 // so we need to push a dummy value into position zero. 168 args.Unshift("dummy_string"); 169 const bool require_validation = true; 170 error = args.ParseOptions(*options, &exe_ctx, 171 GetCommandInterpreter().GetPlatform(true), 172 require_validation); 173 174 // The "dummy_string" will have already been removed by ParseOptions, 175 // so no need to remove it. 176 177 if (error.Success()) 178 error = options->NotifyOptionParsingFinished(&exe_ctx); 179 180 if (error.Success()) 181 { 182 if (options->VerifyOptions (result)) 183 return true; 184 } 185 else 186 { 187 const char *error_cstr = error.AsCString(); 188 if (error_cstr) 189 { 190 // We got an error string, lets use that 191 result.AppendError(error_cstr); 192 } 193 else 194 { 195 // No error string, output the usage information into result 196 options->GenerateOptionUsage(result.GetErrorStream(), this, 197 GetCommandInterpreter() 198 .GetDebugger() 199 .GetTerminalWidth()); 200 } 201 } 202 result.SetStatus (eReturnStatusFailed); 203 return false; 204 } 205 return true; 206 } 207 208 209 210 bool 211 CommandObject::CheckRequirements (CommandReturnObject &result) 212 { 213 #ifdef LLDB_CONFIGURATION_DEBUG 214 // Nothing should be stored in m_exe_ctx between running commands as m_exe_ctx 215 // has shared pointers to the target, process, thread and frame and we don't 216 // want any CommandObject instances to keep any of these objects around 217 // longer than for a single command. Every command should call 218 // CommandObject::Cleanup() after it has completed 219 assert (m_exe_ctx.GetTargetPtr() == NULL); 220 assert (m_exe_ctx.GetProcessPtr() == NULL); 221 assert (m_exe_ctx.GetThreadPtr() == NULL); 222 assert (m_exe_ctx.GetFramePtr() == NULL); 223 #endif 224 225 // Lock down the interpreter's execution context prior to running the 226 // command so we guarantee the selected target, process, thread and frame 227 // can't go away during the execution 228 m_exe_ctx = m_interpreter.GetExecutionContext(); 229 230 const uint32_t flags = GetFlags().Get(); 231 if (flags & (eCommandRequiresTarget | 232 eCommandRequiresProcess | 233 eCommandRequiresThread | 234 eCommandRequiresFrame | 235 eCommandTryTargetAPILock )) 236 { 237 238 if ((flags & eCommandRequiresTarget) && !m_exe_ctx.HasTargetScope()) 239 { 240 result.AppendError (GetInvalidTargetDescription()); 241 return false; 242 } 243 244 if ((flags & eCommandRequiresProcess) && !m_exe_ctx.HasProcessScope()) 245 { 246 if (!m_exe_ctx.HasTargetScope()) 247 result.AppendError (GetInvalidTargetDescription()); 248 else 249 result.AppendError (GetInvalidProcessDescription()); 250 return false; 251 } 252 253 if ((flags & eCommandRequiresThread) && !m_exe_ctx.HasThreadScope()) 254 { 255 if (!m_exe_ctx.HasTargetScope()) 256 result.AppendError (GetInvalidTargetDescription()); 257 else if (!m_exe_ctx.HasProcessScope()) 258 result.AppendError (GetInvalidProcessDescription()); 259 else 260 result.AppendError (GetInvalidThreadDescription()); 261 return false; 262 } 263 264 if ((flags & eCommandRequiresFrame) && !m_exe_ctx.HasFrameScope()) 265 { 266 if (!m_exe_ctx.HasTargetScope()) 267 result.AppendError (GetInvalidTargetDescription()); 268 else if (!m_exe_ctx.HasProcessScope()) 269 result.AppendError (GetInvalidProcessDescription()); 270 else if (!m_exe_ctx.HasThreadScope()) 271 result.AppendError (GetInvalidThreadDescription()); 272 else 273 result.AppendError (GetInvalidFrameDescription()); 274 return false; 275 } 276 277 if ((flags & eCommandRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr)) 278 { 279 result.AppendError (GetInvalidRegContextDescription()); 280 return false; 281 } 282 283 if (flags & eCommandTryTargetAPILock) 284 { 285 Target *target = m_exe_ctx.GetTargetPtr(); 286 if (target) 287 m_api_locker = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex()); 288 } 289 } 290 291 if (GetFlags().AnySet (eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)) 292 { 293 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr(); 294 if (process == nullptr) 295 { 296 // A process that is not running is considered paused. 297 if (GetFlags().Test(eCommandProcessMustBeLaunched)) 298 { 299 result.AppendError ("Process must exist."); 300 result.SetStatus (eReturnStatusFailed); 301 return false; 302 } 303 } 304 else 305 { 306 StateType state = process->GetState(); 307 switch (state) 308 { 309 case eStateInvalid: 310 case eStateSuspended: 311 case eStateCrashed: 312 case eStateStopped: 313 break; 314 315 case eStateConnected: 316 case eStateAttaching: 317 case eStateLaunching: 318 case eStateDetached: 319 case eStateExited: 320 case eStateUnloaded: 321 if (GetFlags().Test(eCommandProcessMustBeLaunched)) 322 { 323 result.AppendError ("Process must be launched."); 324 result.SetStatus (eReturnStatusFailed); 325 return false; 326 } 327 break; 328 329 case eStateRunning: 330 case eStateStepping: 331 if (GetFlags().Test(eCommandProcessMustBePaused)) 332 { 333 result.AppendError ("Process is running. Use 'process interrupt' to pause execution."); 334 result.SetStatus (eReturnStatusFailed); 335 return false; 336 } 337 } 338 } 339 } 340 return true; 341 } 342 343 void 344 CommandObject::Cleanup () 345 { 346 m_exe_ctx.Clear(); 347 if (m_api_locker.owns_lock()) 348 m_api_locker.unlock(); 349 } 350 351 int 352 CommandObject::HandleCompletion 353 ( 354 Args &input, 355 int &cursor_index, 356 int &cursor_char_position, 357 int match_start_point, 358 int max_return_elements, 359 bool &word_complete, 360 StringList &matches 361 ) 362 { 363 // Default implementation of WantsCompletion() is !WantsRawCommandString(). 364 // Subclasses who want raw command string but desire, for example, 365 // argument completion should override WantsCompletion() to return true, 366 // instead. 367 if (WantsRawCommandString() && !WantsCompletion()) 368 { 369 // FIXME: Abstract telling the completion to insert the completion character. 370 matches.Clear(); 371 return -1; 372 } 373 else 374 { 375 // Can we do anything generic with the options? 376 Options *cur_options = GetOptions(); 377 CommandReturnObject result; 378 OptionElementVector opt_element_vector; 379 380 if (cur_options != nullptr) 381 { 382 // Re-insert the dummy command name string which will have been 383 // stripped off: 384 input.Unshift ("dummy-string"); 385 cursor_index++; 386 387 388 // I stick an element on the end of the input, because if the last element is 389 // option that requires an argument, getopt_long_only will freak out. 390 391 input.AppendArgument ("<FAKE-VALUE>"); 392 393 input.ParseArgsForCompletion (*cur_options, opt_element_vector, cursor_index); 394 395 input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1); 396 397 bool handled_by_options; 398 handled_by_options = cur_options->HandleOptionCompletion (input, 399 opt_element_vector, 400 cursor_index, 401 cursor_char_position, 402 match_start_point, 403 max_return_elements, 404 GetCommandInterpreter(), 405 word_complete, 406 matches); 407 if (handled_by_options) 408 return matches.GetSize(); 409 } 410 411 // If we got here, the last word is not an option or an option argument. 412 return HandleArgumentCompletion (input, 413 cursor_index, 414 cursor_char_position, 415 opt_element_vector, 416 match_start_point, 417 max_return_elements, 418 word_complete, 419 matches); 420 } 421 } 422 423 bool 424 CommandObject::HelpTextContainsWord (const char *search_word, 425 bool search_short_help, 426 bool search_long_help, 427 bool search_syntax, 428 bool search_options) 429 { 430 std::string options_usage_help; 431 432 bool found_word = false; 433 434 const char *short_help = GetHelp(); 435 const char *long_help = GetHelpLong(); 436 const char *syntax_help = GetSyntax(); 437 438 if (search_short_help && short_help && strcasestr (short_help, search_word)) 439 found_word = true; 440 else if (search_long_help && long_help && strcasestr (long_help, search_word)) 441 found_word = true; 442 else if (search_syntax && syntax_help && strcasestr (syntax_help, search_word)) 443 found_word = true; 444 445 if (!found_word 446 && search_options 447 && GetOptions() != nullptr) 448 { 449 StreamString usage_help; 450 GetOptions()->GenerateOptionUsage(usage_help, this, 451 GetCommandInterpreter() 452 .GetDebugger().GetTerminalWidth()); 453 if (usage_help.GetSize() > 0) 454 { 455 const char *usage_text = usage_help.GetData(); 456 if (strcasestr (usage_text, search_word)) 457 found_word = true; 458 } 459 } 460 461 return found_word; 462 } 463 464 int 465 CommandObject::GetNumArgumentEntries () 466 { 467 return m_arguments.size(); 468 } 469 470 CommandObject::CommandArgumentEntry * 471 CommandObject::GetArgumentEntryAtIndex (int idx) 472 { 473 if (static_cast<size_t>(idx) < m_arguments.size()) 474 return &(m_arguments[idx]); 475 476 return nullptr; 477 } 478 479 const CommandObject::ArgumentTableEntry * 480 CommandObject::FindArgumentDataByType (CommandArgumentType arg_type) 481 { 482 const ArgumentTableEntry *table = CommandObject::GetArgumentTable(); 483 484 for (int i = 0; i < eArgTypeLastArg; ++i) 485 if (table[i].arg_type == arg_type) 486 return &(table[i]); 487 488 return nullptr; 489 } 490 491 void 492 CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter) 493 { 494 const ArgumentTableEntry* table = CommandObject::GetArgumentTable(); 495 const ArgumentTableEntry *entry = &(table[arg_type]); 496 497 // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up... 498 499 if (entry->arg_type != arg_type) 500 entry = CommandObject::FindArgumentDataByType (arg_type); 501 502 if (!entry) 503 return; 504 505 StreamString name_str; 506 name_str.Printf ("<%s>", entry->arg_name); 507 508 if (entry->help_function) 509 { 510 const char* help_text = entry->help_function(); 511 if (!entry->help_function.self_formatting) 512 { 513 interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", help_text, 514 name_str.GetSize()); 515 } 516 else 517 { 518 interpreter.OutputHelpText(str, name_str.GetData(), "--", help_text, 519 name_str.GetSize()); 520 } 521 } 522 else 523 interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", entry->help_text, name_str.GetSize()); 524 } 525 526 const char * 527 CommandObject::GetArgumentName (CommandArgumentType arg_type) 528 { 529 const ArgumentTableEntry *entry = &(CommandObject::GetArgumentTable()[arg_type]); 530 531 // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up... 532 533 if (entry->arg_type != arg_type) 534 entry = CommandObject::FindArgumentDataByType (arg_type); 535 536 if (entry) 537 return entry->arg_name; 538 539 StreamString str; 540 str << "Arg name for type (" << arg_type << ") not in arg table!"; 541 return str.GetData(); 542 } 543 544 bool 545 CommandObject::IsPairType (ArgumentRepetitionType arg_repeat_type) 546 { 547 if ((arg_repeat_type == eArgRepeatPairPlain) 548 || (arg_repeat_type == eArgRepeatPairOptional) 549 || (arg_repeat_type == eArgRepeatPairPlus) 550 || (arg_repeat_type == eArgRepeatPairStar) 551 || (arg_repeat_type == eArgRepeatPairRange) 552 || (arg_repeat_type == eArgRepeatPairRangeOptional)) 553 return true; 554 555 return false; 556 } 557 558 static CommandObject::CommandArgumentEntry 559 OptSetFiltered(uint32_t opt_set_mask, CommandObject::CommandArgumentEntry &cmd_arg_entry) 560 { 561 CommandObject::CommandArgumentEntry ret_val; 562 for (unsigned i = 0; i < cmd_arg_entry.size(); ++i) 563 if (opt_set_mask & cmd_arg_entry[i].arg_opt_set_association) 564 ret_val.push_back(cmd_arg_entry[i]); 565 return ret_val; 566 } 567 568 // Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means take 569 // all the argument data into account. On rare cases where some argument sticks 570 // with certain option sets, this function returns the option set filtered args. 571 void 572 CommandObject::GetFormattedCommandArguments (Stream &str, uint32_t opt_set_mask) 573 { 574 int num_args = m_arguments.size(); 575 for (int i = 0; i < num_args; ++i) 576 { 577 if (i > 0) 578 str.Printf (" "); 579 CommandArgumentEntry arg_entry = 580 opt_set_mask == LLDB_OPT_SET_ALL ? m_arguments[i] 581 : OptSetFiltered(opt_set_mask, m_arguments[i]); 582 int num_alternatives = arg_entry.size(); 583 584 if ((num_alternatives == 2) 585 && IsPairType (arg_entry[0].arg_repetition)) 586 { 587 const char *first_name = GetArgumentName (arg_entry[0].arg_type); 588 const char *second_name = GetArgumentName (arg_entry[1].arg_type); 589 switch (arg_entry[0].arg_repetition) 590 { 591 case eArgRepeatPairPlain: 592 str.Printf ("<%s> <%s>", first_name, second_name); 593 break; 594 case eArgRepeatPairOptional: 595 str.Printf ("[<%s> <%s>]", first_name, second_name); 596 break; 597 case eArgRepeatPairPlus: 598 str.Printf ("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, first_name, second_name); 599 break; 600 case eArgRepeatPairStar: 601 str.Printf ("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, first_name, second_name); 602 break; 603 case eArgRepeatPairRange: 604 str.Printf ("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, first_name, second_name); 605 break; 606 case eArgRepeatPairRangeOptional: 607 str.Printf ("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, first_name, second_name); 608 break; 609 // Explicitly test for all the rest of the cases, so if new types get added we will notice the 610 // missing case statement(s). 611 case eArgRepeatPlain: 612 case eArgRepeatOptional: 613 case eArgRepeatPlus: 614 case eArgRepeatStar: 615 case eArgRepeatRange: 616 // These should not be reached, as they should fail the IsPairType test above. 617 break; 618 } 619 } 620 else 621 { 622 StreamString names; 623 for (int j = 0; j < num_alternatives; ++j) 624 { 625 if (j > 0) 626 names.Printf (" | "); 627 names.Printf ("%s", GetArgumentName (arg_entry[j].arg_type)); 628 } 629 switch (arg_entry[0].arg_repetition) 630 { 631 case eArgRepeatPlain: 632 str.Printf ("<%s>", names.GetData()); 633 break; 634 case eArgRepeatPlus: 635 str.Printf ("<%s> [<%s> [...]]", names.GetData(), names.GetData()); 636 break; 637 case eArgRepeatStar: 638 str.Printf ("[<%s> [<%s> [...]]]", names.GetData(), names.GetData()); 639 break; 640 case eArgRepeatOptional: 641 str.Printf ("[<%s>]", names.GetData()); 642 break; 643 case eArgRepeatRange: 644 str.Printf ("<%s_1> .. <%s_n>", names.GetData(), names.GetData()); 645 break; 646 // Explicitly test for all the rest of the cases, so if new types get added we will notice the 647 // missing case statement(s). 648 case eArgRepeatPairPlain: 649 case eArgRepeatPairOptional: 650 case eArgRepeatPairPlus: 651 case eArgRepeatPairStar: 652 case eArgRepeatPairRange: 653 case eArgRepeatPairRangeOptional: 654 // These should not be hit, as they should pass the IsPairType test above, and control should 655 // have gone into the other branch of the if statement. 656 break; 657 } 658 } 659 } 660 } 661 662 CommandArgumentType 663 CommandObject::LookupArgumentName (const char *arg_name) 664 { 665 CommandArgumentType return_type = eArgTypeLastArg; 666 667 std::string arg_name_str (arg_name); 668 size_t len = arg_name_str.length(); 669 if (arg_name[0] == '<' 670 && arg_name[len-1] == '>') 671 arg_name_str = arg_name_str.substr (1, len-2); 672 673 const ArgumentTableEntry *table = GetArgumentTable(); 674 for (int i = 0; i < eArgTypeLastArg; ++i) 675 if (arg_name_str.compare (table[i].arg_name) == 0) 676 return_type = g_arguments_data[i].arg_type; 677 678 return return_type; 679 } 680 681 static const char * 682 RegisterNameHelpTextCallback () 683 { 684 return "Register names can be specified using the architecture specific names. " 685 "They can also be specified using generic names. Not all generic entities have " 686 "registers backing them on all architectures. When they don't the generic name " 687 "will return an error.\n" 688 "The generic names defined in lldb are:\n" 689 "\n" 690 "pc - program counter register\n" 691 "ra - return address register\n" 692 "fp - frame pointer register\n" 693 "sp - stack pointer register\n" 694 "flags - the flags register\n" 695 "arg{1-6} - integer argument passing registers.\n"; 696 } 697 698 static const char * 699 BreakpointIDHelpTextCallback () 700 { 701 return "Breakpoints are identified using major and minor numbers; the major " 702 "number corresponds to the single entity that was created with a 'breakpoint " 703 "set' command; the minor numbers correspond to all the locations that were " 704 "actually found/set based on the major breakpoint. A full breakpoint ID might " 705 "look like 3.14, meaning the 14th location set for the 3rd breakpoint. You " 706 "can specify all the locations of a breakpoint by just indicating the major " 707 "breakpoint number. A valid breakpoint ID consists either of just the major " 708 "number, or the major number followed by a dot and the location number (e.g. " 709 "3 or 3.2 could both be valid breakpoint IDs.)"; 710 } 711 712 static const char * 713 BreakpointIDRangeHelpTextCallback () 714 { 715 return "A 'breakpoint ID list' is a manner of specifying multiple breakpoints. " 716 "This can be done through several mechanisms. The easiest way is to just " 717 "enter a space-separated list of breakpoint IDs. To specify all the " 718 "breakpoint locations under a major breakpoint, you can use the major " 719 "breakpoint number followed by '.*', eg. '5.*' means all the locations under " 720 "breakpoint 5. You can also indicate a range of breakpoints by using " 721 "<start-bp-id> - <end-bp-id>. The start-bp-id and end-bp-id for a range can " 722 "be any valid breakpoint IDs. It is not legal, however, to specify a range " 723 "using specific locations that cross major breakpoint numbers. I.e. 3.2 - 3.7" 724 " is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal."; 725 } 726 727 static const char * 728 BreakpointNameHelpTextCallback () 729 { 730 return "A name that can be added to a breakpoint when it is created, or later " 731 "on with the \"breakpoint name add\" command. " 732 "Breakpoint names can be used to specify breakpoints in all the places breakpoint IDs " 733 "and breakpoint ID ranges can be used. As such they provide a convenient way to group breakpoints, " 734 "and to operate on breakpoints you create without having to track the breakpoint number. " 735 "Note, the attributes you set when using a breakpoint name in a breakpoint command don't " 736 "adhere to the name, but instead are set individually on all the breakpoints currently tagged with that " 737 "name. Future breakpoints " 738 "tagged with that name will not pick up the attributes previously given using that name. " 739 "In order to distinguish breakpoint names from breakpoint IDs and ranges, " 740 "names must start with a letter from a-z or A-Z and cannot contain spaces, \".\" or \"-\". " 741 "Also, breakpoint names can only be applied to breakpoints, not to breakpoint locations."; 742 } 743 744 static const char * 745 GDBFormatHelpTextCallback () 746 { 747 return "A GDB format consists of a repeat count, a format letter and a size letter. " 748 "The repeat count is optional and defaults to 1. The format letter is optional " 749 "and defaults to the previous format that was used. The size letter is optional " 750 "and defaults to the previous size that was used.\n" 751 "\n" 752 "Format letters include:\n" 753 "o - octal\n" 754 "x - hexadecimal\n" 755 "d - decimal\n" 756 "u - unsigned decimal\n" 757 "t - binary\n" 758 "f - float\n" 759 "a - address\n" 760 "i - instruction\n" 761 "c - char\n" 762 "s - string\n" 763 "T - OSType\n" 764 "A - float as hex\n" 765 "\n" 766 "Size letters include:\n" 767 "b - 1 byte (byte)\n" 768 "h - 2 bytes (halfword)\n" 769 "w - 4 bytes (word)\n" 770 "g - 8 bytes (giant)\n" 771 "\n" 772 "Example formats:\n" 773 "32xb - show 32 1 byte hexadecimal integer values\n" 774 "16xh - show 16 2 byte hexadecimal integer values\n" 775 "64 - show 64 2 byte hexadecimal integer values (format and size from the last format)\n" 776 "dw - show 1 4 byte decimal integer value\n" 777 ; 778 } 779 780 static const char * 781 FormatHelpTextCallback () 782 { 783 784 static char* help_text_ptr = nullptr; 785 786 if (help_text_ptr) 787 return help_text_ptr; 788 789 StreamString sstr; 790 sstr << "One of the format names (or one-character names) that can be used to show a variable's value:\n"; 791 for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1)) 792 { 793 if (f != eFormatDefault) 794 sstr.PutChar('\n'); 795 796 char format_char = FormatManager::GetFormatAsFormatChar(f); 797 if (format_char) 798 sstr.Printf("'%c' or ", format_char); 799 800 sstr.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f)); 801 } 802 803 sstr.Flush(); 804 805 std::string data = sstr.GetString(); 806 807 help_text_ptr = new char[data.length()+1]; 808 809 data.copy(help_text_ptr, data.length()); 810 811 return help_text_ptr; 812 } 813 814 static const char * 815 LanguageTypeHelpTextCallback () 816 { 817 static char* help_text_ptr = nullptr; 818 819 if (help_text_ptr) 820 return help_text_ptr; 821 822 StreamString sstr; 823 sstr << "One of the following languages:\n"; 824 825 Language::PrintAllLanguages(sstr, " ", "\n"); 826 827 sstr.Flush(); 828 829 std::string data = sstr.GetString(); 830 831 help_text_ptr = new char[data.length()+1]; 832 833 data.copy(help_text_ptr, data.length()); 834 835 return help_text_ptr; 836 } 837 838 static const char * 839 SummaryStringHelpTextCallback() 840 { 841 return 842 "A summary string is a way to extract information from variables in order to present them using a summary.\n" 843 "Summary strings contain static text, variables, scopes and control sequences:\n" 844 " - Static text can be any sequence of non-special characters, i.e. anything but '{', '}', '$', or '\\'.\n" 845 " - Variables are sequences of characters beginning with ${, ending with } and that contain symbols in the format described below.\n" 846 " - Scopes are any sequence of text between { and }. Anything included in a scope will only appear in the output summary if there were no errors.\n" 847 " - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus '\\$', '\\{' and '\\}'.\n" 848 "A summary string works by copying static text verbatim, turning control sequences into their character counterpart, expanding variables and trying to expand scopes.\n" 849 "A variable is expanded by giving it a value other than its textual representation, and the way this is done depends on what comes after the ${ marker.\n" 850 "The most common sequence if ${var followed by an expression path, which is the text one would type to access a member of an aggregate types, given a variable of that type" 851 " (e.g. if type T has a member named x, which has a member named y, and if t is of type T, the expression path would be .x.y and the way to fit that into a summary string would be" 852 " ${var.x.y}). You can also use ${*var followed by an expression path and in that case the object referred by the path will be dereferenced before being displayed." 853 " If the object is not a pointer, doing so will cause an error. For additional details on expression paths, you can type 'help expr-path'. \n" 854 "By default, summary strings attempt to display the summary for any variable they reference, and if that fails the value. If neither can be shown, nothing is displayed." 855 "In a summary string, you can also use an array index [n], or a slice-like range [n-m]. This can have two different meanings depending on what kind of object the expression" 856 " path refers to:\n" 857 " - if it is a scalar type (any basic type like int, float, ...) the expression is a bitfield, i.e. the bits indicated by the indexing operator are extracted out of the number" 858 " and displayed as an individual variable\n" 859 " - if it is an array or pointer the array items indicated by the indexing operator are shown as the result of the variable. if the expression is an array, real array items are" 860 " printed; if it is a pointer, the pointer-as-array syntax is used to obtain the values (this means, the latter case can have no range checking)\n" 861 "If you are trying to display an array for which the size is known, you can also use [] instead of giving an exact range. This has the effect of showing items 0 thru size - 1.\n" 862 "Additionally, a variable can contain an (optional) format code, as in ${var.x.y%code}, where code can be any of the valid formats described in 'help format', or one of the" 863 " special symbols only allowed as part of a variable:\n" 864 " %V: show the value of the object by default\n" 865 " %S: show the summary of the object by default\n" 866 " %@: show the runtime-provided object description (for Objective-C, it calls NSPrintForDebugger; for C/C++ it does nothing)\n" 867 " %L: show the location of the object (memory address or a register name)\n" 868 " %#: show the number of children of the object\n" 869 " %T: show the type of the object\n" 870 "Another variable that you can use in summary strings is ${svar . This sequence works exactly like ${var, including the fact that ${*svar is an allowed sequence, but uses" 871 " the object's synthetic children provider instead of the actual objects. For instance, if you are using STL synthetic children providers, the following summary string would" 872 " count the number of actual elements stored in an std::list:\n" 873 "type summary add -s \"${svar%#}\" -x \"std::list<\""; 874 } 875 876 static const char * 877 ExprPathHelpTextCallback() 878 { 879 return 880 "An expression path is the sequence of symbols that is used in C/C++ to access a member variable of an aggregate object (class).\n" 881 "For instance, given a class:\n" 882 " class foo {\n" 883 " int a;\n" 884 " int b; .\n" 885 " foo* next;\n" 886 " };\n" 887 "the expression to read item b in the item pointed to by next for foo aFoo would be aFoo.next->b.\n" 888 "Given that aFoo could just be any object of type foo, the string '.next->b' is the expression path, because it can be attached to any foo instance to achieve the effect.\n" 889 "Expression paths in LLDB include dot (.) and arrow (->) operators, and most commands using expression paths have ways to also accept the star (*) operator.\n" 890 "The meaning of these operators is the same as the usual one given to them by the C/C++ standards.\n" 891 "LLDB also has support for indexing ([ ]) in expression paths, and extends the traditional meaning of the square brackets operator to allow bitfield extraction:\n" 892 "for objects of native types (int, float, char, ...) saying '[n-m]' as an expression path (where n and m are any positive integers, e.g. [3-5]) causes LLDB to extract" 893 " bits n thru m from the value of the variable. If n == m, [n] is also allowed as a shortcut syntax. For arrays and pointers, expression paths can only contain one index" 894 " and the meaning of the operation is the same as the one defined by C/C++ (item extraction). Some commands extend bitfield-like syntax for arrays and pointers with the" 895 " meaning of array slicing (taking elements n thru m inside the array or pointed-to memory)."; 896 } 897 898 void 899 CommandObject::FormatLongHelpText (Stream &output_strm, const char *long_help) 900 { 901 CommandInterpreter& interpreter = GetCommandInterpreter(); 902 std::stringstream lineStream (long_help); 903 std::string line; 904 while (std::getline (lineStream, line)) { 905 if (line.empty()) { 906 output_strm << "\n"; 907 continue; 908 } 909 size_t result = line.find_first_not_of (" \t"); 910 if (result == std::string::npos) { 911 result = 0; 912 } 913 std::string whitespace_prefix = line.substr (0, result); 914 std::string remainder = line.substr (result); 915 interpreter.OutputFormattedHelpText(output_strm, whitespace_prefix.c_str(), remainder.c_str()); 916 } 917 } 918 919 void 920 CommandObject::GenerateHelpText (CommandReturnObject &result) 921 { 922 GenerateHelpText(result.GetOutputStream()); 923 924 result.SetStatus (eReturnStatusSuccessFinishNoResult); 925 } 926 927 void 928 CommandObject::GenerateHelpText (Stream &output_strm) 929 { 930 CommandInterpreter& interpreter = GetCommandInterpreter(); 931 if (WantsRawCommandString()) 932 { 933 std::string help_text(GetHelp()); 934 help_text.append(" Expects 'raw' input (see 'help raw-input'.)"); 935 interpreter.OutputFormattedHelpText(output_strm, "", "", help_text.c_str(), 1); 936 } 937 else 938 interpreter.OutputFormattedHelpText(output_strm, "", "", GetHelp(), 1); 939 output_strm.Printf("\nSyntax: %s\n", GetSyntax()); 940 Options *options = GetOptions(); 941 if (options != nullptr) 942 { 943 options->GenerateOptionUsage(output_strm, this, 944 GetCommandInterpreter() 945 .GetDebugger().GetTerminalWidth()); 946 } 947 const char *long_help = GetHelpLong(); 948 if ((long_help != nullptr) && (strlen(long_help) > 0)) 949 { 950 FormatLongHelpText(output_strm, long_help); 951 } 952 if (!IsDashDashCommand() && options && options->NumCommandOptions() > 0) 953 { 954 if (WantsRawCommandString() && !WantsCompletion()) 955 { 956 // Emit the message about using ' -- ' between the end of the command options and the raw input 957 // conditionally, i.e., only if the command object does not want completion. 958 interpreter.OutputFormattedHelpText( 959 output_strm, "", "", 960 "\nImportant Note: Because this command takes 'raw' input, if you use any command options" 961 " you must use ' -- ' between the end of the command options and the beginning of the raw input.", 962 1); 963 } 964 else if (GetNumArgumentEntries() > 0) 965 { 966 // Also emit a warning about using "--" in case you are using a command that takes options and arguments. 967 interpreter.OutputFormattedHelpText( 968 output_strm, "", "", "\nThis command takes options and free-form arguments. If your arguments resemble" 969 " option specifiers (i.e., they start with a - or --), you must use ' -- ' between" 970 " the end of the command options and the beginning of the arguments.", 971 1); 972 } 973 } 974 } 975 976 void 977 CommandObject::AddIDsArgumentData(CommandArgumentEntry &arg, CommandArgumentType ID, CommandArgumentType IDRange) 978 { 979 CommandArgumentData id_arg; 980 CommandArgumentData id_range_arg; 981 982 // Create the first variant for the first (and only) argument for this command. 983 id_arg.arg_type = ID; 984 id_arg.arg_repetition = eArgRepeatOptional; 985 986 // Create the second variant for the first (and only) argument for this command. 987 id_range_arg.arg_type = IDRange; 988 id_range_arg.arg_repetition = eArgRepeatOptional; 989 990 // The first (and only) argument for this command could be either an id or an id_range. 991 // Push both variants into the entry for the first argument for this command. 992 arg.push_back(id_arg); 993 arg.push_back(id_range_arg); 994 } 995 996 const char * 997 CommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type) 998 { 999 assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentTypeAsCString"); 1000 return g_arguments_data[arg_type].arg_name; 1001 } 1002 1003 const char * 1004 CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type) 1005 { 1006 assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentDescriptionAsCString"); 1007 return g_arguments_data[arg_type].help_text; 1008 } 1009 1010 Target * 1011 CommandObject::GetDummyTarget() 1012 { 1013 return m_interpreter.GetDebugger().GetDummyTarget(); 1014 } 1015 1016 Target * 1017 CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy) 1018 { 1019 return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy); 1020 } 1021 1022 Thread * 1023 CommandObject::GetDefaultThread() 1024 { 1025 Thread *thread_to_use = m_exe_ctx.GetThreadPtr(); 1026 if (thread_to_use) 1027 return thread_to_use; 1028 1029 Process *process = m_exe_ctx.GetProcessPtr(); 1030 if (!process) 1031 { 1032 Target *target = m_exe_ctx.GetTargetPtr(); 1033 if (!target) 1034 { 1035 target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1036 } 1037 if (target) 1038 process = target->GetProcessSP().get(); 1039 } 1040 1041 if (process) 1042 return process->GetThreadList().GetSelectedThread().get(); 1043 else 1044 return nullptr; 1045 } 1046 1047 bool 1048 CommandObjectParsed::Execute (const char *args_string, CommandReturnObject &result) 1049 { 1050 bool handled = false; 1051 Args cmd_args (args_string); 1052 if (HasOverrideCallback()) 1053 { 1054 Args full_args (GetCommandName ()); 1055 full_args.AppendArguments(cmd_args); 1056 handled = InvokeOverrideCallback (full_args.GetConstArgumentVector(), result); 1057 } 1058 if (!handled) 1059 { 1060 for (size_t i = 0; i < cmd_args.GetArgumentCount(); ++i) 1061 { 1062 const char *tmp_str = cmd_args.GetArgumentAtIndex (i); 1063 if (tmp_str[0] == '`') // back-quote 1064 cmd_args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str)); 1065 } 1066 1067 if (CheckRequirements(result)) 1068 { 1069 if (ParseOptions (cmd_args, result)) 1070 { 1071 // Call the command-specific version of 'Execute', passing it the already processed arguments. 1072 handled = DoExecute (cmd_args, result); 1073 } 1074 } 1075 1076 Cleanup(); 1077 } 1078 return handled; 1079 } 1080 1081 bool 1082 CommandObjectRaw::Execute (const char *args_string, CommandReturnObject &result) 1083 { 1084 bool handled = false; 1085 if (HasOverrideCallback()) 1086 { 1087 std::string full_command (GetCommandName ()); 1088 full_command += ' '; 1089 full_command += args_string; 1090 const char *argv[2] = { nullptr, nullptr }; 1091 argv[0] = full_command.c_str(); 1092 handled = InvokeOverrideCallback (argv, result); 1093 } 1094 if (!handled) 1095 { 1096 if (CheckRequirements(result)) 1097 handled = DoExecute (args_string, result); 1098 1099 Cleanup(); 1100 } 1101 return handled; 1102 } 1103 1104 static 1105 const char *arch_helper() 1106 { 1107 static StreamString g_archs_help; 1108 if (g_archs_help.Empty()) 1109 { 1110 StringList archs; 1111 ArchSpec::AutoComplete(nullptr, archs); 1112 g_archs_help.Printf("These are the supported architecture names:\n"); 1113 archs.Join("\n", g_archs_help); 1114 } 1115 return g_archs_help.GetData(); 1116 } 1117 1118 CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = { 1119 // clang-format off 1120 { eArgTypeAddress, "address", CommandCompletions::eNoCompletion, { nullptr, false }, "A valid address in the target program's execution space." }, 1121 { eArgTypeAddressOrExpression, "address-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "An expression that resolves to an address." }, 1122 { eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of an abbreviation (alias) for a debugger command." }, 1123 { eArgTypeAliasOptions, "options-for-aliased-command", CommandCompletions::eNoCompletion, { nullptr, false }, "Command options to be used as part of an alias (abbreviation) definition. (See 'help commands alias' for more information.)" }, 1124 { eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, { arch_helper, true }, "The architecture name, e.g. i386 or x86_64." }, 1125 { eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, { nullptr, false }, "A Boolean value: 'true' or 'false'" }, 1126 { eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, { BreakpointIDHelpTextCallback, false }, nullptr }, 1127 { eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, { BreakpointIDRangeHelpTextCallback, false }, nullptr }, 1128 { eArgTypeBreakpointName, "breakpoint-name", CommandCompletions::eNoCompletion, { BreakpointNameHelpTextCallback, false }, nullptr }, 1129 { eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, { nullptr, false }, "Number of bytes to use." }, 1130 { eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, { nullptr, false }, "Then name of a class from the debug information in the program." }, 1131 { eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A debugger command (may be multiple words), without any options or arguments." }, 1132 { eArgTypeCount, "count", CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." }, 1133 { eArgTypeDirectoryName, "directory", CommandCompletions::eDiskDirectoryCompletion, { nullptr, false }, "A directory name." }, 1134 { eArgTypeDisassemblyFlavor, "disassembly-flavor", CommandCompletions::eNoCompletion, { nullptr, false }, "A disassembly flavor recognized by your disassembly plugin. Currently the only valid options are \"att\" and \"intel\" for Intel targets" }, 1135 { eArgTypeDescriptionVerbosity, "description-verbosity", CommandCompletions::eNoCompletion, { nullptr, false }, "How verbose the output of 'po' should be." }, 1136 { eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1137 { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1138 { eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, nullptr }, 1139 { eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, { nullptr, false }, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" }, 1140 { eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, { nullptr, false }, "The name of a file (can include path)." }, 1141 { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, { FormatHelpTextCallback, true }, nullptr }, 1142 { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, { nullptr, false }, "Index into a thread's list of frames." }, 1143 { eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1144 { eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function." }, 1145 { eArgTypeFunctionOrSymbol, "function-or-symbol", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function or symbol." }, 1146 { eArgTypeGDBFormat, "gdb-format", CommandCompletions::eNoCompletion, { GDBFormatHelpTextCallback, true }, nullptr }, 1147 { eArgTypeHelpText, "help-text", CommandCompletions::eNoCompletion, { nullptr, false }, "Text to be used as help for some other entity in LLDB" }, 1148 { eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a list." }, 1149 { eArgTypeLanguage, "source-language", CommandCompletions::eNoCompletion, { LanguageTypeHelpTextCallback, true }, nullptr }, 1150 { eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { nullptr, false }, "Line number in a source file." }, 1151 { eArgTypeLogCategory, "log-category", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a category within a log channel, e.g. all (try \"log list\" to see a list of all channels and their categories." }, 1152 { eArgTypeLogChannel, "log-channel", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a log channel, e.g. process.gdb-remote (try \"log list\" to see a list of all channels and their categories)." }, 1153 { eArgTypeMethod, "method", CommandCompletions::eNoCompletion, { nullptr, false }, "A C++ method name." }, 1154 { eArgTypeName, "name", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1155 { eArgTypeNewPathPrefix, "new-path-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1156 { eArgTypeNumLines, "num-lines", CommandCompletions::eNoCompletion, { nullptr, false }, "The number of lines to use." }, 1157 { eArgTypeNumberPerLine, "number-per-line", CommandCompletions::eNoCompletion, { nullptr, false }, "The number of items per line to display." }, 1158 { eArgTypeOffset, "offset", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1159 { eArgTypeOldPathPrefix, "old-path-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1160 { eArgTypeOneLiner, "one-line-command", CommandCompletions::eNoCompletion, { nullptr, false }, "A command that is entered as a single line of text." }, 1161 { eArgTypePath, "path", CommandCompletions::eDiskFileCompletion, { nullptr, false }, "Path." }, 1162 { eArgTypePermissionsNumber, "perms-numeric", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as an octal number (e.g. 755)." }, 1163 { eArgTypePermissionsString, "perms=string", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as a string value (e.g. rw-r-xr--)." }, 1164 { eArgTypePid, "pid", CommandCompletions::eNoCompletion, { nullptr, false }, "The process ID number." }, 1165 { eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1166 { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the process." }, 1167 { eArgTypePythonClass, "python-class", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python class." }, 1168 { eArgTypePythonFunction, "python-function", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python function." }, 1169 { eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { nullptr, false }, "Source code written in Python." }, 1170 { eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the thread queue." }, 1171 { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { RegisterNameHelpTextCallback, true }, nullptr }, 1172 { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "A regular expression." }, 1173 { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { nullptr, false }, "Arguments to be passed to the target program when it starts executing." }, 1174 { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1175 { eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", CommandCompletions::eNoCompletion, { nullptr, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." }, 1176 { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, { nullptr, false }, "The scripting language to be used for script-based commands. Currently only Python is valid." }, 1177 { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, { nullptr, false }, "Any word of interest for search purposes." }, 1178 { eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, { nullptr, false }, "An Objective-C selector name." }, 1179 { eArgTypeSettingIndex, "setting-index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a settings variable that is an array (try 'settings list' to see all the possible settings variables and their types)." }, 1180 { eArgTypeSettingKey, "setting-key", CommandCompletions::eNoCompletion, { nullptr, false }, "A key into a settings variables that is a dictionary (try 'settings list' to see all the possible settings variables and their types)." }, 1181 { eArgTypeSettingPrefix, "setting-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" }, 1182 { eArgTypeSettingVariableName, "setting-variable-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a settable internal debugger variable. Type 'settings list' to see a complete list of such variables." }, 1183 { eArgTypeShlibName, "shlib-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a shared library." }, 1184 { eArgTypeSourceFile, "source-file", CommandCompletions::eSourceFileCompletion, { nullptr, false }, "The name of a source file.." }, 1185 { eArgTypeSortOrder, "sort-order", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify a sort order when dumping lists." }, 1186 { eArgTypeStartAddress, "start-address", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1187 { eArgTypeSummaryString, "summary-string", CommandCompletions::eNoCompletion, { SummaryStringHelpTextCallback, true }, nullptr }, 1188 { eArgTypeSymbol, "symbol", CommandCompletions::eSymbolCompletion, { nullptr, false }, "Any symbol name (function name, variable, argument, etc.)" }, 1189 { eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Thread ID number." }, 1190 { eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, { nullptr, false }, "Index into the process' list of threads." }, 1191 { eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The thread's name." }, 1192 { eArgTypeTypeName, "type-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A type name." }, 1193 { eArgTypeUnsignedInteger, "unsigned-integer", CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." }, 1194 { eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, { nullptr, false }, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." }, 1195 { eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a variable in your program." }, 1196 { eArgTypeValue, "value", CommandCompletions::eNoCompletion, { nullptr, false }, "A value could be anything, depending on where and how it is used." }, 1197 { eArgTypeWidth, "width", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." }, 1198 { eArgTypeNone, "none", CommandCompletions::eNoCompletion, { nullptr, false }, "No help available for this." }, 1199 { eArgTypePlatform, "platform-name", CommandCompletions::ePlatformPluginCompletion, { nullptr, false }, "The name of an installed platform plug-in . Type 'platform list' to see a complete list of installed platforms." }, 1200 { eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Watchpoint IDs are positive integers." }, 1201 { eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." }, 1202 { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." }, 1203 { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." } 1204 // clang-format on 1205 }; 1206 1207 const CommandObject::ArgumentTableEntry* 1208 CommandObject::GetArgumentTable () 1209 { 1210 // If this assertion fires, then the table above is out of date with the CommandArgumentType enumeration 1211 assert ((sizeof (CommandObject::g_arguments_data) / sizeof (CommandObject::ArgumentTableEntry)) == eArgTypeLastArg); 1212 return CommandObject::g_arguments_data; 1213 } 1214 1215 1216