63#include "lldb/Host/Config.h"
65#if LLDB_ENABLE_LIBEDIT
88#include "llvm/ADT/STLExtras.h"
89#include "llvm/ADT/ScopeExit.h"
90#include "llvm/ADT/SmallString.h"
91#include "llvm/Support/FormatAdapters.h"
92#include "llvm/Support/Path.h"
93#include "llvm/Support/PrettyStackTrace.h"
94#include "llvm/Support/ScopedPrinter.h"
95#include "llvm/Telemetry/Telemetry.h"
98#include <TargetConditionals.h>
107 "There is a .lldbinit file in the current directory which is not being "
109 "To silence this warning without sourcing in the local .lldbinit,\n"
110 "add the following to the lldbinit file in your home directory:\n"
111 " settings set target.load-cwd-lldbinit false\n"
112 "To allow lldb to source .lldbinit files in the current working "
114 "set the value of this variable to true. Only do so if you understand "
116 "accept the security risk.";
122#define LLDB_PROPERTIES_interpreter
123#include "InterpreterProperties.inc"
126#define LLDB_PROPERTIES_interpreter
127#include "InterpreterPropertiesEnum.inc"
131 static constexpr llvm::StringLiteral class_name(
"lldb.commandInterpreter");
136 bool synchronous_execution)
155 const uint32_t idx = ePropertyExpandRegexAliases;
157 idx, g_interpreter_properties[idx].default_uint_value != 0);
161 const uint32_t idx = ePropertyPromptOnQuit;
163 idx, g_interpreter_properties[idx].default_uint_value != 0);
167 const uint32_t idx = ePropertyPromptOnQuit;
172 const uint32_t idx = ePropertySaveTranscript;
174 idx, g_interpreter_properties[idx].default_uint_value != 0);
178 const uint32_t idx = ePropertySaveTranscript;
183 const uint32_t idx = ePropertySaveSessionOnQuit;
185 idx, g_interpreter_properties[idx].default_uint_value != 0);
189 const uint32_t idx = ePropertySaveSessionOnQuit;
194 const uint32_t idx = ePropertyOpenTranscriptInEditor;
196 idx, g_interpreter_properties[idx].default_uint_value != 0);
200 const uint32_t idx = ePropertyOpenTranscriptInEditor;
205 const uint32_t idx = ePropertySaveSessionDirectory;
210 const uint32_t idx = ePropertySaveSessionDirectory;
215 const uint32_t idx = ePropertyEchoCommands;
217 idx, g_interpreter_properties[idx].default_uint_value != 0);
221 const uint32_t idx = ePropertyEchoCommands;
226 const uint32_t idx = ePropertyEchoCommentCommands;
228 idx, g_interpreter_properties[idx].default_uint_value != 0);
232 const uint32_t idx = ePropertyEchoCommentCommands;
258 std::string command = command_line;
266 const uint32_t idx = ePropertyStopCmdSourceOnError;
268 idx, g_interpreter_properties[idx].default_uint_value != 0);
272 const uint32_t idx = ePropertySpaceReplPrompts;
274 idx, g_interpreter_properties[idx].default_uint_value != 0);
278 const uint32_t idx = ePropertyRepeatPreviousCommand;
280 idx, g_interpreter_properties[idx].default_uint_value != 0);
284 const uint32_t idx = ePropertyRequireCommandOverwrite;
286 idx, g_interpreter_properties[idx].default_uint_value != 0);
349 "sif", cmd_obj_sp,
"--end-linenumber block --step-in-target %1");
351 sif_alias->
SetHelp(
"Step through the current block, stopping if you step "
352 "directly into a function whose name matches the "
353 "TargetFunctionName.");
354 sif_alias->
SetSyntax(
"sif <TargetFunctionName>");
435 alias_arguments_vector_sp = std::make_shared<OptionArgVector>();
441 if (
auto *po =
AddAlias(
"po", cmd_obj_sp,
"-O --")) {
442 po->SetHelp(
"Evaluate an expression on the current thread. Displays any "
443 "returned value with formatting "
444 "controlled by the type's author.");
455 AddAlias(
"parray", cmd_obj_sp,
"--element-count %1 --");
458 "parray <COUNT> <EXPRESSION> -- lldb will evaluate EXPRESSION "
459 "to get a typed-pointer-to-an-array in memory, and will display "
460 "COUNT elements of that type from the array.");
464 "poarray", cmd_obj_sp,
"--object-description --element-count %1 --");
467 "poarray <COUNT> <EXPRESSION> -- lldb will "
468 "evaluate EXPRESSION to get the address of an array of COUNT "
469 "objects in memory, and will call po on them.");
478 shell_alias->
SetHelp(
"Run a shell command on the host.");
480 shell_alias->
SetSyntax(
"shell <shell-command>");
491 alias_arguments_vector_sp = std::make_shared<OptionArgVector>();
492#if defined(__APPLE__)
497 AddAlias(
"r", cmd_obj_sp,
"--shell-expand-args true --");
498 AddAlias(
"run", cmd_obj_sp,
"--shell-expand-args true --");
502 defaultshell.
Printf(
"--shell=%s --",
503 HostInfo::GetDefaultShell().GetPath().c_str());
516 AddAlias(
"rbreak", cmd_obj_sp,
"--func-regex %1");
523 AddAlias(
"vo", cmd_obj_sp,
"--object-description");
562#define REGISTER_COMMAND_OBJECT(NAME, CLASS) \
563 m_command_dict[NAME] = std::make_shared<CLASS>(*this);
600 const char *break_regexes[][2] = {
601 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
602 "breakpoint set --file '%1' --line %2 --column %3"},
603 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
604 "breakpoint set --file '%1' --line %2"},
605 {
"^/([^/]+)/$",
"breakpoint set --source-pattern-regexp '%1'"},
606 {
"^([[:digit:]]+)[[:space:]]*$",
"breakpoint set --line %1"},
607 {
"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
"breakpoint set --address %1"},
608 {
"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$",
609 "breakpoint set --name '%1'"},
610 {
"^(-.*)$",
"breakpoint set %1"},
611 {
"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$",
612 "breakpoint set --name '%2' --shlib '%1'"},
613 {
"^\\&(.*[^[:space:]])[[:space:]]*$",
614 "breakpoint set --name '%1' --skip-prologue=0"},
615 {
"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$",
616 "breakpoint set --name '%1'"}};
619 size_t num_regexes = std::size(break_regexes);
621 std::unique_ptr<CommandObjectRegexCommand> break_regex_cmd_up(
623 *
this,
"_regexp-break",
624 "Set a breakpoint using one of several shorthand formats, or list "
625 "the existing breakpoints if no arguments are provided.",
627 "_regexp-break <filename>:<linenum>:<colnum>\n"
628 " main.c:12:21 // Break at line 12 and column "
630 "_regexp-break <filename>:<linenum>\n"
631 " main.c:12 // Break at line 12 of "
633 "_regexp-break <linenum>\n"
634 " 12 // Break at line 12 of current "
636 "_regexp-break 0x<address>\n"
637 " 0x1234000 // Break at address "
639 "_regexp-break <name>\n"
640 " main // Break in 'main' after the "
642 "_regexp-break &<name>\n"
643 " &main // Break at first instruction "
645 "_regexp-break <module>`<name>\n"
646 " libc.so`malloc // Break in 'malloc' from "
648 "_regexp-break /<source-regex>/\n"
649 " /break here/ // Break on source lines in "
651 " // containing text 'break "
654 " // List the existing "
658 if (break_regex_cmd_up) {
660 for (
size_t i = 0; i < num_regexes; i++) {
661 success = break_regex_cmd_up->AddRegexCommand(break_regexes[i][0],
662 break_regexes[i][1]);
667 break_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
671 m_command_dict[std::string(break_regex_cmd_sp->GetCommandName())] =
680 const char *break_add_regexes[][2] = {
681 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
682 "breakpoint add file --file '%1' --line %2 --column %3"},
683 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
684 "breakpoint add file --file '%1' --line %2"},
685 {
"^/([^/]+)/$",
"breakpoint add pattern -- %1"},
686 {
"^([[:digit:]]+)[[:space:]]*$",
687 "breakpoint add file --line %1"},
688 {
"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
689 "breakpoint add address %1"},
690 {
"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$",
691 "breakpoint add name '%1'"},
693 "breakpoint add name '%1'"},
694 {
"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$",
695 "breakpoint add name '%2' --shlib '%1'"},
696 {
"^\\&(.*[^[:space:]])[[:space:]]*$",
697 "breakpoint add name '%1' --skip-prologue=0"},
698 {
"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$",
699 "breakpoint add name '%1'"}};
702 size_t num_add_regexes = std::size(break_add_regexes);
704 std::unique_ptr<CommandObjectRegexCommand> break_add_regex_cmd_up(
706 *
this,
"_regexp-break-add",
707 "Set a breakpoint using one of several shorthand formats, or list "
708 "the existing breakpoints if no arguments are provided.",
710 "_regexp-break-add <filename>:<linenum>:<colnum>\n"
711 " main.c:12:21 // Break at line 12 and column "
713 "_regexp-break-add <filename>:<linenum>\n"
714 " main.c:12 // Break at line 12 of "
716 "_regexp-break-add <linenum>\n"
717 " 12 // Break at line 12 of current "
719 "_regexp-break-add 0x<address>\n"
720 " 0x1234000 // Break at address "
722 "_regexp-break-add <name>\n"
723 " main // Break in 'main' after the "
725 "_regexp-break-add &<name>\n"
726 " &main // Break at first instruction "
728 "_regexp-break-add <module>`<name>\n"
729 " libc.so`malloc // Break in 'malloc' from "
731 "_regexp-break-add /<source-regex>/\n"
732 " /break here/ // Break on source lines in "
734 " // containing text 'break "
736 "_regexp-break-add\n"
737 " // List the existing "
741 if (break_add_regex_cmd_up) {
743 for (
size_t i = 0; i < num_add_regexes; i++) {
744 success = break_add_regex_cmd_up->AddRegexCommand(
745 break_add_regexes[i][0], break_add_regexes[i][1]);
750 break_add_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
753 CommandObjectSP break_add_regex_cmd_sp(break_add_regex_cmd_up.release());
754 m_command_dict[std::string(break_add_regex_cmd_sp->GetCommandName())] =
755 break_add_regex_cmd_sp;
759 std::unique_ptr<CommandObjectRegexCommand> tbreak_regex_cmd_up(
761 *
this,
"_regexp-tbreak",
762 "Set a one-shot breakpoint using one of several shorthand formats.",
764 "_regexp-break <filename>:<linenum>:<colnum>\n"
765 " main.c:12:21 // Break at line 12 and column "
767 "_regexp-break <filename>:<linenum>\n"
768 " main.c:12 // Break at line 12 of "
770 "_regexp-break <linenum>\n"
771 " 12 // Break at line 12 of current "
773 "_regexp-break 0x<address>\n"
774 " 0x1234000 // Break at address "
776 "_regexp-break <name>\n"
777 " main // Break in 'main' after the "
779 "_regexp-break &<name>\n"
780 " &main // Break at first instruction "
782 "_regexp-break <module>`<name>\n"
783 " libc.so`malloc // Break in 'malloc' from "
785 "_regexp-break /<source-regex>/\n"
786 " /break here/ // Break on source lines in "
788 " // containing text 'break "
792 if (tbreak_regex_cmd_up) {
794 for (
size_t i = 0; i < num_regexes; i++) {
795 std::string command = break_regexes[i][1];
798 tbreak_regex_cmd_up->AddRegexCommand(break_regexes[i][0], command);
803 tbreak_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
807 m_command_dict[std::string(tbreak_regex_cmd_sp->GetCommandName())] =
812 std::unique_ptr<CommandObjectRegexCommand> attach_regex_cmd_up(
814 *
this,
"_regexp-attach",
"Attach to process by ID or name.",
815 "_regexp-attach <pid> | <process-name>", 0,
false));
816 if (attach_regex_cmd_up) {
817 if (attach_regex_cmd_up->AddRegexCommand(
"^([0-9]+)[[:space:]]*$",
818 "process attach --pid %1") &&
819 attach_regex_cmd_up->AddRegexCommand(
820 "^(-.*|.* -.*)$",
"process attach %1") &&
823 attach_regex_cmd_up->AddRegexCommand(
"^(.+)$",
824 "process attach --name '%1'") &&
825 attach_regex_cmd_up->AddRegexCommand(
"^$",
"process attach")) {
827 m_command_dict[std::string(attach_regex_cmd_sp->GetCommandName())] =
832 std::unique_ptr<CommandObjectRegexCommand> down_regex_cmd_up(
834 "Select a newer stack frame. Defaults to "
835 "moving one frame, a numeric argument can "
836 "specify an arbitrary number.",
837 "_regexp-down [<count>]", 0,
false));
838 if (down_regex_cmd_up) {
839 if (down_regex_cmd_up->AddRegexCommand(
"^$",
"frame select -r -1") &&
840 down_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
841 "frame select -r -%1")) {
843 m_command_dict[std::string(down_regex_cmd_sp->GetCommandName())] =
848 std::unique_ptr<CommandObjectRegexCommand> up_regex_cmd_up(
851 "Select an older stack frame. Defaults to moving one "
852 "frame, a numeric argument can specify an arbitrary number.",
853 "_regexp-up [<count>]", 0,
false));
854 if (up_regex_cmd_up) {
855 if (up_regex_cmd_up->AddRegexCommand(
"^$",
"frame select -r 1") &&
856 up_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
"frame select -r %1")) {
863 std::unique_ptr<CommandObjectRegexCommand> display_regex_cmd_up(
865 *
this,
"_regexp-display",
866 "Evaluate an expression at every stop (see 'help target stop-hook'.)",
867 "_regexp-display expression", 0,
false));
868 if (display_regex_cmd_up) {
869 if (display_regex_cmd_up->AddRegexCommand(
870 "^(.+)$",
"target stop-hook add -o \"expr -- %1\"")) {
872 m_command_dict[std::string(display_regex_cmd_sp->GetCommandName())] =
873 display_regex_cmd_sp;
877 std::unique_ptr<CommandObjectRegexCommand> undisplay_regex_cmd_up(
879 "Stop displaying expression at every "
880 "stop (specified by stop-hook index.)",
881 "_regexp-undisplay stop-hook-number", 0,
883 if (undisplay_regex_cmd_up) {
884 if (undisplay_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
885 "target stop-hook delete %1")) {
886 CommandObjectSP undisplay_regex_cmd_sp(undisplay_regex_cmd_up.release());
887 m_command_dict[std::string(undisplay_regex_cmd_sp->GetCommandName())] =
888 undisplay_regex_cmd_sp;
892 std::unique_ptr<CommandObjectRegexCommand> connect_gdb_remote_cmd_up(
895 "Connect to a process via remote GDB server.\n"
896 "If no host is specified, localhost is assumed.\n"
897 "gdb-remote is an abbreviation for 'process connect --plugin "
898 "gdb-remote connect://<hostname>:<port>'\n",
899 "gdb-remote [<hostname>:]<portnum>", 0,
false));
900 if (connect_gdb_remote_cmd_up) {
901 if (connect_gdb_remote_cmd_up->AddRegexCommand(
902 "^([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)$",
903 "process connect --plugin gdb-remote connect://%1:%2") &&
904 connect_gdb_remote_cmd_up->AddRegexCommand(
906 "process connect --plugin gdb-remote connect://localhost:%1")) {
908 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
912 std::unique_ptr<CommandObjectRegexCommand> connect_kdp_remote_cmd_up(
915 "Connect to a process via remote KDP server.\n"
916 "If no UDP port is specified, port 41139 is assumed.\n"
917 "kdp-remote is an abbreviation for 'process connect --plugin "
918 "kdp-remote udp://<hostname>:<port>'\n",
919 "kdp-remote <hostname>[:<portnum>]", 0,
false));
920 if (connect_kdp_remote_cmd_up) {
921 if (connect_kdp_remote_cmd_up->AddRegexCommand(
922 "^([^:]+:[[:digit:]]+)$",
923 "process connect --plugin kdp-remote udp://%1") &&
924 connect_kdp_remote_cmd_up->AddRegexCommand(
925 "^(.+)$",
"process connect --plugin kdp-remote udp://%1:41139")) {
927 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
931 std::unique_ptr<CommandObjectRegexCommand> bt_regex_cmd_up(
934 "Show backtrace of the current thread's call stack. Any numeric "
935 "argument displays at most that many frames. The argument 'all' "
936 "displays all threads. Use 'settings set frame-format' to customize "
937 "the printing of individual frames and 'settings set thread-format' "
938 "to customize the thread header. Frame recognizers may filter the "
939 "list. Use 'thread backtrace -u (--unfiltered)' to see them all.",
940 "bt [<digit> | all]", 0,
false));
941 if (bt_regex_cmd_up) {
946 if (bt_regex_cmd_up->AddRegexCommand(
"^([[:digit:]]+)[[:space:]]*$",
947 "thread backtrace -c %1") &&
948 bt_regex_cmd_up->AddRegexCommand(
"^(-[^[:space:]].*)$",
949 "thread backtrace %1") &&
950 bt_regex_cmd_up->AddRegexCommand(
"^all[[:space:]]*$",
951 "thread backtrace all") &&
952 bt_regex_cmd_up->AddRegexCommand(
"^[[:space:]]*$",
953 "thread backtrace")) {
955 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
959 std::unique_ptr<CommandObjectRegexCommand> list_regex_cmd_up(
961 *
this,
"_regexp-list",
962 "List relevant source code using one of several shorthand formats.",
964 "_regexp-list <file>:<line> // List around specific file/line\n"
965 "_regexp-list <line> // List current file around specified "
967 "_regexp-list <function-name> // List specified function\n"
968 "_regexp-list 0x<address> // List around specified address\n"
969 "_regexp-list -[<count>] // List previous <count> lines\n"
970 "_regexp-list // List subsequent lines",
972 if (list_regex_cmd_up) {
973 if (list_regex_cmd_up->AddRegexCommand(
"^([0-9]+)[[:space:]]*$",
974 "source list --line %1") &&
975 list_regex_cmd_up->AddRegexCommand(
976 "^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]"
978 "source list --file '%1' --line %2") &&
979 list_regex_cmd_up->AddRegexCommand(
980 "^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
981 "source list --address %1") &&
982 list_regex_cmd_up->AddRegexCommand(
"^-[[:space:]]*$",
983 "source list --reverse") &&
984 list_regex_cmd_up->AddRegexCommand(
985 "^-([[:digit:]]+)[[:space:]]*$",
986 "source list --reverse --count %1") &&
987 list_regex_cmd_up->AddRegexCommand(
"^(.+)$",
988 "source list --name \"%1\"") &&
989 list_regex_cmd_up->AddRegexCommand(
"^$",
"source list")) {
991 m_command_dict[std::string(list_regex_cmd_sp->GetCommandName())] =
996 std::unique_ptr<CommandObjectRegexCommand> env_regex_cmd_up(
998 *
this,
"_regexp-env",
999 "Shorthand for viewing and setting environment variables.",
1001 "_regexp-env // Show environment\n"
1002 "_regexp-env <name>=<value> // Set an environment variable",
1004 if (env_regex_cmd_up) {
1005 if (env_regex_cmd_up->AddRegexCommand(
"^$",
1006 "settings show target.env-vars") &&
1007 env_regex_cmd_up->AddRegexCommand(
"^([A-Za-z_][A-Za-z_0-9]*=.*)$",
1008 "settings set target.env-vars %1")) {
1010 m_command_dict[std::string(env_regex_cmd_sp->GetCommandName())] =
1015 std::unique_ptr<CommandObjectRegexCommand> jump_regex_cmd_up(
1017 *
this,
"_regexp-jump",
"Set the program counter to a new address.",
1019 "_regexp-jump <line>\n"
1020 "_regexp-jump +<line-offset> | -<line-offset>\n"
1021 "_regexp-jump <file>:<line>\n"
1022 "_regexp-jump *<addr>\n",
1024 if (jump_regex_cmd_up) {
1025 if (jump_regex_cmd_up->AddRegexCommand(
"^\\*(.*)$",
1026 "thread jump --addr %1") &&
1027 jump_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
1028 "thread jump --line %1") &&
1029 jump_regex_cmd_up->AddRegexCommand(
"^([^:]+):([0-9]+)$",
1030 "thread jump --file %1 --line %2") &&
1031 jump_regex_cmd_up->AddRegexCommand(
"^([+\\-][0-9]+)$",
1032 "thread jump --by %1")) {
1034 m_command_dict[std::string(jump_regex_cmd_sp->GetCommandName())] =
1039 std::shared_ptr<CommandObjectRegexCommand> step_regex_cmd_sp(
1041 *
this,
"_regexp-step",
1042 "Single step, optionally to a specific function.",
1044 "_regexp-step // Single step\n"
1045 "_regexp-step <function-name> // Step into the named function\n",
1047 if (step_regex_cmd_sp) {
1048 if (step_regex_cmd_sp->AddRegexCommand(
"^[[:space:]]*$",
1049 "thread step-in") &&
1050 step_regex_cmd_sp->AddRegexCommand(
"^[[:space:]]*(-.+)$",
1051 "thread step-in %1") &&
1052 step_regex_cmd_sp->AddRegexCommand(
1053 "^[[:space:]]*(.+)[[:space:]]*$",
1054 "thread step-in --end-linenumber block --step-in-target %1")) {
1055 m_command_dict[std::string(step_regex_cmd_sp->GetCommandName())] =
1062 const char *cmd_str,
bool include_aliases,
StringList &matches,
1067 if (include_aliases) {
1080 auto get_multi_or_report_error =
1085 "Path component: '%s' not found", name);
1088 if (!cmd_sp->IsUserCommand()) {
1090 "Path component: '%s' is not a user "
1096 if (!cmd_as_multi) {
1098 "Path component: '%s' is not a container "
1103 return cmd_as_multi;
1107 if (num_args == 0) {
1112 if (num_args == 1 && leaf_is_command) {
1122 get_multi_or_report_error(cur_cmd_sp, cur_name);
1123 if (cur_as_multi ==
nullptr)
1126 size_t num_path_elements = num_args - (leaf_is_command ? 1 : 0);
1127 for (
size_t cursor = 1; cursor < num_path_elements && cur_as_multi !=
nullptr;
1131 cur_as_multi = get_multi_or_report_error(cur_cmd_sp, cur_name);
1133 return cur_as_multi;
1140 auto frame_language =
1153 auto lang_name =
plugin->GetPluginName();
1155 return language_cmd_sp->GetSubcommandSPExact(lang_name);
1164 std::string cmd = std::string(cmd_str);
1169 command_sp = pos->second;
1175 command_sp = alias_pos->second;
1181 command_sp = pos->second;
1187 command_sp = pos->second;
1190 if (!exact && !command_sp) {
1197 if (matches ==
nullptr)
1198 matches = &local_matches;
1200 unsigned int num_cmd_matches = 0;
1201 unsigned int num_alias_matches = 0;
1202 unsigned int num_user_matches = 0;
1203 unsigned int num_user_mw_matches = 0;
1211 *matches, descriptions);
1214 if (num_cmd_matches == 1) {
1218 real_match_sp = pos->second;
1223 *matches, descriptions);
1226 if (num_alias_matches == 1) {
1230 alias_match_sp = alias_pos->second;
1235 *matches, descriptions);
1238 if (num_user_matches == 1) {
1244 user_match_sp = pos->second;
1252 if (num_user_mw_matches == 1) {
1258 user_mw_match_sp = pos->second;
1264 if (num_user_matches + num_user_mw_matches + num_cmd_matches +
1265 num_alias_matches ==
1267 if (num_cmd_matches)
1268 return real_match_sp;
1269 else if (num_alias_matches)
1270 return alias_match_sp;
1271 else if (num_user_mw_matches)
1272 return user_mw_match_sp;
1274 return user_match_sp;
1285 command_sp = lang_subcmd_sp->GetSubcommandSPExact(cmd_str);
1288 if (!command_sp && !exact && lang_subcmd) {
1291 cmd_str, lang_matches, descriptions);
1294 if (lang_matches.
GetSize() == 1) {
1296 auto pos = lang_dict.find(lang_matches[0]);
1297 if (pos != lang_dict.end())
1303 if (matches && command_sp) {
1316 lldbassert((
this == &cmd_sp->GetCommandInterpreter()) &&
1317 "tried to add a CommandObject from a different interpreter");
1322 cmd_sp->SetIsUserCommand(
false);
1324 std::string name_sstr(name);
1327 if (!can_replace || !name_iter->second->IsRemovable())
1329 name_iter->second = cmd_sp;
1341 lldbassert((
this == &cmd_sp->GetCommandInterpreter()) &&
1342 "tried to add a CommandObject from a different interpreter");
1345 "can't use the empty string for a command name");
1357 "user command \"{0}\" already exists and force replace was not set "
1358 "by --overwrite or 'settings set interpreter.require-overwrite "
1363 if (cmd_sp->IsMultiwordObject()) {
1366 "can't replace explicitly non-removable multi-word command");
1370 if (!
m_user_dict[std::string(name)]->IsRemovable()) {
1372 "can't replace explicitly non-removable command");
1378 cmd_sp->SetIsUserCommand(
true);
1380 if (cmd_sp->IsMultiwordObject())
1389 bool include_aliases)
const {
1391 Args cmd_words(cmd_str);
1393 if (cmd_str.empty())
1410 for (
size_t i = 1; i < end; ++i) {
1411 if (!cmd_obj_sp->IsMultiwordObject()) {
1436 matches, descriptions)
1442 std::string cmd_str(cmd);
1444 auto found_elem = map.find(cmd);
1445 if (found_elem == map.end())
1468 StringList *matches_ptr = matches ? matches : &tmp_list;
1480 auto found_elem = map.find(cmd);
1481 if (found_elem == map.end())
1503 StringList *matches_ptr = matches ? matches : &tmp_list;
1514 std::string &full_name)
const {
1517 full_name.assign(std::string(cmd));
1521 size_t num_alias_matches;
1524 if (num_alias_matches == 1) {
1527 const bool include_aliases =
false;
1528 const bool exact =
false;
1530 GetCommandSP(cmd, include_aliases, exact, ®ular_matches));
1531 if (cmd_obj_sp || regular_matches.
GetSize() > 0)
1558 llvm::StringRef args_string) {
1559 if (command_obj_sp.get())
1560 lldbassert((
this == &command_obj_sp->GetCommandInterpreter()) &&
1561 "tried to add a CommandObject from a different interpreter");
1563 std::unique_ptr<CommandAlias> command_alias_up(
1564 new CommandAlias(*
this, command_obj_sp, args_string, alias_name));
1566 if (command_alias_up && command_alias_up->IsValid()) {
1569 return command_alias_up.release();
1587 if (force || pos->second->IsRemovable()) {
1598 CommandObject::CommandMap::iterator pos =
m_user_dict.find(user_name);
1607 CommandObject::CommandMap::iterator pos =
m_user_mw_dict.find(multi_name);
1616 uint32_t cmd_types) {
1617 llvm::StringRef help_prologue(
GetDebugger().GetIOHandlerHelpPrologue());
1618 if (!help_prologue.empty()) {
1623 CommandObject::CommandMap::const_iterator pos;
1632 (pos->first.compare(0, 1,
"_") == 0))
1636 pos->second->GetHelp(), max_len);
1644 "Current command abbreviations "
1645 "(type '%shelp command alias' for more info):\n",
1653 alias_pos->second->GetHelp(), max_len);
1665 pos->second->GetHelp(), max_len);
1672 result.
AppendMessage(
"Current user-defined container commands:");
1677 pos->second->GetHelp(), max_len);
1683 "For more information on any command, type '%shelp <command-name>'.\n",
1688 llvm::StringRef &command_string) {
1694 size_t start = command_string.find_first_not_of(
k_white_space);
1698 if (start != std::string::npos) {
1701 if (end == std::string::npos)
1702 end = command_string.size();
1703 std::string cmd_word =
1704 std::string(command_string.substr(start, end - start));
1706 if (cmd_obj ==
nullptr)
1716 cmd_obj = sub_cmd_obj;
1728 end >= command_string.size())
1731 start = command_string.find_first_not_of(
k_white_space, end);
1737 command_string = command_string.substr(end);
1742 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
1746 if (pos == std::string::npos)
1755 const size_t s_len = s.size();
1757 while (offset < s_len) {
1758 size_t pos = s.find(
"--", offset);
1759 if (pos == std::string::npos)
1762 if (llvm::isSpace(s[pos - 1])) {
1765 if ((pos + 2 >= s_len) || llvm::isSpace(s[pos + 2])) {
1772 return std::string::npos;
1776 std::string &suffix,
char "e_char) {
1781 bool result =
false;
1784 if (!command_string.empty()) {
1785 const char first_char = command_string[0];
1786 if (first_char ==
'\'' || first_char ==
'"') {
1787 quote_char = first_char;
1788 const size_t end_quote_pos = command_string.find(quote_char, 1);
1789 if (end_quote_pos == std::string::npos) {
1790 command.swap(command_string);
1791 command_string.erase();
1793 command.assign(command_string, 1, end_quote_pos - 1);
1794 if (end_quote_pos + 1 < command_string.size())
1795 command_string.erase(0, command_string.find_first_not_of(
1798 command_string.erase();
1801 const size_t first_space_pos =
1803 if (first_space_pos == std::string::npos) {
1804 command.swap(command_string);
1805 command_string.erase();
1807 command.assign(command_string, 0, first_space_pos);
1808 command_string.erase(0, command_string.find_first_not_of(
1815 if (!command.empty()) {
1817 if (command[0] !=
'-' && command[0] !=
'_') {
1819 if (pos > 0 && pos != std::string::npos) {
1820 suffix.assign(command.begin() + pos, command.end());
1830 llvm::StringRef alias_name, std::string &raw_input_string,
1833 Args cmd_args(raw_input_string);
1837 if (!alias_cmd_obj || !alias_cmd_obj->
IsAlias()) {
1838 alias_result.clear();
1839 return alias_cmd_obj;
1841 std::pair<CommandObjectSP, OptionArgVectorSP> desugared =
1844 alias_cmd_obj = desugared.first.get();
1845 std::string alias_name_str = std::string(alias_name);
1848 cmd_args.
Unshift(alias_name_str);
1852 if (!option_arg_vector_sp.get()) {
1853 alias_result = std::string(result_str.
GetString());
1854 return alias_cmd_obj;
1861 for (
const auto &entry : *option_arg_vector) {
1862 std::tie(option, value_type, value) = entry;
1864 result_str.
Printf(
" %s", value.c_str());
1868 result_str.
Printf(
" %s", option.c_str());
1876 result_str.
Printf(
"%s", value.c_str());
1880 "need at least %d arguments to use "
1886 size_t strpos = raw_input_string.find(entry.
c_str());
1888 if (strpos != std::string::npos) {
1889 const size_t start_fudge = quote_char ==
'\0' ? 0 : 1;
1890 const size_t len_fudge = quote_char ==
'\0' ? 0 : 2;
1893 if (strpos < start_fudge) {
1894 result.
AppendError(
"unmatched quote at command beginning");
1897 llvm::StringRef arg_text = entry.
ref();
1898 if (strpos - start_fudge + arg_text.size() + len_fudge >
1899 raw_input_string.size()) {
1900 result.
AppendError(
"unmatched quote at command end");
1903 raw_input_string = raw_input_string.erase(
1904 strpos - start_fudge,
1907 if (quote_char ==
'\0')
1910 result_str.
Printf(
"%c%s%c", quote_char, entry.
c_str(), quote_char);
1914 alias_result = std::string(result_str.
GetString());
1915 return alias_cmd_obj;
1926 size_t start_backtick;
1928 while ((start_backtick = command.find(
'`', pos)) != std::string::npos) {
1933 if (start_backtick > 0 && command[start_backtick - 1] ==
'\\') {
1936 command.erase(start_backtick - 1, 1);
1938 pos = start_backtick;
1942 const size_t expr_content_start = start_backtick + 1;
1943 const size_t end_backtick = command.find(
'`', expr_content_start);
1945 if (end_backtick == std::string::npos) {
1950 if (end_backtick == expr_content_start) {
1952 command.erase(start_backtick, 2);
1956 std::string expr_str(command, expr_content_start,
1957 end_backtick - expr_content_start);
1963 command.erase(start_backtick, end_backtick - start_backtick + 1);
1964 command.insert(start_backtick, std::string(expr_str));
1965 pos = start_backtick + expr_str.size();
1991 expr_str.c_str(), exe_ctx.
GetFramePtr(), expr_result_valobj_sp, options);
1995 if (expr_result_valobj_sp)
1996 expr_result_valobj_sp =
1997 expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable(
1998 expr_result_valobj_sp->GetDynamicValueType(),
true);
1999 if (expr_result_valobj_sp->ResolveValue(scalar)) {
2002 const bool show_type =
false;
2003 scalar.
GetValue(value_strm, show_type);
2004 size_t value_string_size = value_strm.
GetSize();
2005 if (value_string_size) {
2006 expr_str = value_strm.
GetData();
2010 "in a scalar value for the "
2017 "in a scalar value for the "
2028 if (expr_result_valobj_sp)
2029 error = expr_result_valobj_sp->GetError().Clone();
2031 if (
error.Success()) {
2033 "for the expression '" + expr_str +
"'";
2045 bool status =
HandleCommand(command_line, lazy_add_to_history, result);
2053 bool force_repeat_command) {
2058 std::string parsed_command_args;
2062 const bool detailed_command_telemetry =
2068 std::string command_string(command_line);
2069 std::string original_command_string(command_string);
2070 std::string real_original_command_string(command_string);
2076 info->
target_uuid = target->GetExecutableModule() !=
nullptr
2077 ? target->GetExecutableModule()->GetUUID()
2080 if (detailed_command_telemetry)
2087 detailed_command_telemetry, command_id](
2093 llvm::StringRef command_name =
2097 if (std::string error_str = result.
GetErrorString(); !error_str.empty())
2100 if (detailed_command_telemetry)
2101 info->
args = parsed_command_args;
2105 LLDB_LOGF(log,
"Processing command: %s", command_line);
2117 bool add_to_history;
2121 add_to_history = (lazy_add_to_history ==
eLazyBoolYes);
2129 transcript_item = std::make_shared<StructuredData::Dictionary>();
2130 transcript_item->AddStringItem(
"command", command_line);
2131 transcript_item->AddIntegerItem(
2132 "timestampInEpochSeconds",
2133 std::chrono::duration_cast<std::chrono::seconds>(
2134 std::chrono::system_clock::now().time_since_epoch())
2139 bool empty_command =
false;
2140 bool comment_command =
false;
2141 if (command_string.empty())
2142 empty_command =
true;
2144 const char *k_space_characters =
"\t\n\v\f\r ";
2146 size_t non_space = command_string.find_first_not_of(k_space_characters);
2149 if (non_space == std::string::npos)
2150 empty_command =
true;
2152 comment_command =
true;
2154 llvm::StringRef search_str(command_string);
2155 search_str = search_str.drop_front(non_space);
2157 add_to_history =
false;
2158 command_string = std::string(*hist_str);
2159 original_command_string = std::string(*hist_str);
2162 command_string.c_str());
2168 if (empty_command) {
2180 command_string = command_line;
2181 original_command_string = command_line;
2187 add_to_history =
false;
2188 }
else if (comment_command) {
2228 llvm::StringRef command_name =
2230 LLDB_LOGF(log,
"HandleCommand, cmd_obj : '%s'", command_name.str().c_str());
2231 LLDB_LOGF(log,
"HandleCommand, (revised) command_string: '%s'",
2232 command_string.c_str());
2233 const bool wants_raw_input =
2235 LLDB_LOGF(log,
"HandleCommand, wants_raw_input:'%s'",
2236 wants_raw_input ?
"True" :
"False");
2244 if (cmd_obj !=
nullptr) {
2245 bool generate_repeat_command = add_to_history;
2249 generate_repeat_command |= empty_command;
2254 generate_repeat_command |= force_repeat_command;
2255 if (generate_repeat_command) {
2256 Args command_args(command_string);
2257 std::optional<std::string> repeat_command =
2259 if (repeat_command) {
2260 LLDB_LOGF(log,
"Repeat command: %s", repeat_command->data());
2270 const std::size_t actual_cmd_name_len = cmd_obj->
GetCommandName().size();
2271 if (actual_cmd_name_len < command_string.length())
2272 parsed_command_args = command_string.substr(actual_cmd_name_len);
2275 size_t pos = parsed_command_args.find_first_not_of(
k_white_space);
2276 if (pos != 0 && pos != std::string::npos)
2277 parsed_command_args.erase(0, pos);
2280 log,
"HandleCommand, command line after removing command name(s): '%s'",
2281 parsed_command_args.c_str());
2286 if (transcript_item) {
2287 transcript_item->AddStringItem(
"commandName", cmd_obj->
GetCommandName());
2288 transcript_item->AddStringItem(
"commandArguments", parsed_command_args);
2294 pos = real_original_command_string.rfind(parsed_command_args);
2295 std::optional<uint16_t> indent;
2296 if (pos != std::string::npos)
2299 cmd_obj->
Execute(parsed_command_args.c_str(), result);
2302 LLDB_LOGF(log,
"HandleCommand, command %s",
2303 (result.
Succeeded() ?
"succeeded" :
"did not succeed"));
2308 if (transcript_item) {
2313 transcript_item->AddStringItem(
"error", result.
GetErrorString());
2314 transcript_item->AddFloatItem(
"durationInSeconds",
2315 execute_time.
get().count());
2322 bool look_for_subcommand =
false;
2328 bool include_aliases =
true;
2339 &new_matches, &new_descriptions);
2346 look_for_subcommand =
true;
2361 if (command_object) {
2374 if (!first_arg.empty()) {
2379 request.
AddCompletion(*hist_str,
"Previous command history event",
2388std::optional<std::string>
2391 return std::nullopt;
2393 for (
int i = s - 1; i >= 0; --i) {
2395 if (entry.consume_front(line))
2398 return std::nullopt;
2402 EventSP prompt_change_event_sp(
2418 return default_answer;
2455 const char *alias_name,
2457 std::string &raw_input_string,
2465 std::string alias_name_str = alias_name;
2467 cmd_args.
Unshift(alias_name_str);
2473 if (option_arg_vector_sp.get()) {
2474 if (wants_raw_input) {
2478 size_t pos = raw_input_string.find(
" -- ");
2479 if (pos == std::string::npos) {
2481 raw_input_string.insert(0,
" -- ");
2487 std::vector<bool> used(old_size + 1,
false);
2494 for (
const auto &option_entry : *option_arg_vector) {
2495 std::tie(option, value_type, value) = option_entry;
2497 if (!wants_raw_input || (value !=
"--")) {
2521 "need at least %d arguments to use "
2529 if (strpos != std::string::npos) {
2530 raw_input_string = raw_input_string.erase(
2543 for (
auto entry : llvm::enumerate(cmd_args.
entries())) {
2544 if (!used[entry.index()] && !wants_raw_input)
2557 if (wants_raw_input) {
2573 const char *cptr = in_string;
2576 if (cptr[0] ==
'%') {
2580 if (isdigit(cptr[0])) {
2581 const char *start = cptr;
2582 while (isdigit(cptr[0]))
2587 if (cptr[0] ==
'\0')
2588 position = atoi(start);
2596 std::string init_file_name =
".lldbinit";
2597 if (!suffix.empty()) {
2598 init_file_name.append(
"-");
2599 init_file_name.append(suffix.str());
2610 language = *main_repl_language;
2615 std::string init_file_name =
2616 (llvm::Twine(
".lldbinit-") +
2618 llvm::Twine(
"-repl"))
2626 llvm::StringRef s =
".lldbinit";
2627 init_file.assign(s.begin(), s.end());
2659 llvm::SmallString<128> init_file;
2669 switch (should_load) {
2679 if (llvm::sys::path::parent_path(init_file) ==
2680 llvm::sys::path::parent_path(home_init_file.
GetPath())) {
2705 if (init_file.
GetPath().empty())
2709 llvm::StringRef program_name =
2710 HostInfo::GetProgramFileSpec().GetFilename().GetStringRef();
2714 init_file = program_init_file;
2721#ifdef LLDB_GLOBAL_INIT_DIRECTORY
2723 FileSpec init_file(LLDB_GLOBAL_INIT_DIRECTORY);
2737 return prefix ==
nullptr ?
"" : prefix;
2742 if (prefer_target_platform) {
2750 platform_sp =
m_debugger.GetPlatformList().GetSelectedPlatform();
2756 TargetSP target_sp = exe_ctx.GetTargetSP();
2760 ProcessSP process_sp(target_sp->GetProcessSP());
2767 for (
const auto &thread_sp : process_sp->GetThreadList().Threads()) {
2768 StopInfoSP stop_info = thread_sp->GetStopInfo();
2776 const StopReason reason = stop_info->GetStopReason();
2784 const auto stop_signal =
static_cast<int32_t
>(stop_info->GetValue());
2786 if (!signals_sp || !signals_sp->SignalIsValid(stop_signal))
2790 const auto sigint_num = signals_sp->GetSignalNumberFromName(
"SIGINT");
2791 const auto sigstop_num = signals_sp->GetSignalNumberFromName(
"SIGSTOP");
2792 if ((stop_signal != sigint_num) && (stop_signal != sigstop_num))
2813 size_t num_lines = commands.
GetSize();
2819 bool old_async_execution =
m_debugger.GetAsyncExecution();
2825 for (
size_t idx = 0; idx < num_lines; idx++) {
2854 if (!success || !tmp_result.
Succeeded()) {
2856 if (error_msg.empty())
2857 error_msg =
"<unknown error>.\n";
2860 "command #{0}: '{1}' failed with {2}",
2861 (uint64_t)idx, cmd, error_msg);
2862 m_debugger.SetAsyncExecution(old_async_execution);
2867 (uint64_t)idx + 1, cmd, error_msg);
2888 if (idx != num_lines - 1)
2890 "Aborting reading of commands after command #%" PRIu64
2891 ": '%s' continued the target.\n",
2892 (uint64_t)idx + 1, cmd);
2895 " '%s' continued the target.\n",
2896 (uint64_t)idx + 1, cmd);
2899 m_debugger.SetAsyncExecution(old_async_execution);
2908 if (idx != num_lines - 1)
2910 "Aborting reading of commands after command #%" PRIu64
2911 ": '%s' stopped with a signal or exception.\n",
2912 (uint64_t)idx + 1, cmd);
2915 "Command #%" PRIu64
" '%s' stopped with a signal or exception.\n",
2916 (uint64_t)idx + 1, cmd);
2919 m_debugger.SetAsyncExecution(old_async_execution);
2926 m_debugger.SetAsyncExecution(old_async_execution);
2955 "Error reading commands from file %s - file not found.\n",
2960 std::string cmd_file_path = cmd_file.
GetPath();
2961 auto input_file_up =
2963 if (!input_file_up) {
2964 std::string
error = llvm::toString(input_file_up.takeError());
2966 "error: an error occurred read file '{0}': {1}\n", cmd_file_path,
2967 llvm::fmt_consume(input_file_up.takeError()));
2970 FileSP input_file_sp =
FileSP(std::move(input_file_up.get()));
3057 cmd_file_path.c_str());
3073 debugger.
GetPrompt(), llvm::StringRef(),
3103 llvm::StringRef prefix,
3104 llvm::StringRef help_text) {
3105 const uint32_t max_columns =
m_debugger.GetTerminalWidth();
3107 size_t line_width_max = max_columns - prefix.size();
3108 if (line_width_max < 16)
3109 line_width_max = help_text.size() + prefix.size();
3112 bool prefixed_yet =
false;
3114 if (help_text.empty())
3115 help_text =
"No help text";
3116 while (!help_text.empty()) {
3118 if (!prefixed_yet) {
3120 prefixed_yet =
true;
3125 llvm::StringRef this_line = help_text.substr(0, line_width_max);
3128 std::size_t first_newline = this_line.find_first_of(
"\n");
3131 std::size_t last_space = llvm::StringRef::npos;
3132 if (this_line.size() != help_text.size())
3133 last_space = this_line.find_last_of(
" \t");
3136 this_line = this_line.substr(0, std::min(first_newline, last_space));
3141 help_text = help_text.drop_front(this_line.size()).ltrim();
3147 llvm::StringRef word_text,
3148 llvm::StringRef separator,
3149 llvm::StringRef help_text,
3150 size_t max_word_len) {
3152 prefix_stream.
Printf(
" %-*s %*s ", (
int)max_word_len, word_text.data(),
3153 (
int)separator.size(), separator.data());
3158 llvm::StringRef separator,
3159 llvm::StringRef help_text,
3160 uint32_t max_word_len) {
3161 int indent_size = max_word_len + separator.size() + 2;
3166 text_strm.
Printf(
"%-*s ", (
int)max_word_len, word_text.data());
3167 text_strm << separator <<
" " << help_text;
3169 const uint32_t max_columns =
m_debugger.GetTerminalWidth();
3171 llvm::StringRef text = text_strm.
GetString();
3173 uint32_t chars_left = max_columns;
3175 auto nextWordLength = [](llvm::StringRef S) {
3176 size_t pos = S.find(
' ');
3177 return pos == llvm::StringRef::npos ? S.size() : pos;
3180 while (!text.empty()) {
3181 if (text.front() ==
'\n' ||
3182 (text.front() ==
' ' && nextWordLength(text.ltrim(
' ')) > chars_left)) {
3185 chars_left = max_columns - indent_size;
3186 if (text.front() ==
'\n')
3187 text = text.drop_front();
3189 text = text.ltrim(
' ');
3193 text = text.drop_front();
3202 llvm::StringRef search_word,
StringList &commands_found,
3204 for (
const auto &pair : command_map) {
3205 llvm::StringRef command_name = pair.first;
3208 const bool search_short_help =
true;
3209 const bool search_long_help =
false;
3210 const bool search_syntax =
false;
3211 const bool search_options =
false;
3212 if (command_name.contains_insensitive(search_word) ||
3214 search_long_help, search_syntax,
3223 multiword_cmd->GetSubcommandDictionary());
3224 for (
const auto &subcommand_name : subcommands_found) {
3225 std::string qualified_name =
3226 (command_name +
" " + subcommand_name).str();
3236 bool search_builtin_commands,
3237 bool search_user_commands,
3238 bool search_alias_commands,
3239 bool search_user_mw_commands) {
3240 CommandObject::CommandMap::const_iterator pos;
3242 if (search_builtin_commands)
3246 if (search_user_commands)
3250 if (search_user_mw_commands)
3254 if (search_alias_commands)
3277 m_debugger.FlushProcessOutput(*process_sp,
true,
3306 if (!
m_debugger.IsIOHandlerThreadCurrentThread())
3309 bool was_interrupted =
3312 return was_interrupted;
3316 llvm::StringRef str,
3323 bool had_output = !str.empty();
3324 while (!str.empty()) {
3325 llvm::StringRef line;
3326 std::tie(line, str) = str.split(
'\n');
3329 stream_file.
Write(line.data(), line.size());
3330 stream_file.
Write(
"\n", 1);
3337 stream_file.
Printf(
"\n... Interrupted.\n");
3338 stream_file.
Flush();
3342 llvm::StringRef line,
const Flags &io_handler_flags)
const {
3346 llvm::StringRef command = line.trim();
3347 if (command.empty())
3357 std::string &line) {
3363 const bool allow_repeats =
3366 if (!is_interactive && !allow_repeats) {
3375 if (!is_interactive) {
3389 bool pushed_exe_ctx =
false;
3392 pushed_exe_ctx =
true;
3394 llvm::scope_exit finalize([
this, pushed_exe_ctx]() {
3403 if ((result.Succeeded() &&
3408 const bool inline_diagnostics = !result.GetImmediateErrorStream() &&
3410 if (inline_diagnostics) {
3411 unsigned prompt_len =
m_debugger.GetPrompt().size();
3412 if (
auto indent = result.GetDiagnosticIndent()) {
3414 result.GetInlineDiagnosticString(prompt_len + *indent);
3422 if (!result.GetImmediateOutputStream()) {
3423 llvm::StringRef output = result.GetOutputString();
3428 if (!result.GetImmediateErrorStream()) {
3429 std::string
error = result.GetErrorString(!inline_diagnostics);
3437 DefaultPrintCallback(result);
3439 DefaultPrintCallback(result);
3445 switch (result.GetStatus()) {
3459 m_result.IncrementNumberOfErrors();
3474 result.GetDidChangeProcessState() &&
3499 if (script_interpreter) {
3508 if (output_file == std::nullopt || output_file->empty()) {
3509 std::string now = llvm::to_string(std::chrono::system_clock::now());
3510 llvm::replace(now,
' ',
'_');
3512 llvm::replace(now,
':',
'-');
3513 const std::string file_name =
"lldb_session_" + now +
".log";
3518 save_location = HostInfo::GetGlobalTempDir();
3522 output_file = save_location.
GetPath();
3525 auto error_out = [&](llvm::StringRef error_message, std::string description) {
3527 output_file, description);
3529 "Failed to save session's transcripts to {0}!", *output_file);
3540 return error_out(
"Unable to create file",
3541 llvm::toString(opened_file.takeError()));
3543 FileUP file = std::move(opened_file.get());
3550 return error_out(
"Unable to write to destination file",
3551 "Bytes written do not match transcript size.");
3555 output_file->c_str());
3558 "Note: the setting interpreter.save-transcript is set to false, so the "
3559 "transcript might not have been recorded.");
3563 error = file->GetFileSpec(
const_cast<FileSpec &
>(file_spec));
3564 if (
error.Success()) {
3566 m_debugger.GetExternalEditor(), file_spec, 1))
3590 llvm::StringRef(prompt),
3597 if (io_handler_sp) {
3598 io_handler_sp->SetUserData(baton);
3609 llvm::StringRef(prompt),
3616 if (io_handler_sp) {
3617 io_handler_sp->SetUserData(baton);
3677 bool force_create =
true;
3691 m_debugger.SetIOHandlerThread(new_io_handler_thread);
3693 m_debugger.SetIOHandlerThread(old_io_handler_thread);
3705 std::string scratch_command(command_line);
3709 bool wants_raw_input =
false;
3710 std::string next_word;
3714 auto build_alias_cmd = [&](std::string &full_name) {
3715 revised_command_line.
Clear();
3717 std::string alias_result;
3720 revised_command_line.
Printf(
"%s", alias_result.c_str());
3727 char quote_char =
'\0';
3730 if (cmd_obj ==
nullptr) {
3731 std::string full_name;
3734 bool is_real_command =
3735 (!is_alias) || (cmd_obj !=
nullptr && !cmd_obj->
IsAlias());
3736 if (!is_real_command) {
3737 build_alias_cmd(full_name);
3741 revised_command_line.
Printf(
"%s", cmd_name.str().c_str());
3744 revised_command_line.
Printf(
"%s", next_word.c_str());
3755 revised_command_line.
Clear();
3756 revised_command_line.
Printf(
"%s", sub_cmd_name.str().c_str());
3757 cmd_obj = sub_cmd_obj;
3761 revised_command_line.
Printf(
" %c%s%s%c", quote_char,
3762 next_word.c_str(), suffix.c_str(),
3765 revised_command_line.
Printf(
" %s%s", next_word.c_str(),
3771 revised_command_line.
Printf(
" %c%s%s%c", quote_char,
3772 next_word.c_str(), suffix.c_str(),
3775 revised_command_line.
Printf(
" %s%s", next_word.c_str(),
3781 if (cmd_obj ==
nullptr) {
3782 const size_t num_matches = matches.
GetSize();
3787 if (alias_matches.
GetSize() == 1) {
3788 std::string full_name;
3790 build_alias_cmd(full_name);
3791 done =
static_cast<bool>(cmd_obj);
3794 error_msg.
Printf(
"ambiguous command '%s'. Possible matches:\n",
3796 for (uint32_t i = 0; i < num_matches; ++i)
3811 if (!suffix.empty()) {
3813 "command '%s' did not recognize '%s%s%s' as valid (subcommand "
3814 "might be invalid).\n",
3816 next_word.empty() ?
"" : next_word.c_str(),
3817 next_word.empty() ?
" -- " :
" ", suffix.c_str());
3823 if (!suffix.empty()) {
3824 switch (suffix[0]) {
3829 if (command_options &&
3831 std::string gdb_format_option(
"--gdb-format=");
3832 gdb_format_option += (suffix.c_str() + 1);
3834 std::string cmd = std::string(revised_command_line.
GetString());
3836 if (arg_terminator_idx != std::string::npos) {
3839 gdb_format_option.append(1,
' ');
3840 cmd.insert(arg_terminator_idx, gdb_format_option);
3841 revised_command_line.
Clear();
3844 revised_command_line.
Printf(
" %s", gdb_format_option.c_str());
3846 if (wants_raw_input &&
3851 "the '%s' command doesn't support the --gdb-format option\n",
3860 "unknown command shorthand suffix: '%s'\n", suffix.c_str());
3865 if (scratch_command.empty())
3869 if (!scratch_command.empty())
3870 revised_command_line.
Printf(
" %s", scratch_command.c_str());
3872 if (cmd_obj !=
nullptr)
3873 command_line = std::string(revised_command_line.
GetString());
3879 llvm::json::Object stats;
3881 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)
@ eHandleCommandFlagAllowRepeats
@ eHandleCommandFlagStopOnCrash
@ eHandleCommandFlagEchoCommentCommand
@ eHandleCommandFlagStopOnError
@ eHandleCommandFlagStopOnContinue
@ eHandleCommandFlagPrintErrors
@ eHandleCommandFlagEchoCommand
@ eHandleCommandFlagPrintResult
static void GetHomeInitFile(FileSpec &init_file, llvm::StringRef suffix={})
#define REGISTER_COMMAND_OBJECT(NAME, CLASS)
static void StripLeadingSpaces(std::string &s)
static void GetCwdInitFile(llvm::SmallVectorImpl< char > &init_file)
static void GetHomeREPLInitFile(FileSpec &init_file, LanguageType language)
static const char * k_white_space
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.
Broadcaster(lldb::BroadcasterManagerSP manager_sp, std::string name)
Construct with a broadcaster with a name.
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
static const char g_repeat_char
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
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)
lldb::CommandObjectSP GetFrameLanguageCommand() const
Return the language specific command object for the current frame.
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.
CommandReturnObjectCallback m_print_callback
An optional callback to handle printing the CommandReturnObject.
llvm::json::Value GetStatistics()
void UpdateUseColor(bool use_color)
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
std::function< lldb::CommandReturnObjectCallbackResult( CommandReturnObject &)> CommandReturnObjectCallback
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)
@ eBroadcastBitQuitCommandReceived
@ eBroadcastBitResetPrompt
@ eBroadcastBitThreadShouldExit
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
ChildrenOmissionWarningStatus m_truncation_warning
Whether we truncated a value's list of children and whether the user has been told.
void SetOpenTranscriptInEditor(bool enable)
void HandleCompletion(CompletionRequest &request)
CommandInterpreterRunResult m_result
bool GetSpaceReplPrompts() const
@ eCommandTypesUserDef
scripted commands
@ eCommandTypesBuiltin
native commands such as "frame"
@ eCommandTypesHidden
commands prefixed with an underscore
@ eCommandTypesUserMW
multiword commands (command containers)
@ eCommandTypesAliases
aliases such as "po"
ChildrenOmissionWarningStatus m_max_depth_warning
Whether we reached the maximum child nesting depth and whether the user has been told.
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)
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
@ eNoOmission
No children were omitted.
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 m_batch_command_mode
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 SetPrintCallback(CommandReturnObjectCallback callback)
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,...
CommandObject::CommandMap & GetSubcommandDictionary()
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 AppendMessage(llvm::StringRef in_string)
bool GetInteractive() const
void void AppendError(llvm::StringRef in_string)
std::string GetErrorString(bool with_diagnostics=true) const
Return the errors as a string.
llvm::StringRef GetOutputString() const
bool GetDidChangeProcessState() const
void SetSuppressImmediateOutput(bool b)
void SetInteractive(bool b)
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void AppendMessageWithFormat(const char *format,...) __attribute__((format(printf
void void AppendMessageWithFormatv(const char *format, Args &&...args)
void SetDiagnosticIndent(std::optional< uint16_t > indent)
lldb::ReturnStatus GetStatus() const
lldb::StreamSP GetImmediateErrorStream() const
void SetCommand(std::string command)
lldb::StreamSP GetImmediateOutputStream() const
void void AppendWarning(llvm::StringRef in_string)
void AppendErrorWithFormatv(const char *format, Args &&...args)
Stream & GetOutputStream()
"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.
void SetAsyncExecution(bool async)
bool GetShowInlineDiagnostics() const
lldb::FileSP GetOutputFileSP()
const char * GetIOHandlerCommandPrefix()
void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler=true)
Run the given IO handler and return immediately.
void RunIOHandlerSync(const lldb::IOHandlerSP &reader_sp)
Run the given IO handler and block until it's complete.
llvm::StringRef GetPrompt() const
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.
const lldb::StackFrameSP & GetFrameSP() const
Get accessor to get the frame shared pointer.
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.
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
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
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
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)
IOHandlerDelegate(Completion completion=Completion::None)
virtual const char * GetPrompt()
bool GetIsInteractive()
Check if the input is being supplied interactively by a user.
lldb::LockableStreamFileSP GetErrorStreamFileSP()
lldb::LockableStreamFileSP GetOutputStreamFileSP()
static LanguageSet GetLanguagesSupportingREPLs()
static Language * FindPlugin(lldb::LanguageType language)
static const char * GetNameForLanguageType(lldb::LanguageType language)
Returns the internal LLDB name for the specified language.
static lldb::LanguageType GetPrimaryLanguage(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
T GetPropertyAtIndexAs(uint32_t idx, T default_value, const ExecutionContext *exe_ctx=nullptr) const
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)
void Flush() override
Flush the stream.
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
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 AppendList(const char **strv, int strc)
void AppendString(const std::string &s)
const char * GetStringAtIndex(size_t idx) const
void DeleteStringAtIndex(size_t id)
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)
Represents UUID's of various sizes.
const LLDBConfig * GetConfig()
static TelemetryManager * GetInstance()
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::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::LockableStreamFile > LockableStreamFileSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
StopReason
Thread stop reasons.
@ eStopReasonInstrumentation
@ eStopReasonHistoryBoundary
@ eStopReasonInterrupt
Thread requested interrupt.
@ eStopReasonProcessorTrace
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::File > FileSP
@ eCommandReturnObjectPrintCallbackSkipped
The callback deferred printing the command return object.
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.
std::optional< std::string > original_command
These two fields are not collected by default due to PII risks.
std::string command_name
The command name(eg., "breakpoint set")
std::optional< lldb::ReturnStatus > ret_status
Return status of a command and any error description in case of error.
UUID target_uuid
If the command is/can be associated with a target entry this field contains that target's UUID.
std::optional< std::string > args
uint64_t command_id
A unique ID for a command so the manager can match the start entry with its end entry.
static uint64_t GetNextID()
std::optional< std::string > error_data
const bool detailed_command_telemetry
Helper RAII class for collecting telemetry.
void DispatchOnExit(llvm::unique_function< void(Info *info)> final_callback)
void DispatchNow(llvm::unique_function< void(Info *info)> populate_fields_cb)