59#include "lldb/Host/Config.h"
60#if LLDB_ENABLE_LIBEDIT
83#include "llvm/ADT/STLExtras.h"
84#include "llvm/ADT/ScopeExit.h"
85#include "llvm/ADT/SmallString.h"
86#include "llvm/Support/FormatAdapters.h"
87#include "llvm/Support/Path.h"
88#include "llvm/Support/PrettyStackTrace.h"
89#include "llvm/Support/ScopedPrinter.h"
92#include <TargetConditionals.h>
101 "There is a .lldbinit file in the current directory which is not being "
103 "To silence this warning without sourcing in the local .lldbinit,\n"
104 "add the following to the lldbinit file in your home directory:\n"
105 " settings set target.load-cwd-lldbinit false\n"
106 "To allow lldb to source .lldbinit files in the current working "
108 "set the value of this variable to true. Only do so if you understand "
110 "accept the security risk.";
117#define LLDB_PROPERTIES_interpreter
118#include "InterpreterProperties.inc"
121#define LLDB_PROPERTIES_interpreter
122#include "InterpreterPropertiesEnum.inc"
126 static constexpr llvm::StringLiteral class_name(
"lldb.commandInterpreter");
131 bool synchronous_execution)
137 m_debugger(debugger), m_synchronous_execution(true),
138 m_skip_lldbinit_files(false), m_skip_app_init_files(false),
139 m_comment_char(
'#'), m_batch_command_mode(false),
140 m_truncation_warning(eNoOmission), m_max_depth_warning(eNoOmission),
141 m_command_source_depth(0) {
151 const uint32_t idx = ePropertyExpandRegexAliases;
152 return GetPropertyAtIndexAs<bool>(
153 idx, g_interpreter_properties[idx].default_uint_value != 0);
157 const uint32_t idx = ePropertyPromptOnQuit;
158 return GetPropertyAtIndexAs<bool>(
159 idx, g_interpreter_properties[idx].default_uint_value != 0);
163 const uint32_t idx = ePropertyPromptOnQuit;
168 const uint32_t idx = ePropertySaveTranscript;
169 return GetPropertyAtIndexAs<bool>(
170 idx, g_interpreter_properties[idx].default_uint_value != 0);
174 const uint32_t idx = ePropertySaveTranscript;
179 const uint32_t idx = ePropertySaveSessionOnQuit;
180 return GetPropertyAtIndexAs<bool>(
181 idx, g_interpreter_properties[idx].default_uint_value != 0);
185 const uint32_t idx = ePropertySaveSessionOnQuit;
190 const uint32_t idx = ePropertyOpenTranscriptInEditor;
191 return GetPropertyAtIndexAs<bool>(
192 idx, g_interpreter_properties[idx].default_uint_value != 0);
196 const uint32_t idx = ePropertyOpenTranscriptInEditor;
201 const uint32_t idx = ePropertySaveSessionDirectory;
202 return GetPropertyAtIndexAs<FileSpec>(idx, {});
206 const uint32_t idx = ePropertySaveSessionDirectory;
211 const uint32_t idx = ePropertyEchoCommands;
212 return GetPropertyAtIndexAs<bool>(
213 idx, g_interpreter_properties[idx].default_uint_value != 0);
217 const uint32_t idx = ePropertyEchoCommands;
222 const uint32_t idx = ePropertyEchoCommentCommands;
223 return GetPropertyAtIndexAs<bool>(
224 idx, g_interpreter_properties[idx].default_uint_value != 0);
228 const uint32_t idx = ePropertyEchoCommentCommands;
254 std::string command = command_line;
262 const uint32_t idx = ePropertyStopCmdSourceOnError;
263 return GetPropertyAtIndexAs<bool>(
264 idx, g_interpreter_properties[idx].default_uint_value != 0);
268 const uint32_t idx = ePropertySpaceReplPrompts;
269 return GetPropertyAtIndexAs<bool>(
270 idx, g_interpreter_properties[idx].default_uint_value != 0);
274 const uint32_t idx = ePropertyRepeatPreviousCommand;
275 return GetPropertyAtIndexAs<bool>(
276 idx, g_interpreter_properties[idx].default_uint_value != 0);
280 const uint32_t idx = ePropertyRequireCommandOverwrite;
281 return GetPropertyAtIndexAs<bool>(
282 idx, g_interpreter_properties[idx].default_uint_value != 0);
342 "sif", cmd_obj_sp,
"--end-linenumber block --step-in-target %1");
344 sif_alias->
SetHelp(
"Step through the current block, stopping if you step "
345 "directly into a function whose name matches the "
346 "TargetFunctionName.");
347 sif_alias->
SetSyntax(
"sif <TargetFunctionName>");
428 alias_arguments_vector_sp = std::make_shared<OptionArgVector>();
434 if (
auto *po =
AddAlias(
"po", cmd_obj_sp,
"-O --")) {
435 po->SetHelp(
"Evaluate an expression on the current thread. Displays any "
436 "returned value with formatting "
437 "controlled by the type's author.");
448 AddAlias(
"parray", cmd_obj_sp,
"--element-count %1 --");
451 (
"parray <COUNT> <EXPRESSION> -- lldb will evaluate EXPRESSION "
452 "to get a typed-pointer-to-an-array in memory, and will display "
453 "COUNT elements of that type from the array.");
457 "--object-description --element-count %1 --");
459 poarray_alias->
SetHelp(
"poarray <COUNT> <EXPRESSION> -- lldb will "
460 "evaluate EXPRESSION to get the address of an array of COUNT "
461 "objects in memory, and will call po on them.");
470 shell_alias->
SetHelp(
"Run a shell command on the host.");
472 shell_alias->
SetSyntax(
"shell <shell-command>");
483 alias_arguments_vector_sp = std::make_shared<OptionArgVector>();
484#if defined(__APPLE__)
489 AddAlias(
"r", cmd_obj_sp,
"--shell-expand-args true --");
490 AddAlias(
"run", cmd_obj_sp,
"--shell-expand-args true --");
494 defaultshell.
Printf(
"--shell=%s --",
495 HostInfo::GetDefaultShell().GetPath().c_str());
508 AddAlias(
"rbreak", cmd_obj_sp,
"--func-regex %1");
515 AddAlias(
"vo", cmd_obj_sp,
"--object-description");
556#define REGISTER_COMMAND_OBJECT(NAME, CLASS) \
557 m_command_dict[NAME] = std::make_shared<CLASS>(*this);
593 const char *break_regexes[][2] = {
594 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
595 "breakpoint set --file '%1' --line %2 --column %3"},
596 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
597 "breakpoint set --file '%1' --line %2"},
598 {
"^/([^/]+)/$",
"breakpoint set --source-pattern-regexp '%1'"},
599 {
"^([[:digit:]]+)[[:space:]]*$",
"breakpoint set --line %1"},
600 {
"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
"breakpoint set --address %1"},
601 {
"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$",
602 "breakpoint set --name '%1'"},
603 {
"^(-.*)$",
"breakpoint set %1"},
604 {
"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$",
605 "breakpoint set --name '%2' --shlib '%1'"},
606 {
"^\\&(.*[^[:space:]])[[:space:]]*$",
607 "breakpoint set --name '%1' --skip-prologue=0"},
608 {
"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$",
609 "breakpoint set --name '%1'"}};
612 size_t num_regexes = std::size(break_regexes);
614 std::unique_ptr<CommandObjectRegexCommand> break_regex_cmd_up(
616 *
this,
"_regexp-break",
617 "Set a breakpoint using one of several shorthand formats.",
619 "_regexp-break <filename>:<linenum>:<colnum>\n"
620 " main.c:12:21 // Break at line 12 and column "
622 "_regexp-break <filename>:<linenum>\n"
623 " main.c:12 // Break at line 12 of "
625 "_regexp-break <linenum>\n"
626 " 12 // Break at line 12 of current "
628 "_regexp-break 0x<address>\n"
629 " 0x1234000 // Break at address "
631 "_regexp-break <name>\n"
632 " main // Break in 'main' after the "
634 "_regexp-break &<name>\n"
635 " &main // Break at first instruction "
637 "_regexp-break <module>`<name>\n"
638 " libc.so`malloc // Break in 'malloc' from "
640 "_regexp-break /<source-regex>/\n"
641 " /break here/ // Break on source lines in "
643 " // containing text 'break "
647 if (break_regex_cmd_up) {
649 for (
size_t i = 0; i < num_regexes; i++) {
650 success = break_regex_cmd_up->AddRegexCommand(break_regexes[i][0],
651 break_regexes[i][1]);
656 break_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
660 m_command_dict[std::string(break_regex_cmd_sp->GetCommandName())] =
665 std::unique_ptr<CommandObjectRegexCommand> tbreak_regex_cmd_up(
667 *
this,
"_regexp-tbreak",
668 "Set a one-shot breakpoint using one of several shorthand formats.",
670 "_regexp-break <filename>:<linenum>:<colnum>\n"
671 " main.c:12:21 // Break at line 12 and column "
673 "_regexp-break <filename>:<linenum>\n"
674 " main.c:12 // Break at line 12 of "
676 "_regexp-break <linenum>\n"
677 " 12 // Break at line 12 of current "
679 "_regexp-break 0x<address>\n"
680 " 0x1234000 // Break at address "
682 "_regexp-break <name>\n"
683 " main // Break in 'main' after the "
685 "_regexp-break &<name>\n"
686 " &main // Break at first instruction "
688 "_regexp-break <module>`<name>\n"
689 " libc.so`malloc // Break in 'malloc' from "
691 "_regexp-break /<source-regex>/\n"
692 " /break here/ // Break on source lines in "
694 " // containing text 'break "
698 if (tbreak_regex_cmd_up) {
700 for (
size_t i = 0; i < num_regexes; i++) {
701 std::string command = break_regexes[i][1];
704 tbreak_regex_cmd_up->AddRegexCommand(break_regexes[i][0], command);
709 tbreak_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
713 m_command_dict[std::string(tbreak_regex_cmd_sp->GetCommandName())] =
718 std::unique_ptr<CommandObjectRegexCommand> attach_regex_cmd_up(
720 *
this,
"_regexp-attach",
"Attach to process by ID or name.",
721 "_regexp-attach <pid> | <process-name>", 0,
false));
722 if (attach_regex_cmd_up) {
723 if (attach_regex_cmd_up->AddRegexCommand(
"^([0-9]+)[[:space:]]*$",
724 "process attach --pid %1") &&
725 attach_regex_cmd_up->AddRegexCommand(
726 "^(-.*|.* -.*)$",
"process attach %1") &&
729 attach_regex_cmd_up->AddRegexCommand(
"^(.+)$",
730 "process attach --name '%1'") &&
731 attach_regex_cmd_up->AddRegexCommand(
"^$",
"process attach")) {
733 m_command_dict[std::string(attach_regex_cmd_sp->GetCommandName())] =
738 std::unique_ptr<CommandObjectRegexCommand> down_regex_cmd_up(
740 "Select a newer stack frame. Defaults to "
741 "moving one frame, a numeric argument can "
742 "specify an arbitrary number.",
743 "_regexp-down [<count>]", 0,
false));
744 if (down_regex_cmd_up) {
745 if (down_regex_cmd_up->AddRegexCommand(
"^$",
"frame select -r -1") &&
746 down_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
747 "frame select -r -%1")) {
749 m_command_dict[std::string(down_regex_cmd_sp->GetCommandName())] =
754 std::unique_ptr<CommandObjectRegexCommand> up_regex_cmd_up(
757 "Select an older stack frame. Defaults to moving one "
758 "frame, a numeric argument can specify an arbitrary number.",
759 "_regexp-up [<count>]", 0,
false));
760 if (up_regex_cmd_up) {
761 if (up_regex_cmd_up->AddRegexCommand(
"^$",
"frame select -r 1") &&
762 up_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
"frame select -r %1")) {
769 std::unique_ptr<CommandObjectRegexCommand> display_regex_cmd_up(
771 *
this,
"_regexp-display",
772 "Evaluate an expression at every stop (see 'help target stop-hook'.)",
773 "_regexp-display expression", 0,
false));
774 if (display_regex_cmd_up) {
775 if (display_regex_cmd_up->AddRegexCommand(
776 "^(.+)$",
"target stop-hook add -o \"expr -- %1\"")) {
778 m_command_dict[std::string(display_regex_cmd_sp->GetCommandName())] =
779 display_regex_cmd_sp;
783 std::unique_ptr<CommandObjectRegexCommand> undisplay_regex_cmd_up(
785 "Stop displaying expression at every "
786 "stop (specified by stop-hook index.)",
787 "_regexp-undisplay stop-hook-number", 0,
789 if (undisplay_regex_cmd_up) {
790 if (undisplay_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
791 "target stop-hook delete %1")) {
792 CommandObjectSP undisplay_regex_cmd_sp(undisplay_regex_cmd_up.release());
793 m_command_dict[std::string(undisplay_regex_cmd_sp->GetCommandName())] =
794 undisplay_regex_cmd_sp;
798 std::unique_ptr<CommandObjectRegexCommand> connect_gdb_remote_cmd_up(
801 "Connect to a process via remote GDB server.\n"
802 "If no host is specified, localhost is assumed.\n"
803 "gdb-remote is an abbreviation for 'process connect --plugin "
804 "gdb-remote connect://<hostname>:<port>'\n",
805 "gdb-remote [<hostname>:]<portnum>", 0,
false));
806 if (connect_gdb_remote_cmd_up) {
807 if (connect_gdb_remote_cmd_up->AddRegexCommand(
808 "^([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)$",
809 "process connect --plugin gdb-remote connect://%1:%2") &&
810 connect_gdb_remote_cmd_up->AddRegexCommand(
812 "process connect --plugin gdb-remote connect://localhost:%1")) {
814 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
818 std::unique_ptr<CommandObjectRegexCommand> connect_kdp_remote_cmd_up(
821 "Connect to a process via remote KDP server.\n"
822 "If no UDP port is specified, port 41139 is assumed.\n"
823 "kdp-remote is an abbreviation for 'process connect --plugin "
824 "kdp-remote udp://<hostname>:<port>'\n",
825 "kdp-remote <hostname>[:<portnum>]", 0,
false));
826 if (connect_kdp_remote_cmd_up) {
827 if (connect_kdp_remote_cmd_up->AddRegexCommand(
828 "^([^:]+:[[:digit:]]+)$",
829 "process connect --plugin kdp-remote udp://%1") &&
830 connect_kdp_remote_cmd_up->AddRegexCommand(
831 "^(.+)$",
"process connect --plugin kdp-remote udp://%1:41139")) {
833 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
837 std::unique_ptr<CommandObjectRegexCommand> bt_regex_cmd_up(
840 "Show backtrace of the current thread's call stack. Any numeric "
841 "argument displays at most that many frames. The argument 'all' "
842 "displays all threads. Use 'settings set frame-format' to customize "
843 "the printing of individual frames and 'settings set thread-format' "
844 "to customize the thread header. Frame recognizers may filter the "
845 "list. Use 'thread backtrace -u (--unfiltered)' to see them all.",
846 "bt [<digit> | all]", 0,
false));
847 if (bt_regex_cmd_up) {
852 if (bt_regex_cmd_up->AddRegexCommand(
"^([[:digit:]]+)[[:space:]]*$",
853 "thread backtrace -c %1") &&
854 bt_regex_cmd_up->AddRegexCommand(
"^(-[^[:space:]].*)$",
"thread backtrace %1") &&
855 bt_regex_cmd_up->AddRegexCommand(
"^all[[:space:]]*$",
"thread backtrace all") &&
856 bt_regex_cmd_up->AddRegexCommand(
"^[[:space:]]*$",
"thread backtrace")) {
858 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
862 std::unique_ptr<CommandObjectRegexCommand> list_regex_cmd_up(
864 *
this,
"_regexp-list",
865 "List relevant source code using one of several shorthand formats.",
867 "_regexp-list <file>:<line> // List around specific file/line\n"
868 "_regexp-list <line> // List current file around specified "
870 "_regexp-list <function-name> // List specified function\n"
871 "_regexp-list 0x<address> // List around specified address\n"
872 "_regexp-list -[<count>] // List previous <count> lines\n"
873 "_regexp-list // List subsequent lines",
875 if (list_regex_cmd_up) {
876 if (list_regex_cmd_up->AddRegexCommand(
"^([0-9]+)[[:space:]]*$",
877 "source list --line %1") &&
878 list_regex_cmd_up->AddRegexCommand(
879 "^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]"
881 "source list --file '%1' --line %2") &&
882 list_regex_cmd_up->AddRegexCommand(
883 "^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
884 "source list --address %1") &&
885 list_regex_cmd_up->AddRegexCommand(
"^-[[:space:]]*$",
886 "source list --reverse") &&
887 list_regex_cmd_up->AddRegexCommand(
888 "^-([[:digit:]]+)[[:space:]]*$",
889 "source list --reverse --count %1") &&
890 list_regex_cmd_up->AddRegexCommand(
"^(.+)$",
891 "source list --name \"%1\"") &&
892 list_regex_cmd_up->AddRegexCommand(
"^$",
"source list")) {
894 m_command_dict[std::string(list_regex_cmd_sp->GetCommandName())] =
899 std::unique_ptr<CommandObjectRegexCommand> env_regex_cmd_up(
901 *
this,
"_regexp-env",
902 "Shorthand for viewing and setting environment variables.",
904 "_regexp-env // Show environment\n"
905 "_regexp-env <name>=<value> // Set an environment variable",
907 if (env_regex_cmd_up) {
908 if (env_regex_cmd_up->AddRegexCommand(
"^$",
909 "settings show target.env-vars") &&
910 env_regex_cmd_up->AddRegexCommand(
"^([A-Za-z_][A-Za-z_0-9]*=.*)$",
911 "settings set target.env-vars %1")) {
918 std::unique_ptr<CommandObjectRegexCommand> jump_regex_cmd_up(
920 *
this,
"_regexp-jump",
"Set the program counter to a new address.",
922 "_regexp-jump <line>\n"
923 "_regexp-jump +<line-offset> | -<line-offset>\n"
924 "_regexp-jump <file>:<line>\n"
925 "_regexp-jump *<addr>\n",
927 if (jump_regex_cmd_up) {
928 if (jump_regex_cmd_up->AddRegexCommand(
"^\\*(.*)$",
929 "thread jump --addr %1") &&
930 jump_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
931 "thread jump --line %1") &&
932 jump_regex_cmd_up->AddRegexCommand(
"^([^:]+):([0-9]+)$",
933 "thread jump --file %1 --line %2") &&
934 jump_regex_cmd_up->AddRegexCommand(
"^([+\\-][0-9]+)$",
935 "thread jump --by %1")) {
937 m_command_dict[std::string(jump_regex_cmd_sp->GetCommandName())] =
944 const char *cmd_str,
bool include_aliases,
StringList &matches,
949 if (include_aliases) {
958 Args &path,
bool leaf_is_command,
Status &result) {
961 auto get_multi_or_report_error =
966 "Path component: '%s' not found", name);
969 if (!cmd_sp->IsUserCommand()) {
971 "Path component: '%s' is not a user "
979 "Path component: '%s' is not a container "
993 if (num_args == 1 && leaf_is_command) {
1003 get_multi_or_report_error(cur_cmd_sp, cur_name);
1004 if (cur_as_multi ==
nullptr)
1007 size_t num_path_elements = num_args - (leaf_is_command ? 1 : 0);
1008 for (
size_t cursor = 1; cursor < num_path_elements && cur_as_multi !=
nullptr;
1012 cur_as_multi = get_multi_or_report_error(cur_cmd_sp, cur_name);
1014 return cur_as_multi;
1023 std::string cmd = std::string(cmd_str);
1028 command_sp = pos->second;
1034 command_sp = alias_pos->second;
1040 command_sp = pos->second;
1046 command_sp = pos->second;
1049 if (!exact && !command_sp) {
1056 if (matches ==
nullptr)
1057 matches = &local_matches;
1059 unsigned int num_cmd_matches = 0;
1060 unsigned int num_alias_matches = 0;
1061 unsigned int num_user_matches = 0;
1062 unsigned int num_user_mw_matches = 0;
1070 *matches, descriptions);
1073 if (num_cmd_matches == 1) {
1077 real_match_sp = pos->second;
1082 *matches, descriptions);
1085 if (num_alias_matches == 1) {
1089 alias_match_sp = alias_pos->second;
1094 *matches, descriptions);
1097 if (num_user_matches == 1) {
1103 user_match_sp = pos->second;
1111 if (num_user_mw_matches == 1) {
1117 user_mw_match_sp = pos->second;
1123 if (num_user_matches + num_user_mw_matches + num_cmd_matches +
1124 num_alias_matches ==
1126 if (num_cmd_matches)
1127 return real_match_sp;
1128 else if (num_alias_matches)
1129 return alias_match_sp;
1130 else if (num_user_mw_matches)
1131 return user_mw_match_sp;
1133 return user_match_sp;
1135 }
else if (matches && command_sp) {
1148 lldbassert((
this == &cmd_sp->GetCommandInterpreter()) &&
1149 "tried to add a CommandObject from a different interpreter");
1154 cmd_sp->SetIsUserCommand(
false);
1156 std::string name_sstr(name);
1159 if (!can_replace || !name_iter->second->IsRemovable())
1161 name_iter->second = cmd_sp;
1173 lldbassert((
this == &cmd_sp->GetCommandInterpreter()) &&
1174 "tried to add a CommandObject from a different interpreter");
1177 "can't use the empty string for a command name");
1189 "user command \"{0}\" already exists and force replace was not set "
1190 "by --overwrite or 'settings set interpreter.require-overwrite "
1195 if (cmd_sp->IsMultiwordObject()) {
1198 "can't replace explicitly non-removable multi-word command");
1202 if (!
m_user_dict[std::string(name)]->IsRemovable()) {
1204 "can't replace explicitly non-removable command");
1210 cmd_sp->SetIsUserCommand(
true);
1212 if (cmd_sp->IsMultiwordObject())
1221 bool include_aliases)
const {
1223 Args cmd_words(cmd_str);
1225 if (cmd_str.empty())
1242 for (
size_t i = 1; i < end; ++i) {
1243 if (!cmd_obj_sp->IsMultiwordObject()) {
1268 matches, descriptions)
1274 std::string cmd_str(cmd);
1276 auto found_elem = map.find(cmd);
1277 if (found_elem == map.end())
1300 StringList *matches_ptr = matches ? matches : &tmp_list;
1303 cmd_str, *matches_ptr);
1312 auto found_elem = map.find(cmd);
1313 if (found_elem == map.end())
1335 StringList *matches_ptr = matches ? matches : &tmp_list;
1346 std::string &full_name)
const {
1349 full_name.assign(std::string(cmd));
1353 size_t num_alias_matches;
1356 if (num_alias_matches == 1) {
1359 const bool include_aliases =
false;
1360 const bool exact =
false;
1362 GetCommandSP(cmd, include_aliases, exact, ®ular_matches));
1363 if (cmd_obj_sp || regular_matches.
GetSize() > 0)
1389 llvm::StringRef args_string) {
1390 if (command_obj_sp.get())
1391 lldbassert((
this == &command_obj_sp->GetCommandInterpreter()) &&
1392 "tried to add a CommandObject from a different interpreter");
1394 std::unique_ptr<CommandAlias> command_alias_up(
1395 new CommandAlias(*
this, command_obj_sp, args_string, alias_name));
1397 if (command_alias_up && command_alias_up->IsValid()) {
1400 return command_alias_up.release();
1418 if (force || pos->second->IsRemovable()) {
1429 CommandObject::CommandMap::iterator pos =
m_user_dict.find(user_name);
1438 CommandObject::CommandMap::iterator pos =
m_user_mw_dict.find(multi_name);
1447 uint32_t cmd_types) {
1448 llvm::StringRef help_prologue(
GetDebugger().GetIOHandlerHelpPrologue());
1449 if (!help_prologue.empty()) {
1454 CommandObject::CommandMap::const_iterator pos;
1463 (pos->first.compare(0, 1,
"_") == 0))
1467 pos->second->GetHelp(), max_len);
1475 "Current command abbreviations "
1476 "(type '%shelp command alias' for more info):\n",
1484 alias_pos->second->GetHelp(), max_len);
1496 pos->second->GetHelp(), max_len);
1503 result.
AppendMessage(
"Current user-defined container commands:");
1508 pos->second->GetHelp(), max_len);
1514 "For more information on any command, type '%shelp <command-name>'.\n",
1519 llvm::StringRef &command_string) {
1525 size_t start = command_string.find_first_not_of(
k_white_space);
1529 if (start != std::string::npos) {
1532 if (end == std::string::npos)
1533 end = command_string.size();
1534 std::string cmd_word =
1535 std::string(command_string.substr(start, end - start));
1537 if (cmd_obj ==
nullptr)
1547 cmd_obj = sub_cmd_obj;
1559 end >= command_string.size())
1562 start = command_string.find_first_not_of(
k_white_space, end);
1568 command_string = command_string.substr(end);
1573 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
1577 if (pos == std::string::npos)
1586 const size_t s_len = s.size();
1588 while (offset < s_len) {
1589 size_t pos = s.find(
"--", offset);
1590 if (pos == std::string::npos)
1593 if (llvm::isSpace(s[pos - 1])) {
1596 if ((pos + 2 >= s_len) || llvm::isSpace(s[pos + 2])) {
1603 return std::string::npos;
1607 std::string &suffix,
char "e_char) {
1612 bool result =
false;
1615 if (!command_string.empty()) {
1616 const char first_char = command_string[0];
1617 if (first_char ==
'\'' || first_char ==
'"') {
1618 quote_char = first_char;
1619 const size_t end_quote_pos = command_string.find(quote_char, 1);
1620 if (end_quote_pos == std::string::npos) {
1621 command.swap(command_string);
1622 command_string.erase();
1624 command.assign(command_string, 1, end_quote_pos - 1);
1625 if (end_quote_pos + 1 < command_string.size())
1626 command_string.erase(0, command_string.find_first_not_of(
1629 command_string.erase();
1632 const size_t first_space_pos =
1634 if (first_space_pos == std::string::npos) {
1635 command.swap(command_string);
1636 command_string.erase();
1638 command.assign(command_string, 0, first_space_pos);
1639 command_string.erase(0, command_string.find_first_not_of(
1646 if (!command.empty()) {
1648 if (command[0] !=
'-' && command[0] !=
'_') {
1650 if (pos > 0 && pos != std::string::npos) {
1651 suffix.assign(command.begin() + pos, command.end());
1661 llvm::StringRef alias_name, std::string &raw_input_string,
1664 Args cmd_args(raw_input_string);
1668 if (!alias_cmd_obj || !alias_cmd_obj->
IsAlias()) {
1669 alias_result.clear();
1670 return alias_cmd_obj;
1672 std::pair<CommandObjectSP, OptionArgVectorSP> desugared =
1675 alias_cmd_obj = desugared.first.get();
1676 std::string alias_name_str = std::string(alias_name);
1679 cmd_args.
Unshift(alias_name_str);
1683 if (!option_arg_vector_sp.get()) {
1684 alias_result = std::string(result_str.
GetString());
1685 return alias_cmd_obj;
1692 for (
const auto &entry : *option_arg_vector) {
1693 std::tie(option, value_type, value) = entry;
1695 result_str.
Printf(
" %s", value.c_str());
1699 result_str.
Printf(
" %s", option.c_str());
1707 result_str.
Printf(
"%s", value.c_str());
1711 "need at least %d arguments to use "
1717 size_t strpos = raw_input_string.find(entry.
c_str());
1719 if (strpos != std::string::npos) {
1720 const size_t start_fudge = quote_char ==
'\0' ? 0 : 1;
1721 const size_t len_fudge = quote_char ==
'\0' ? 0 : 2;
1724 if (strpos < start_fudge) {
1725 result.
AppendError(
"Unmatched quote at command beginning.");
1728 llvm::StringRef arg_text = entry.
ref();
1729 if (strpos - start_fudge + arg_text.size() + len_fudge >
1730 raw_input_string.size()) {
1731 result.
AppendError(
"Unmatched quote at command end.");
1734 raw_input_string = raw_input_string.erase(
1735 strpos - start_fudge,
1738 if (quote_char ==
'\0')
1741 result_str.
Printf(
"%c%s%c", quote_char, entry.
c_str(), quote_char);
1745 alias_result = std::string(result_str.
GetString());
1746 return alias_cmd_obj;
1757 size_t start_backtick;
1759 while ((start_backtick = command.find(
'`', pos)) != std::string::npos) {
1764 if (start_backtick > 0 && command[start_backtick - 1] ==
'\\') {
1767 command.erase(start_backtick - 1, 1);
1769 pos = start_backtick;
1773 const size_t expr_content_start = start_backtick + 1;
1774 const size_t end_backtick = command.find(
'`', expr_content_start);
1776 if (end_backtick == std::string::npos) {
1781 if (end_backtick == expr_content_start) {
1783 command.erase(start_backtick, 2);
1787 std::string expr_str(command, expr_content_start,
1788 end_backtick - expr_content_start);
1794 command.erase(start_backtick, end_backtick - start_backtick + 1);
1795 command.insert(start_backtick, std::string(expr_str));
1796 pos = start_backtick + expr_str.size();
1824 expr_result_valobj_sp, options);
1828 if (expr_result_valobj_sp)
1829 expr_result_valobj_sp =
1830 expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable(
1831 expr_result_valobj_sp->GetDynamicValueType(),
true);
1832 if (expr_result_valobj_sp->ResolveValue(scalar)) {
1835 const bool show_type =
false;
1836 scalar.
GetValue(value_strm, show_type);
1837 size_t value_string_size = value_strm.
GetSize();
1838 if (value_string_size) {
1839 expr_str = value_strm.
GetData();
1843 "in a scalar value for the "
1850 "in a scalar value for the "
1861 if (expr_result_valobj_sp)
1862 error = expr_result_valobj_sp->GetError().Clone();
1864 if (
error.Success()) {
1866 "for the expression '" + expr_str +
"'";
1878 bool status =
HandleCommand(command_line, lazy_add_to_history, result);
1886 bool force_repeat_command) {
1887 std::string command_string(command_line);
1888 std::string original_command_string(command_string);
1889 std::string real_original_command_string(command_string);
1892 llvm::PrettyStackTraceFormat stack_trace(
"HandleCommand(command = \"%s\")",
1895 LLDB_LOGF(log,
"Processing command: %s", command_line);
1903 bool add_to_history;
1907 add_to_history = (lazy_add_to_history ==
eLazyBoolYes);
1915 transcript_item = std::make_shared<StructuredData::Dictionary>();
1916 transcript_item->AddStringItem(
"command", command_line);
1917 transcript_item->AddIntegerItem(
1918 "timestampInEpochSeconds",
1919 std::chrono::duration_cast<std::chrono::seconds>(
1920 std::chrono::system_clock::now().time_since_epoch())
1925 bool empty_command =
false;
1926 bool comment_command =
false;
1927 if (command_string.empty())
1928 empty_command =
true;
1930 const char *k_space_characters =
"\t\n\v\f\r ";
1932 size_t non_space = command_string.find_first_not_of(k_space_characters);
1935 if (non_space == std::string::npos)
1936 empty_command =
true;
1938 comment_command =
true;
1940 llvm::StringRef search_str(command_string);
1941 search_str = search_str.drop_front(non_space);
1943 add_to_history =
false;
1944 command_string = std::string(*hist_str);
1945 original_command_string = std::string(*hist_str);
1948 command_string.c_str());
1954 if (empty_command) {
1966 command_string = command_line;
1967 original_command_string = command_line;
1973 add_to_history =
false;
1974 }
else if (comment_command) {
2014 llvm::StringRef command_name = cmd_obj ? cmd_obj->
GetCommandName() :
"<not found>";
2015 LLDB_LOGF(log,
"HandleCommand, cmd_obj : '%s'", command_name.str().c_str());
2016 LLDB_LOGF(log,
"HandleCommand, (revised) command_string: '%s'",
2017 command_string.c_str());
2018 const bool wants_raw_input =
2020 LLDB_LOGF(log,
"HandleCommand, wants_raw_input:'%s'",
2021 wants_raw_input ?
"True" :
"False");
2029 if (cmd_obj !=
nullptr) {
2030 bool generate_repeat_command = add_to_history;
2034 generate_repeat_command |= empty_command;
2039 generate_repeat_command |= force_repeat_command;
2040 if (generate_repeat_command) {
2041 Args command_args(command_string);
2042 std::optional<std::string> repeat_command =
2044 if (repeat_command) {
2045 LLDB_LOGF(log,
"Repeat command: %s", repeat_command->data());
2055 std::string remainder;
2056 const std::size_t actual_cmd_name_len = cmd_obj->
GetCommandName().size();
2057 if (actual_cmd_name_len < command_string.length())
2058 remainder = command_string.substr(actual_cmd_name_len);
2062 if (pos != 0 && pos != std::string::npos)
2063 remainder.erase(0, pos);
2066 log,
"HandleCommand, command line after removing command name(s): '%s'",
2072 if (transcript_item) {
2073 transcript_item->AddStringItem(
"commandName", cmd_obj->
GetCommandName());
2074 transcript_item->AddStringItem(
"commandArguments", remainder);
2080 pos = real_original_command_string.rfind(remainder);
2081 std::optional<uint16_t> indent;
2082 if (pos != std::string::npos)
2085 cmd_obj->
Execute(remainder.c_str(), result);
2088 LLDB_LOGF(log,
"HandleCommand, command %s",
2089 (result.
Succeeded() ?
"succeeded" :
"did not succeed"));
2094 if (transcript_item) {
2099 transcript_item->AddStringItem(
"error", result.
GetErrorString());
2100 transcript_item->AddFloatItem(
"durationInSeconds",
2101 execute_time.
get().count());
2108 bool look_for_subcommand =
false;
2114 bool include_aliases =
true;
2125 &new_matches, &new_descriptions);
2132 look_for_subcommand =
true;
2147 if (command_object) {
2160 if (!first_arg.empty()) {
2165 request.
AddCompletion(*hist_str,
"Previous command history event",
2174std::optional<std::string>
2177 return std::nullopt;
2179 for (
int i = s - 1; i >= 0; --i) {
2181 if (entry.consume_front(line))
2184 return std::nullopt;
2188 EventSP prompt_change_event_sp(
2199 return default_answer;
2232 const char *alias_name,
2234 std::string &raw_input_string,
2242 std::string alias_name_str = alias_name;
2244 cmd_args.
Unshift(alias_name_str);
2250 if (option_arg_vector_sp.get()) {
2251 if (wants_raw_input) {
2255 size_t pos = raw_input_string.find(
" -- ");
2256 if (pos == std::string::npos) {
2258 raw_input_string.insert(0,
" -- ");
2264 std::vector<bool> used(old_size + 1,
false);
2271 for (
const auto &option_entry : *option_arg_vector) {
2272 std::tie(option, value_type, value) = option_entry;
2274 if (!wants_raw_input || (value !=
"--")) {
2298 "need at least %d arguments to use "
2306 if (strpos != std::string::npos) {
2307 raw_input_string = raw_input_string.erase(
2320 for (
auto entry : llvm::enumerate(cmd_args.
entries())) {
2321 if (!used[entry.index()] && !wants_raw_input)
2334 if (wants_raw_input) {
2350 const char *cptr = in_string;
2353 if (cptr[0] ==
'%') {
2357 if (isdigit(cptr[0])) {
2358 const char *start = cptr;
2359 while (isdigit(cptr[0]))
2364 if (cptr[0] ==
'\0')
2365 position = atoi(start);
2373 llvm::StringRef suffix = {}) {
2374 std::string init_file_name =
".lldbinit";
2375 if (!suffix.empty()) {
2376 init_file_name.append(
"-");
2377 init_file_name.append(suffix.str());
2381 llvm::sys::path::append(init_file, init_file_name);
2391 language = *main_repl_language;
2396 std::string init_file_name =
2397 (llvm::Twine(
".lldbinit-") +
2399 llvm::Twine(
"-repl"))
2402 llvm::sys::path::append(init_file, init_file_name);
2407 llvm::StringRef s =
".lldbinit";
2408 init_file.assign(s.begin(), s.end());
2440 llvm::SmallString<128> init_file;
2450 switch (should_load) {
2458 llvm::SmallString<128> home_init_file;
2460 if (llvm::sys::path::parent_path(init_file) ==
2461 llvm::sys::path::parent_path(home_init_file)) {
2481 llvm::SmallString<128> init_file;
2486 if (init_file.empty())
2490 llvm::StringRef program_name =
2491 HostInfo::GetProgramFileSpec().GetFilename().GetStringRef();
2492 llvm::SmallString<128> program_init_file;
2495 init_file = program_init_file;
2502#ifdef LLDB_GLOBAL_INIT_DIRECTORY
2504 FileSpec init_file(LLDB_GLOBAL_INIT_DIRECTORY);
2518 return prefix ==
nullptr ?
"" : prefix;
2523 if (prefer_target_platform) {
2537 TargetSP target_sp = exe_ctx.GetTargetSP();
2541 ProcessSP process_sp(target_sp->GetProcessSP());
2548 for (
const auto &thread_sp : process_sp->GetThreadList().Threads()) {
2549 StopInfoSP stop_info = thread_sp->GetStopInfo();
2557 const StopReason reason = stop_info->GetStopReason();
2564 const auto stop_signal =
static_cast<int32_t
>(stop_info->GetValue());
2566 if (!signals_sp || !signals_sp->SignalIsValid(stop_signal))
2570 const auto sigint_num = signals_sp->GetSignalNumberFromName(
"SIGINT");
2571 const auto sigstop_num = signals_sp->GetSignalNumberFromName(
"SIGSTOP");
2572 if ((stop_signal != sigint_num) && (stop_signal != sigstop_num))
2595 size_t num_lines = commands.
GetSize();
2607 for (
size_t idx = 0; idx < num_lines; idx++) {
2636 if (!success || !tmp_result.
Succeeded()) {
2638 if (error_msg.empty())
2639 error_msg =
"<unknown error>.\n";
2642 "command #{0}: '{1}' failed with {2}",
2643 (uint64_t)idx, cmd, error_msg);
2648 (uint64_t)idx + 1, cmd, error_msg);
2669 if (idx != num_lines - 1)
2671 "Aborting reading of commands after command #%" PRIu64
2672 ": '%s' continued the target.\n",
2673 (uint64_t)idx + 1, cmd);
2676 " '%s' continued the target.\n",
2677 (uint64_t)idx + 1, cmd);
2689 if (idx != num_lines - 1)
2691 "Aborting reading of commands after command #%" PRIu64
2692 ": '%s' stopped with a signal or exception.\n",
2693 (uint64_t)idx + 1, cmd);
2696 "Command #%" PRIu64
" '%s' stopped with a signal or exception.\n",
2697 (uint64_t)idx + 1, cmd);
2735 "Error reading commands from file %s - file not found.\n",
2740 std::string cmd_file_path = cmd_file.
GetPath();
2741 auto input_file_up =
2743 if (!input_file_up) {
2744 std::string
error = llvm::toString(input_file_up.takeError());
2746 "error: an error occurred read file '{0}': {1}\n", cmd_file_path,
2747 llvm::fmt_consume(input_file_up.takeError()));
2750 FileSP input_file_sp =
FileSP(std::move(input_file_up.get()));
2837 cmd_file_path.c_str());
2853 debugger.
GetPrompt(), llvm::StringRef(),
2883 llvm::StringRef prefix,
2884 llvm::StringRef help_text) {
2887 size_t line_width_max = max_columns - prefix.size();
2888 if (line_width_max < 16)
2889 line_width_max = help_text.size() + prefix.size();
2892 bool prefixed_yet =
false;
2894 if (help_text.empty())
2895 help_text =
"No help text";
2896 while (!help_text.empty()) {
2898 if (!prefixed_yet) {
2900 prefixed_yet =
true;
2905 llvm::StringRef this_line = help_text.substr(0, line_width_max);
2908 std::size_t first_newline = this_line.find_first_of(
"\n");
2911 std::size_t last_space = llvm::StringRef::npos;
2912 if (this_line.size() != help_text.size())
2913 last_space = this_line.find_last_of(
" \t");
2916 this_line = this_line.substr(0, std::min(first_newline, last_space));
2921 help_text = help_text.drop_front(this_line.size()).ltrim();
2927 llvm::StringRef word_text,
2928 llvm::StringRef separator,
2929 llvm::StringRef help_text,
2930 size_t max_word_len) {
2932 prefix_stream.
Printf(
" %-*s %*s ", (
int)max_word_len, word_text.data(),
2933 (
int)separator.size(), separator.data());
2938 llvm::StringRef separator,
2939 llvm::StringRef help_text,
2940 uint32_t max_word_len) {
2941 int indent_size = max_word_len + separator.size() + 2;
2946 text_strm.
Printf(
"%-*s ", (
int)max_word_len, word_text.data());
2947 text_strm << separator <<
" " << help_text;
2951 llvm::StringRef text = text_strm.
GetString();
2953 uint32_t chars_left = max_columns;
2955 auto nextWordLength = [](llvm::StringRef S) {
2956 size_t pos = S.find(
' ');
2957 return pos == llvm::StringRef::npos ? S.size() : pos;
2960 while (!text.empty()) {
2961 if (text.front() ==
'\n' ||
2962 (text.front() ==
' ' && nextWordLength(text.ltrim(
' ')) > chars_left)) {
2965 chars_left = max_columns - indent_size;
2966 if (text.front() ==
'\n')
2967 text = text.drop_front();
2969 text = text.ltrim(
' ');
2973 text = text.drop_front();
2982 llvm::StringRef search_word,
StringList &commands_found,
2984 for (
const auto &pair : command_map) {
2985 llvm::StringRef command_name = pair.first;
2988 const bool search_short_help =
true;
2989 const bool search_long_help =
false;
2990 const bool search_syntax =
false;
2991 const bool search_options =
false;
2992 if (command_name.contains_insensitive(search_word) ||
2994 search_long_help, search_syntax,
3003 multiword_cmd->GetSubcommandDictionary());
3004 for (
const auto &subcommand_name : subcommands_found) {
3005 std::string qualified_name =
3006 (command_name +
" " + subcommand_name).str();
3016 bool search_builtin_commands,
3017 bool search_user_commands,
3018 bool search_alias_commands,
3019 bool search_user_mw_commands) {
3020 CommandObject::CommandMap::const_iterator pos;
3022 if (search_builtin_commands)
3026 if (search_user_commands)
3030 if (search_user_mw_commands)
3034 if (search_alias_commands)
3089 bool was_interrupted =
3092 return was_interrupted;
3096 llvm::StringRef str,
3102 bool had_output = !str.empty();
3103 while (!str.empty()) {
3104 llvm::StringRef line;
3105 std::tie(line, str) = str.split(
'\n');
3107 std::lock_guard<std::recursive_mutex> guard(io_handler.
GetOutputMutex());
3108 stream->Write(line.data(), line.size());
3109 stream->Write(
"\n", 1);
3113 std::lock_guard<std::recursive_mutex> guard(io_handler.
GetOutputMutex());
3116 stream->Printf(
"\n... Interrupted.\n");
3121 llvm::StringRef line,
const Flags &io_handler_flags)
const {
3125 llvm::StringRef command = line.trim();
3126 if (command.empty())
3136 std::string &line) {
3142 const bool allow_repeats =
3145 if (!is_interactive && !allow_repeats) {
3154 if (!is_interactive) {
3159 std::lock_guard<std::recursive_mutex> guard(io_handler.
GetOutputMutex());
3161 "%s%s\n", io_handler.
GetPrompt(), line.c_str());
3168 bool pushed_exe_ctx =
false;
3171 pushed_exe_ctx =
true;
3173 auto finalize = llvm::make_scope_exit([
this, pushed_exe_ctx]() {
3182 if ((result.Succeeded() &&
3186 const bool inline_diagnostics = !result.GetImmediateErrorStream() &&
3188 if (inline_diagnostics) {
3190 if (
auto indent = result.GetDiagnosticIndent()) {
3192 result.GetInlineDiagnosticString(prompt_len + *indent);
3200 if (!result.GetImmediateOutputStream()) {
3201 llvm::StringRef output = result.GetOutputString();
3206 if (!result.GetImmediateErrorStream()) {
3207 std::string
error = result.GetErrorString(!inline_diagnostics);
3214 switch (result.GetStatus()) {
3243 result.GetDidChangeProcessState() &&
3268 if (script_interpreter) {
3277 if (output_file == std::nullopt || output_file->empty()) {
3278 std::string now = llvm::to_string(std::chrono::system_clock::now());
3279 std::replace(now.begin(), now.end(),
' ',
'_');
3281 std::replace(now.begin(), now.end(),
':',
'-');
3282 const std::string file_name =
"lldb_session_" + now +
".log";
3287 save_location = HostInfo::GetGlobalTempDir();
3291 output_file = save_location.
GetPath();
3294 auto error_out = [&](llvm::StringRef error_message, std::string description) {
3296 output_file, description);
3298 "Failed to save session's transcripts to {0}!", *output_file);
3309 return error_out(
"Unable to create file",
3310 llvm::toString(opened_file.takeError()));
3312 FileUP file = std::move(opened_file.get());
3319 return error_out(
"Unable to write to destination file",
3320 "Bytes written do not match transcript size.");
3324 output_file->c_str());
3327 "Note: the setting interpreter.save-transcript is set to false, so the "
3328 "transcript might not have been recorded.");
3332 error = file->GetFileSpec(
const_cast<FileSpec &
>(file_spec));
3333 if (
error.Success()) {
3359 llvm::StringRef(prompt),
3366 if (io_handler_sp) {
3367 io_handler_sp->SetUserData(baton);
3378 llvm::StringRef(prompt),
3385 if (io_handler_sp) {
3386 io_handler_sp->SetUserData(baton);
3446 bool force_create =
true;
3474 std::string scratch_command(command_line);
3478 bool wants_raw_input =
false;
3479 std::string next_word;
3483 auto build_alias_cmd = [&](std::string &full_name) {
3484 revised_command_line.
Clear();
3486 std::string alias_result;
3489 revised_command_line.
Printf(
"%s", alias_result.c_str());
3496 char quote_char =
'\0';
3499 if (cmd_obj ==
nullptr) {
3500 std::string full_name;
3503 bool is_real_command =
3504 (!is_alias) || (cmd_obj !=
nullptr && !cmd_obj->
IsAlias());
3505 if (!is_real_command) {
3506 build_alias_cmd(full_name);
3510 revised_command_line.
Printf(
"%s", cmd_name.str().c_str());
3513 revised_command_line.
Printf(
"%s", next_word.c_str());
3524 revised_command_line.
Clear();
3525 revised_command_line.
Printf(
"%s", sub_cmd_name.str().c_str());
3526 cmd_obj = sub_cmd_obj;
3530 revised_command_line.
Printf(
" %c%s%s%c", quote_char,
3531 next_word.c_str(), suffix.c_str(),
3534 revised_command_line.
Printf(
" %s%s", next_word.c_str(),
3540 revised_command_line.
Printf(
" %c%s%s%c", quote_char,
3541 next_word.c_str(), suffix.c_str(),
3544 revised_command_line.
Printf(
" %s%s", next_word.c_str(),
3550 if (cmd_obj ==
nullptr) {
3551 const size_t num_matches = matches.
GetSize();
3556 if (alias_matches.
GetSize() == 1) {
3557 std::string full_name;
3559 build_alias_cmd(full_name);
3560 done =
static_cast<bool>(cmd_obj);
3563 error_msg.
Printf(
"Ambiguous command '%s'. Possible matches:\n",
3566 for (uint32_t i = 0; i < num_matches; ++i) {
3582 if (!suffix.empty()) {
3584 "command '%s' did not recognize '%s%s%s' as valid (subcommand "
3585 "might be invalid).\n",
3587 next_word.empty() ?
"" : next_word.c_str(),
3588 next_word.empty() ?
" -- " :
" ", suffix.c_str());
3594 if (!suffix.empty()) {
3595 switch (suffix[0]) {
3600 if (command_options &&
3602 std::string gdb_format_option(
"--gdb-format=");
3603 gdb_format_option += (suffix.c_str() + 1);
3605 std::string cmd = std::string(revised_command_line.
GetString());
3607 if (arg_terminator_idx != std::string::npos) {
3610 gdb_format_option.append(1,
' ');
3611 cmd.insert(arg_terminator_idx, gdb_format_option);
3612 revised_command_line.
Clear();
3615 revised_command_line.
Printf(
" %s", gdb_format_option.c_str());
3617 if (wants_raw_input &&
3622 "the '%s' command doesn't support the --gdb-format option\n",
3631 "unknown command shorthand suffix: '%s'\n", suffix.c_str());
3636 if (scratch_command.empty())
3640 if (!scratch_command.empty())
3641 revised_command_line.
Printf(
" %s", scratch_command.c_str());
3643 if (cmd_obj !=
nullptr)
3644 command_line = std::string(revised_command_line.
GetString());
3650 llvm::json::Object stats;
3652 stats.try_emplace(command_usage.getKey(), command_usage.getValue());
static const char * k_valid_command_chars
static constexpr const char * InitFileWarning
static size_t FindArgumentTerminator(const std::string &s)
#define REGISTER_COMMAND_OBJECT(NAME, CLASS)
static void StripLeadingSpaces(std::string &s)
static void GetHomeREPLInitFile(llvm::SmallVectorImpl< char > &init_file, LanguageType language)
static void GetCwdInitFile(llvm::SmallVectorImpl< char > &init_file)
static const char * k_white_space
static void GetHomeInitFile(llvm::SmallVectorImpl< char > &init_file, llvm::StringRef suffix={})
@ eHandleCommandFlagAllowRepeats
@ eHandleCommandFlagStopOnCrash
@ eHandleCommandFlagEchoCommentCommand
@ eHandleCommandFlagStopOnError
@ eHandleCommandFlagStopOnContinue
@ eHandleCommandFlagPrintErrors
@ eHandleCommandFlagEchoCommand
@ eHandleCommandFlagPrintResult
static bool ExtractCommand(std::string &command_string, std::string &command, std::string &suffix, char "e_char)
static llvm::raw_ostream & error(Stream &strm)
#define INTERRUPT_REQUESTED(debugger,...)
This handy define will keep you from having to generate a report for the interruption by hand.
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
static double elapsed(const StatsTimepoint &start, const StatsTimepoint &end)
#define LLDB_SCOPED_TIMER()
#define LLDB_SCOPED_TIMERF(...)
A command line argument class.
void Unshift(llvm::StringRef arg_str, char quote_char='\0')
Inserts a class owned copy of arg_str at the beginning of the argument vector.
void Shift()
Shifts the first argument C string value of the array off the argument array.
void SetArguments(size_t argc, const char **argv)
Sets the argument vector value, optionally copying all arguments into an internal buffer.
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
llvm::ArrayRef< ArgEntry > entries() const
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
const char ** GetConstArgumentVector() const
Gets the argument vector.
void Clear()
Clear the arguments.
An event broadcasting class.
void SetEventName(uint32_t event_mask, const char *name)
Set the name for an event bit.
void BroadcastEvent(lldb::EventSP &event_sp)
Broadcast an event which has no associated data.
void CheckInWithManager()
OptionArgVectorSP GetOptionArguments() const
void SetHelp(llvm::StringRef str) override
void SetHelpLong(llvm::StringRef str) override
std::optional< llvm::StringRef > FindString(llvm::StringRef input_str) const
static const char g_repeat_char
llvm::StringRef GetStringAtIndex(size_t idx) const
void AppendString(llvm::StringRef str, bool reject_if_dupe=true)
bool GetSpawnThread() const
void SetStopOnContinue(bool stop_on_continue)
void SetSilent(bool silent)
bool GetAutoHandleEvents() const
void SetPrintErrors(bool print_errors)
LazyBool m_add_to_history
bool GetStopOnCrash() const
bool GetAddToHistory() const
bool GetStopOnContinue() const
bool GetPrintResults() const
void SetStopOnError(bool stop_on_error)
bool GetStopOnError() const
bool GetEchoCommands() const
LazyBool m_echo_comment_commands
LazyBool m_stop_on_continue
bool IsResult(lldb::CommandInterpreterResult result)
void SetResult(lldb::CommandInterpreterResult result)
void IncrementNumberOfErrors()
CommandUsageMap m_command_usages
bool m_skip_lldbinit_files
bool GetSaveTranscript() const
bool EchoCommandNonInteractive(llvm::StringRef line, const Flags &io_handler_flags) const
void UpdatePrompt(llvm::StringRef prompt)
bool IOHandlerInterrupt(IOHandler &io_handler) override
lldb::IOHandlerSP m_command_io_handler_sp
void SetPromptOnQuit(bool enable)
void SourceInitFileHome(CommandReturnObject &result, bool is_repl)
We will first see if there is an application specific ".lldbinit" file whose name is "~/....
std::optional< std::string > GetAutoSuggestionForCommand(llvm::StringRef line)
Returns the auto-suggestion string that should be added to the given command line.
void IOHandlerInputComplete(IOHandler &io_handler, std::string &line) override
Called when a line or lines have been retrieved.
llvm::json::Value GetStatistics()
void LoadCommandDictionary()
std::stack< ExecutionContext > m_overriden_exe_contexts
bool GetStopCmdSourceOnError() const
void OutputFormattedHelpText(Stream &strm, llvm::StringRef prefix, llvm::StringRef help_text)
bool Confirm(llvm::StringRef message, bool default_answer)
bool UserMultiwordCommandExists(llvm::StringRef cmd) const
Determine whether a root-level user multiword command with this name exists.
static llvm::StringRef GetStaticBroadcasterClass()
CommandObject * GetAliasCommandObject(llvm::StringRef cmd, StringList *matches=nullptr, StringList *descriptions=nullptr) const
static const char * g_no_argument
void SetEchoCommands(bool enable)
bool RemoveAlias(llvm::StringRef alias_name)
void SetSaveSessionDirectory(llvm::StringRef path)
bool HasAliasOptions() const
void SourceInitFile(FileSpec file, CommandReturnObject &result)
CommandAlias * AddAlias(llvm::StringRef alias_name, lldb::CommandObjectSP &command_obj_sp, llvm::StringRef args_string=llvm::StringRef())
int GetCommandNamesMatchingPartialString(const char *cmd_cstr, bool include_aliases, StringList &matches, StringList &descriptions)
void FindCommandsForApropos(llvm::StringRef word, StringList &commands_found, StringList &commands_help, bool search_builtin_commands, bool search_user_commands, bool search_alias_commands, bool search_user_mw_commands)
CommandObject * GetCommandObject(llvm::StringRef cmd, StringList *matches=nullptr, StringList *descriptions=nullptr) const
std::atomic< CommandHandlingState > m_command_state
Status PreprocessCommand(std::string &command)
CommandObject::CommandMap m_alias_dict
CommandObject * ResolveCommandImpl(std::string &command_line, CommandReturnObject &result)
CommandObject::CommandMap m_command_dict
void SetOpenTranscriptInEditor(bool enable)
void HandleCompletion(CompletionRequest &request)
CommandInterpreterRunResult m_result
bool GetSpaceReplPrompts() const
void ResolveCommand(const char *command_line, CommandReturnObject &result)
bool SetQuitExitCode(int exit_code)
Sets the exit code for the quit command.
CommandInterpreterRunResult RunCommandInterpreter(CommandInterpreterRunOptions &options)
bool HandleCommand(const char *command_line, LazyBool add_to_history, const ExecutionContext &override_context, CommandReturnObject &result)
bool DidProcessStopAbnormally() const
CommandObject::CommandMap m_user_dict
std::optional< int > m_quit_exit_code
ExecutionContext GetExecutionContext() const
const CommandObject::CommandMap & GetUserCommands() const
CommandObject * GetUserCommandObject(llvm::StringRef cmd, StringList *matches=nullptr, StringList *descriptions=nullptr) const
void SourceInitFileGlobal(CommandReturnObject &result)
@ eBroadcastBitQuitCommandReceived
@ eBroadcastBitResetPrompt
@ eBroadcastBitThreadShouldExit
bool GetAliasFullName(llvm::StringRef cmd, std::string &full_name) const
CommandObjectMultiword * VerifyUserMultiwordCmdPath(Args &path, bool leaf_is_command, Status &result)
Look up the command pointed to by path encoded in the arguments of the incoming command object.
bool GetEchoCommentCommands() const
bool WasInterrupted() const
void HandleCompletionMatches(CompletionRequest &request)
Status AddUserCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp, bool can_replace)
bool AddCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp, bool can_replace)
void PrintCommandOutput(IOHandler &io_handler, llvm::StringRef str, bool is_stdout)
int m_iohandler_nesting_level
bool GetOpenTranscriptInEditor() const
bool AliasExists(llvm::StringRef cmd) const
Determine whether an alias command with this name exists.
bool GetExpandRegexAliases() const
int GetOptionArgumentPosition(const char *in_string)
Picks the number out of a string of the form "%NNN", otherwise return 0.
bool HasUserMultiwordCommands() const
void StartHandlingCommand()
void GetHelp(CommandReturnObject &result, uint32_t types=eCommandTypesAllThem)
bool CommandExists(llvm::StringRef cmd) const
Determine whether a root level, built-in command with this name exists.
bool GetPromptOnQuit() const
std::string m_repeat_command
const char * GetCommandPrefix()
bool SaveTranscript(CommandReturnObject &result, std::optional< std::string > output_file=std::nullopt)
Save the current debugger session transcript to a file on disk.
int GetQuitExitCode(bool &exited) const
Returns the exit code that the user has specified when running the 'quit' command.
lldb::PlatformSP GetPlatform(bool prefer_target_platform)
bool GetRequireCommandOverwrite() const
void RestoreExecutionContext()
void GetPythonCommandsFromIOHandler(const char *prompt, IOHandlerDelegate &delegate, void *baton=nullptr)
lldb::CommandObjectSP GetCommandSPExact(llvm::StringRef cmd, bool include_aliases=false) const
CommandInterpreter(Debugger &debugger, bool synchronous_execution)
const CommandAlias * GetAlias(llvm::StringRef alias_name) const
void FinishHandlingCommand()
bool RemoveUser(llvm::StringRef alias_name)
void GetLLDBCommandsFromIOHandler(const char *prompt, IOHandlerDelegate &delegate, void *baton=nullptr)
lldb::CommandObjectSP GetCommandSP(llvm::StringRef cmd, bool include_aliases=true, bool exact=true, StringList *matches=nullptr, StringList *descriptions=nullptr) const
void OutputHelpText(Stream &stream, llvm::StringRef command_word, llvm::StringRef separator, llvm::StringRef help_text, uint32_t max_word_len)
CommandObject * GetCommandObjectForCommand(llvm::StringRef &command_line)
static const char * g_need_argument
bool m_skip_app_init_files
void SetSynchronous(bool value)
uint32_t m_command_source_depth
Status PreprocessToken(std::string &token)
bool RemoveUserMultiword(llvm::StringRef multiword_name)
bool GetSaveSessionOnQuit() const
FileSpec GetSaveSessionDirectory() const
bool UserCommandExists(llvm::StringRef cmd) const
Determine whether a root-level user command with this name exists.
bool GetRepeatPreviousCommand() const
lldb::IOHandlerSP GetIOHandler(bool force_create=false, CommandInterpreterRunOptions *options=nullptr)
bool HasUserCommands() const
const CommandObject::CommandMap & GetUserMultiwordCommands() const
void BuildAliasCommandArgs(CommandObject *alias_cmd_obj, const char *alias_name, Args &cmd_args, std::string &raw_input_string, CommandReturnObject &result)
std::vector< uint32_t > m_command_source_flags
CommandHistory m_command_history
CommandObject * BuildAliasResult(llvm::StringRef alias_name, std::string &raw_input_string, std::string &alias_result, CommandReturnObject &result)
void OverrideExecutionContext(const ExecutionContext &override_context)
bool SetBatchCommandMode(bool value)
const char * ProcessEmbeddedScriptCommands(const char *arg)
void AllowExitCodeOnQuit(bool allow)
Specify if the command interpreter should allow that the user can specify a custom exit code when cal...
CommandObject::CommandMap m_user_mw_dict
bool m_synchronous_execution
StreamString m_transcript_stream
Turn on settings interpreter.save-transcript for LLDB to populate this stream.
void HandleCommandsFromFile(FileSpec &file, const ExecutionContext &context, const CommandInterpreterRunOptions &options, CommandReturnObject &result)
Execute a list of commands from a file.
void SourceInitFileCwd(CommandReturnObject &result)
void SetSaveSessionOnQuit(bool enable)
static const char * g_argument
std::vector< FileSpec > m_command_source_dirs
A stack of directory paths.
void HandleCommands(const StringList &commands, const ExecutionContext &context, const CommandInterpreterRunOptions &options, CommandReturnObject &result)
Execute a list of commands in sequence.
void SetSaveTranscript(bool enable)
FileSpec GetCurrentSourceDir()
void SetEchoCommentCommands(bool enable)
StructuredData::Array m_transcript
Contains a list of handled commands and their details.
bool RemoveCommand(llvm::StringRef cmd, bool force=false)
Remove a command if it is removable (python or regex command).
const StructuredData::Array & GetTranscript() const
const CommandObject::CommandMap & GetAliases() const
bool GetEchoCommands() const
Implements dwim-print, a printing command that chooses the most direct, efficient,...
lldb::CommandObjectSP GetSubcommandSPExact(llvm::StringRef sub_cmd) override
CommandObjectMultiword * GetAsMultiwordCommand() override
virtual bool WantsRawCommandString()=0
void SetOriginalCommandString(std::string s)
Set the command input as it appeared in the terminal.
llvm::StringRef GetCommandName() const
bool HelpTextContainsWord(llvm::StringRef search_word, bool search_short_help=true, bool search_long_help=true, bool search_syntax=true, bool search_options=true)
virtual bool IsMultiwordObject()
virtual void Execute(const char *args_string, CommandReturnObject &result)=0
std::map< std::string, lldb::CommandObjectSP, std::less<> > CommandMap
virtual std::optional< std::string > GetRepeatCommand(Args ¤t_command_args, uint32_t index)
Get the command that appropriate for a "repeat" of the current command.
virtual CommandObject * GetSubcommandObject(llvm::StringRef sub_cmd, StringList *matches=nullptr)
virtual CommandObjectMultiword * GetAsMultiwordCommand()
virtual Options * GetOptions()
void SetSyntax(llvm::StringRef str)
virtual void HandleCompletion(CompletionRequest &request)
This default version handles calling option argument completions and then calls HandleArgumentComplet...
virtual llvm::StringRef GetHelp()
void AppendErrorWithFormatv(const char *format, Args &&... args)
void AppendMessage(llvm::StringRef in_string)
bool GetInteractive() const
void void AppendError(llvm::StringRef in_string)
lldb::StreamSP GetImmediateOutputStream()
bool GetDidChangeProcessState() const
void SetSuppressImmediateOutput(bool b)
void SetInteractive(bool b)
void AppendRawError(llvm::StringRef in_string)
void SetStatus(lldb::ReturnStatus status)
std::string GetErrorString(bool with_diagnostics=true)
Return the errors as a string.
void void AppendMessageWithFormatv(const char *format, Args &&... args)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void AppendMessageWithFormat(const char *format,...) __attribute__((format(printf
lldb::StreamSP GetImmediateErrorStream()
void SetDiagnosticIndent(std::optional< uint16_t > indent)
lldb::ReturnStatus GetStatus() const
Stream & GetOutputStream()
llvm::StringRef GetOutputString()
"lldb/Utility/ArgCompletionRequest.h"
void AddCompletion(llvm::StringRef completion, llvm::StringRef description="", CompletionMode mode=CompletionMode::Normal)
Adds a possible completion string.
void AddCompletions(const StringList &completions)
Adds multiple possible completion strings.
const Args & GetParsedLine() const
void ShiftArguments()
Drops the first argument from the argument list.
void AppendEmptyArgument()
Adds an empty argument at the end of the argument list and moves the cursor to this new argument.
size_t GetCursorIndex() const
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
A class to manage flag bits.
ExecutionContext GetSelectedExecutionContext()
bool StartEventHandlerThread()
Manually start the global event handler thread.
void StopEventHandlerThread()
Manually stop the debugger's default event handler.
void SetAsyncExecution(bool async)
HostThread SetIOHandlerThread(HostThread &new_thread)
lldb::FileSP GetInputFileSP()
bool GetShowInlineDiagnostics() const
bool StartIOHandlerThread()
bool IsTopIOHandler(const lldb::IOHandlerSP &reader_sp)
bool IsIOHandlerThreadCurrentThread() const
uint64_t GetTerminalWidth() const
const char * GetIOHandlerCommandPrefix()
void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
Run the given IO handler and return immediately.
lldb::StreamFileSP GetErrorStreamSP()
bool GetAutoConfirm() const
PlatformList & GetPlatformList()
Target & GetDummyTarget()
void RunIOHandlerSync(const lldb::IOHandlerSP &reader_sp)
Run the given IO handler and block until it's complete.
lldb::StreamFileSP GetOutputStreamSP()
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
llvm::StringRef GetExternalEditor() const
llvm::StringRef GetPrompt() const
void FlushProcessOutput(Process &process, bool flush_stdout, bool flush_stderr)
Force flushing the process's pending stdout and stderr to the debugger's asynchronous stdout and stde...
A class that measures elapsed time in an exception safe way.
void SetUnwindOnError(bool unwind=false)
void SetKeepInMemory(bool keep=true)
void SetCoerceToId(bool coerce=true)
void SetTryAllThreads(bool try_others=true)
void SetTimeout(const Timeout< std::micro > &timeout)
void SetIgnoreBreakpoints(bool ignore=false)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
Target * GetTargetPtr() const
Returns a pointer to the target object.
bool HasTargetScope() const
Returns true the ExecutionContext object contains a valid target.
Process * GetProcessPtr() const
Returns a pointer to the process object.
void AppendPathComponent(llvm::StringRef component)
const ConstString & GetFilename() const
Filename string const get accessor.
void MakeAbsolute(const FileSpec &dir)
Make the FileSpec absolute by treating it relative to dir.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
FileSpec CopyByRemovingLastPathComponent() const
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
bool GetHomeDirectory(llvm::SmallVectorImpl< char > &path) const
Get the user home directory.
int Open(const char *path, int flags, int mode=0600)
Wraps ::open in a platform-independent way.
static FileSystem & Instance()
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
bool Test(ValueType bit) const
Test a single flag bit.
static lldb::thread_t GetCurrentThread()
Get the thread token (the one returned by ThreadCreate when the thread was created) for the calling t...
static bool IsInteractiveGraphicSession()
Check if we're running in an interactive graphical session.
static llvm::Error OpenFileInExternalEditor(llvm::StringRef editor, const FileSpec &file_spec, uint32_t line_no)
A delegate class for use with IOHandler subclasses.
lldb::StreamFileSP GetErrorStreamFileSP()
virtual const char * GetPrompt()
std::recursive_mutex & GetOutputMutex()
lldb::StreamFileSP GetOutputStreamFileSP()
bool GetIsInteractive()
Check if the input is being supplied interactively by a user.
static LanguageSet GetLanguagesSupportingREPLs()
static const char * GetNameForLanguageType(lldb::LanguageType language)
A command line option parsing protocol class.
bool SupportsLongOption(const char *long_option)
A plug-in interface definition class for debugging a process.
lldb::StateType GetState()
Get accessor for the current process state.
Status Halt(bool clear_thread_plans=false, bool use_run_lock=true)
Halts a running process.
lldb::OptionValuePropertiesSP m_collection_sp
bool SetPropertyAtIndex(uint32_t idx, T t, const ExecutionContext *exe_ctx=nullptr) const
void GetValue(Stream &s, bool show_type) const
void Clear()
Clear the object state.
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t EOL()
Output and End of Line character to the stream.
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
void IndentMore(unsigned amount=2)
Increment the current indentation level.
void AppendString(const std::string &s)
const char * GetStringAtIndex(size_t idx) const
void DeleteStringAtIndex(size_t id)
void AddItem(const ObjectSP &item)
std::shared_ptr< Dictionary > DictionarySP
LoadCWDlldbinitFile GetLoadCWDlldbinitFile() const
static TargetProperties & GetGlobalProperties()
lldb::PlatformSP GetPlatform()
lldb::ExpressionResults EvaluateExpression(llvm::StringRef expression, ExecutionContextScope *exe_scope, lldb::ValueObjectSP &result_valobj_sp, const EvaluateExpressionOptions &options=EvaluateExpressionOptions(), std::string *fixed_expression=nullptr, ValueObject *ctx_obj=nullptr)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
size_t FindLongestCommandWord(std::map< std::string, ValueType, std::less<> > &dict)
std::shared_ptr< OptionArgVector > OptionArgVectorSP
bool StateIsRunningState(lldb::StateType state)
Check if a state represents a state where the process or thread is running.
int AddNamesMatchingPartialString(const std::map< std::string, ValueType, std::less<> > &in_map, llvm::StringRef cmd_str, StringList &matches, StringList *descriptions=nullptr)
@ RewriteLine
The full line has been rewritten by the completion.
const char * toString(AppleArm64ExceptionClass EC)
std::vector< std::tuple< std::string, int, std::string > > OptionArgVector
std::shared_ptr< lldb_private::OptionValueProperties > OptionValuePropertiesSP
std::shared_ptr< lldb_private::IOHandler > IOHandlerSP
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::unique_ptr< lldb_private::File > FileUP
@ eCommandInterpreterResultInferiorCrash
Stopped because the corresponding option was set and the inferior crashed.
@ eCommandInterpreterResultSuccess
Command interpreter finished successfully.
@ eCommandInterpreterResultCommandError
Stopped because the corresponding option was set and a command returned an error.
@ eCommandInterpreterResultQuitRequested
Stopped because quit was requested.
std::shared_ptr< lldb_private::UnixSignals > UnixSignalsSP
std::shared_ptr< lldb_private::Platform > PlatformSP
StateType
Process and Thread States.
@ eStateStopped
Process or thread is stopped and can be examined.
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
ExpressionResults
The results of expression evaluation.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Event > EventSP
@ eReturnStatusSuccessContinuingResult
@ eReturnStatusSuccessContinuingNoResult
@ eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishNoResult
std::shared_ptr< lldb_private::StreamFile > StreamFileSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
StopReason
Thread stop reasons.
@ eStopReasonInstrumentation
@ eStopReasonInterrupt
Thread requested interrupt.
@ eStopReasonProcessorTrace
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::File > FileSP
const char * c_str() const
llvm::StringRef ref() const
char GetQuoteChar() const
A SmallBitVector that represents a set of source languages (lldb::LanguageType).
std::optional< lldb::LanguageType > GetSingularLanguage()
If the set contains a single language only, return it.