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 R
"(there is a .lldbinit file in the current directory which is not being read.
108To silence this warning without sourcing in the local .lldbinit, add the following to the lldbinit file in your home directory:
109 settings set target.load-cwd-lldbinit false\n"
110To allow lldb to source .lldbinit files in the current working directory, set the value of this variable to true.
111Only do so if you understand and 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)
150 const uint32_t idx = ePropertyExpandRegexAliases;
152 idx, g_interpreter_properties[idx].default_uint_value != 0);
156 const uint32_t idx = ePropertyPromptOnQuit;
158 idx, g_interpreter_properties[idx].default_uint_value != 0);
162 const uint32_t idx = ePropertyPromptOnQuit;
167 const uint32_t idx = ePropertySaveTranscript;
169 idx, g_interpreter_properties[idx].default_uint_value != 0);
173 const uint32_t idx = ePropertySaveTranscript;
178 const uint32_t idx = ePropertySaveSessionOnQuit;
180 idx, g_interpreter_properties[idx].default_uint_value != 0);
184 const uint32_t idx = ePropertySaveSessionOnQuit;
189 const uint32_t idx = ePropertyOpenTranscriptInEditor;
191 idx, g_interpreter_properties[idx].default_uint_value != 0);
195 const uint32_t idx = ePropertyOpenTranscriptInEditor;
200 const uint32_t idx = ePropertySaveSessionDirectory;
205 const uint32_t idx = ePropertySaveSessionDirectory;
210 const uint32_t idx = ePropertyEchoCommands;
212 idx, g_interpreter_properties[idx].default_uint_value != 0);
216 const uint32_t idx = ePropertyEchoCommands;
221 const uint32_t idx = ePropertyEchoCommentCommands;
223 idx, g_interpreter_properties[idx].default_uint_value != 0);
227 const uint32_t idx = ePropertyEchoCommentCommands;
253 std::string command = command_line;
261 const uint32_t idx = ePropertyStopCmdSourceOnError;
263 idx, g_interpreter_properties[idx].default_uint_value != 0);
267 const uint32_t idx = ePropertySpaceReplPrompts;
269 idx, g_interpreter_properties[idx].default_uint_value != 0);
273 const uint32_t idx = ePropertyRepeatPreviousCommand;
275 idx, g_interpreter_properties[idx].default_uint_value != 0);
279 const uint32_t idx = ePropertyRequireCommandOverwrite;
281 idx, g_interpreter_properties[idx].default_uint_value != 0);
344 "sif", cmd_obj_sp,
"--end-linenumber block --step-in-target %1");
346 sif_alias->
SetHelp(
"Step through the current block, stopping if you step "
347 "directly into a function whose name matches the "
348 "TargetFunctionName.");
349 sif_alias->
SetSyntax(
"sif <TargetFunctionName>");
424 if (
auto *sys_bt =
AddAlias(
"sys_bt", cmd_obj_sp,
"--provider 0")) {
425 sys_bt->SetHelp(
"Show the base unwinder backtrace (without frame "
426 "providers). Equivalent to 'thread backtrace "
439 alias_arguments_vector_sp = std::make_shared<OptionArgVector>();
445 if (
auto *po =
AddAlias(
"po", cmd_obj_sp,
"-O --")) {
446 po->SetHelp(
"Evaluate an expression on the current thread. Displays any "
447 "returned value with formatting "
448 "controlled by the type's author.");
459 AddAlias(
"parray", cmd_obj_sp,
"--element-count %1 --");
462 "parray <COUNT> <EXPRESSION> -- lldb will evaluate EXPRESSION "
463 "to get a typed-pointer-to-an-array in memory, and will display "
464 "COUNT elements of that type from the array.");
468 "poarray", cmd_obj_sp,
"--object-description --element-count %1 --");
471 "poarray <COUNT> <EXPRESSION> -- lldb will "
472 "evaluate EXPRESSION to get the address of an array of COUNT "
473 "objects in memory, and will call po on them.");
482 shell_alias->
SetHelp(
"Run a shell command on the host.");
484 shell_alias->
SetSyntax(
"shell <shell-command>");
495 alias_arguments_vector_sp = std::make_shared<OptionArgVector>();
496#if defined(__APPLE__)
501 AddAlias(
"r", cmd_obj_sp,
"--shell-expand-args true --");
502 AddAlias(
"run", cmd_obj_sp,
"--shell-expand-args true --");
506 defaultshell.
Printf(
"--shell=%s --",
507 HostInfo::GetDefaultShell().GetPath().c_str());
520 AddAlias(
"rbreak", cmd_obj_sp,
"--func-regex %1");
527 AddAlias(
"vo", cmd_obj_sp,
"--object-description");
566#define REGISTER_COMMAND_OBJECT(NAME, CLASS) \
567 m_command_dict[NAME] = std::make_shared<CLASS>(*this);
604 const char *break_regexes[][2] = {
605 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
606 "breakpoint set --file '%1' --line %2 --column %3"},
607 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
608 "breakpoint set --file '%1' --line %2"},
609 {
"^/([^/]+)/$",
"breakpoint set --source-pattern-regexp '%1'"},
610 {
"^([[:digit:]]+)[[:space:]]*$",
"breakpoint set --line %1"},
611 {
"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
"breakpoint set --address %1"},
612 {
"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$",
613 "breakpoint set --name '%1'"},
614 {
"^(-.*)$",
"breakpoint set %1"},
615 {
"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$",
616 "breakpoint set --name '%2' --shlib '%1'"},
617 {
"^\\&(.*[^[:space:]])[[:space:]]*$",
618 "breakpoint set --name '%1' --skip-prologue=0"},
619 {
"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$",
620 "breakpoint set --name '%1'"}};
623 size_t num_regexes = std::size(break_regexes);
625 std::unique_ptr<CommandObjectRegexCommand> break_regex_cmd_up(
627 *
this,
"_regexp-break",
628 "Set a breakpoint using one of several shorthand formats, or list "
629 "the existing breakpoints if no arguments are provided.",
631 "_regexp-break <filename>:<linenum>:<colnum>\n"
632 " main.c:12:21 // Break at line 12 and column "
634 "_regexp-break <filename>:<linenum>\n"
635 " main.c:12 // Break at line 12 of "
637 "_regexp-break <linenum>\n"
638 " 12 // Break at line 12 of current "
640 "_regexp-break 0x<address>\n"
641 " 0x1234000 // Break at address "
643 "_regexp-break <name>\n"
644 " main // Break in 'main' after the "
646 "_regexp-break &<name>\n"
647 " &main // Break at first instruction "
649 "_regexp-break <module>`<name>\n"
650 " libc.so`malloc // Break in 'malloc' from "
652 "_regexp-break /<source-regex>/\n"
653 " /break here/ // Break on source lines in "
655 " // containing text 'break "
658 " // List the existing "
662 if (break_regex_cmd_up) {
664 for (
size_t i = 0; i < num_regexes; i++) {
665 success = break_regex_cmd_up->AddRegexCommand(break_regexes[i][0],
666 break_regexes[i][1]);
671 break_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
675 m_command_dict[std::string(break_regex_cmd_sp->GetCommandName())] =
684 const char *break_add_regexes[][2] = {
685 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
686 "breakpoint add file --file '%1' --line %2 --column %3"},
687 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
688 "breakpoint add file --file '%1' --line %2"},
689 {
"^/([^/]+)/$",
"breakpoint add pattern -- %1"},
690 {
"^([[:digit:]]+)[[:space:]]*$",
691 "breakpoint add file --line %1"},
692 {
"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
693 "breakpoint add address %1"},
694 {
"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$",
695 "breakpoint add name '%1'"},
697 "breakpoint add name '%1'"},
698 {
"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$",
699 "breakpoint add name '%2' --shlib '%1'"},
700 {
"^\\&(.*[^[:space:]])[[:space:]]*$",
701 "breakpoint add name '%1' --skip-prologue=0"},
702 {
"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$",
703 "breakpoint add name '%1'"}};
706 size_t num_add_regexes = std::size(break_add_regexes);
708 std::unique_ptr<CommandObjectRegexCommand> break_add_regex_cmd_up(
710 *
this,
"_regexp-break-add",
711 "Set a breakpoint using one of several shorthand formats, or list "
712 "the existing breakpoints if no arguments are provided.",
714 "_regexp-break-add <filename>:<linenum>:<colnum>\n"
715 " main.c:12:21 // Break at line 12 and column "
717 "_regexp-break-add <filename>:<linenum>\n"
718 " main.c:12 // Break at line 12 of "
720 "_regexp-break-add <linenum>\n"
721 " 12 // Break at line 12 of current "
723 "_regexp-break-add 0x<address>\n"
724 " 0x1234000 // Break at address "
726 "_regexp-break-add <name>\n"
727 " main // Break in 'main' after the "
729 "_regexp-break-add &<name>\n"
730 " &main // Break at first instruction "
732 "_regexp-break-add <module>`<name>\n"
733 " libc.so`malloc // Break in 'malloc' from "
735 "_regexp-break-add /<source-regex>/\n"
736 " /break here/ // Break on source lines in "
738 " // containing text 'break "
740 "_regexp-break-add\n"
741 " // List the existing "
745 if (break_add_regex_cmd_up) {
747 for (
size_t i = 0; i < num_add_regexes; i++) {
748 success = break_add_regex_cmd_up->AddRegexCommand(
749 break_add_regexes[i][0], break_add_regexes[i][1]);
754 break_add_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
757 CommandObjectSP break_add_regex_cmd_sp(break_add_regex_cmd_up.release());
758 m_command_dict[std::string(break_add_regex_cmd_sp->GetCommandName())] =
759 break_add_regex_cmd_sp;
763 std::unique_ptr<CommandObjectRegexCommand> tbreak_regex_cmd_up(
765 *
this,
"_regexp-tbreak",
766 "Set a one-shot breakpoint using one of several shorthand formats.",
768 "_regexp-break <filename>:<linenum>:<colnum>\n"
769 " main.c:12:21 // Break at line 12 and column "
771 "_regexp-break <filename>:<linenum>\n"
772 " main.c:12 // Break at line 12 of "
774 "_regexp-break <linenum>\n"
775 " 12 // Break at line 12 of current "
777 "_regexp-break 0x<address>\n"
778 " 0x1234000 // Break at address "
780 "_regexp-break <name>\n"
781 " main // Break in 'main' after the "
783 "_regexp-break &<name>\n"
784 " &main // Break at first instruction "
786 "_regexp-break <module>`<name>\n"
787 " libc.so`malloc // Break in 'malloc' from "
789 "_regexp-break /<source-regex>/\n"
790 " /break here/ // Break on source lines in "
792 " // containing text 'break "
796 if (tbreak_regex_cmd_up) {
798 for (
size_t i = 0; i < num_regexes; i++) {
799 std::string command = break_regexes[i][1];
802 tbreak_regex_cmd_up->AddRegexCommand(break_regexes[i][0], command);
807 tbreak_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
811 m_command_dict[std::string(tbreak_regex_cmd_sp->GetCommandName())] =
816 std::unique_ptr<CommandObjectRegexCommand> attach_regex_cmd_up(
818 *
this,
"_regexp-attach",
"Attach to process by ID or name.",
819 "_regexp-attach <pid> | <process-name>", 0,
false));
820 if (attach_regex_cmd_up) {
821 if (attach_regex_cmd_up->AddRegexCommand(
"^([0-9]+)[[:space:]]*$",
822 "process attach --pid %1") &&
823 attach_regex_cmd_up->AddRegexCommand(
824 "^(-.*|.* -.*)$",
"process attach %1") &&
827 attach_regex_cmd_up->AddRegexCommand(
"^(.+)$",
828 "process attach --name '%1'") &&
829 attach_regex_cmd_up->AddRegexCommand(
"^$",
"process attach")) {
831 m_command_dict[std::string(attach_regex_cmd_sp->GetCommandName())] =
836 std::unique_ptr<CommandObjectRegexCommand> down_regex_cmd_up(
838 "Select a newer stack frame. Defaults to "
839 "moving one frame, a numeric argument can "
840 "specify an arbitrary number.",
841 "_regexp-down [<count>]", 0,
false));
842 if (down_regex_cmd_up) {
843 if (down_regex_cmd_up->AddRegexCommand(
"^$",
"frame select -r -1") &&
844 down_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
845 "frame select -r -%1")) {
847 m_command_dict[std::string(down_regex_cmd_sp->GetCommandName())] =
852 std::unique_ptr<CommandObjectRegexCommand> up_regex_cmd_up(
855 "Select an older stack frame. Defaults to moving one "
856 "frame, a numeric argument can specify an arbitrary number.",
857 "_regexp-up [<count>]", 0,
false));
858 if (up_regex_cmd_up) {
859 if (up_regex_cmd_up->AddRegexCommand(
"^$",
"frame select -r 1") &&
860 up_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
"frame select -r %1")) {
867 std::unique_ptr<CommandObjectRegexCommand> display_regex_cmd_up(
869 *
this,
"_regexp-display",
870 "Evaluate an expression at every stop (see 'help target stop-hook'.)",
871 "_regexp-display expression", 0,
false));
872 if (display_regex_cmd_up) {
873 if (display_regex_cmd_up->AddRegexCommand(
874 "^(.+)$",
"target stop-hook add -o \"expr -- %1\"")) {
876 m_command_dict[std::string(display_regex_cmd_sp->GetCommandName())] =
877 display_regex_cmd_sp;
881 std::unique_ptr<CommandObjectRegexCommand> undisplay_regex_cmd_up(
883 "Stop displaying expression at every "
884 "stop (specified by stop-hook index.)",
885 "_regexp-undisplay stop-hook-number", 0,
887 if (undisplay_regex_cmd_up) {
888 if (undisplay_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
889 "target stop-hook delete %1")) {
890 CommandObjectSP undisplay_regex_cmd_sp(undisplay_regex_cmd_up.release());
891 m_command_dict[std::string(undisplay_regex_cmd_sp->GetCommandName())] =
892 undisplay_regex_cmd_sp;
896 std::unique_ptr<CommandObjectRegexCommand> connect_gdb_remote_cmd_up(
899 "Connect to a process via remote GDB server.\n"
900 "If no host is specified, localhost is assumed.\n"
901 "gdb-remote is an abbreviation for 'process connect --plugin "
902 "gdb-remote connect://<hostname>:<port>'\n",
903 "gdb-remote [<hostname>:]<portnum>", 0,
false));
904 if (connect_gdb_remote_cmd_up) {
905 if (connect_gdb_remote_cmd_up->AddRegexCommand(
906 "^([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)$",
907 "process connect --plugin gdb-remote connect://%1:%2") &&
908 connect_gdb_remote_cmd_up->AddRegexCommand(
910 "process connect --plugin gdb-remote connect://localhost:%1")) {
912 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
916 std::unique_ptr<CommandObjectRegexCommand> connect_kdp_remote_cmd_up(
919 "Connect to a process via remote KDP server.\n"
920 "If no UDP port is specified, port 41139 is assumed.\n"
921 "kdp-remote is an abbreviation for 'process connect --plugin "
922 "kdp-remote udp://<hostname>:<port>'\n",
923 "kdp-remote <hostname>[:<portnum>]", 0,
false));
924 if (connect_kdp_remote_cmd_up) {
925 if (connect_kdp_remote_cmd_up->AddRegexCommand(
926 "^([^:]+:[[:digit:]]+)$",
927 "process connect --plugin kdp-remote udp://%1") &&
928 connect_kdp_remote_cmd_up->AddRegexCommand(
929 "^(.+)$",
"process connect --plugin kdp-remote udp://%1:41139")) {
931 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
935 std::unique_ptr<CommandObjectRegexCommand> bt_regex_cmd_up(
938 "Show backtrace of the current thread's call stack. Any numeric "
939 "argument displays at most that many frames. The argument 'all' "
940 "displays all threads. Use 'settings set frame-format' to customize "
941 "the printing of individual frames and 'settings set thread-format' "
942 "to customize the thread header. Frame recognizers may filter the "
943 "list. Use 'thread backtrace -u (--unfiltered)' to see them all.",
944 "bt [<digit> | all]", 0,
false));
945 if (bt_regex_cmd_up) {
950 if (bt_regex_cmd_up->AddRegexCommand(
"^([[:digit:]]+)[[:space:]]*$",
951 "thread backtrace -c %1") &&
952 bt_regex_cmd_up->AddRegexCommand(
"^(-[^[:space:]].*)$",
953 "thread backtrace %1") &&
954 bt_regex_cmd_up->AddRegexCommand(
"^all[[:space:]]*$",
955 "thread backtrace all") &&
956 bt_regex_cmd_up->AddRegexCommand(
"^[[:space:]]*$",
957 "thread backtrace")) {
959 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
963 std::unique_ptr<CommandObjectRegexCommand> list_regex_cmd_up(
965 *
this,
"_regexp-list",
966 "List relevant source code using one of several shorthand formats.",
968 "_regexp-list <file>:<line> // List around specific file/line\n"
969 "_regexp-list <line> // List current file around specified "
971 "_regexp-list <function-name> // List specified function\n"
972 "_regexp-list 0x<address> // List around specified address\n"
973 "_regexp-list -[<count>] // List previous <count> lines\n"
974 "_regexp-list // List subsequent lines",
976 if (list_regex_cmd_up) {
977 if (list_regex_cmd_up->AddRegexCommand(
"^([0-9]+)[[:space:]]*$",
978 "source list --line %1") &&
979 list_regex_cmd_up->AddRegexCommand(
980 "^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]"
982 "source list --file '%1' --line %2") &&
983 list_regex_cmd_up->AddRegexCommand(
984 "^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
985 "source list --address %1") &&
986 list_regex_cmd_up->AddRegexCommand(
"^-[[:space:]]*$",
987 "source list --reverse") &&
988 list_regex_cmd_up->AddRegexCommand(
989 "^-([[:digit:]]+)[[:space:]]*$",
990 "source list --reverse --count %1") &&
991 list_regex_cmd_up->AddRegexCommand(
"^(.+)$",
992 "source list --name \"%1\"") &&
993 list_regex_cmd_up->AddRegexCommand(
"^$",
"source list")) {
995 m_command_dict[std::string(list_regex_cmd_sp->GetCommandName())] =
1000 std::unique_ptr<CommandObjectRegexCommand> env_regex_cmd_up(
1002 *
this,
"_regexp-env",
1003 "Shorthand for viewing and setting environment variables.",
1005 "_regexp-env // Show environment\n"
1006 "_regexp-env <name>=<value> // Set an environment variable",
1008 if (env_regex_cmd_up) {
1009 if (env_regex_cmd_up->AddRegexCommand(
"^$",
1010 "settings show target.env-vars") &&
1011 env_regex_cmd_up->AddRegexCommand(
"^([A-Za-z_][A-Za-z_0-9]*=.*)$",
1012 "settings set target.env-vars %1")) {
1014 m_command_dict[std::string(env_regex_cmd_sp->GetCommandName())] =
1019 std::unique_ptr<CommandObjectRegexCommand> jump_regex_cmd_up(
1021 *
this,
"_regexp-jump",
"Set the program counter to a new address.",
1023 "_regexp-jump <line>\n"
1024 "_regexp-jump +<line-offset> | -<line-offset>\n"
1025 "_regexp-jump <file>:<line>\n"
1026 "_regexp-jump *<addr>\n",
1028 if (jump_regex_cmd_up) {
1029 if (jump_regex_cmd_up->AddRegexCommand(
"^\\*(.*)$",
1030 "thread jump --addr %1") &&
1031 jump_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
1032 "thread jump --line %1") &&
1033 jump_regex_cmd_up->AddRegexCommand(
"^([^:]+):([0-9]+)$",
1034 "thread jump --file %1 --line %2") &&
1035 jump_regex_cmd_up->AddRegexCommand(
"^([+\\-][0-9]+)$",
1036 "thread jump --by %1")) {
1038 m_command_dict[std::string(jump_regex_cmd_sp->GetCommandName())] =
1043 std::shared_ptr<CommandObjectRegexCommand> step_regex_cmd_sp(
1045 *
this,
"_regexp-step",
1046 "Single step, optionally to a specific function.",
1048 "_regexp-step // Single step\n"
1049 "_regexp-step <function-name> // Step into the named function\n",
1051 if (step_regex_cmd_sp) {
1052 if (step_regex_cmd_sp->AddRegexCommand(
"^[[:space:]]*$",
1053 "thread step-in") &&
1054 step_regex_cmd_sp->AddRegexCommand(
"^[[:space:]]*(-.+)$",
1055 "thread step-in %1") &&
1056 step_regex_cmd_sp->AddRegexCommand(
1057 "^[[:space:]]*(.+)[[:space:]]*$",
1058 "thread step-in --end-linenumber block --step-in-target %1")) {
1059 m_command_dict[std::string(step_regex_cmd_sp->GetCommandName())] =
1066 const char *cmd_str,
bool include_aliases,
StringList &matches,
1071 if (include_aliases) {
1084 auto get_multi_or_report_error =
1089 "Path component: '%s' not found", name);
1092 if (!cmd_sp->IsUserCommand()) {
1094 "Path component: '%s' is not a user "
1100 if (!cmd_as_multi) {
1102 "Path component: '%s' is not a container "
1107 return cmd_as_multi;
1111 if (num_args == 0) {
1116 if (num_args == 1 && leaf_is_command) {
1126 get_multi_or_report_error(cur_cmd_sp, cur_name);
1127 if (cur_as_multi ==
nullptr)
1130 size_t num_path_elements = num_args - (leaf_is_command ? 1 : 0);
1131 for (
size_t cursor = 1; cursor < num_path_elements && cur_as_multi !=
nullptr;
1135 cur_as_multi = get_multi_or_report_error(cur_cmd_sp, cur_name);
1137 return cur_as_multi;
1144 auto frame_language =
1157 auto lang_name =
plugin->GetPluginName();
1159 return language_cmd_sp->GetSubcommandSPExact(lang_name);
1168 std::string cmd = std::string(cmd_str);
1173 command_sp = pos->second;
1179 command_sp = alias_pos->second;
1185 command_sp = pos->second;
1191 command_sp = pos->second;
1196 if (!exact && !command_sp) {
1202 if (matches ==
nullptr)
1203 matches = &local_matches;
1205 unsigned int num_cmd_matches = 0;
1206 unsigned int num_alias_matches = 0;
1207 unsigned int num_user_matches = 0;
1208 unsigned int num_user_mw_matches = 0;
1216 *matches, descriptions);
1219 if (num_cmd_matches == 1) {
1223 real_match_sp = pos->second;
1228 *matches, descriptions);
1231 if (num_alias_matches == 1) {
1235 alias_match_sp = alias_pos->second;
1240 *matches, descriptions);
1243 if (num_user_matches == 1) {
1249 user_match_sp = pos->second;
1257 if (num_user_mw_matches == 1) {
1263 user_mw_match_sp = pos->second;
1269 if (num_user_matches + num_user_mw_matches + num_cmd_matches +
1270 num_alias_matches ==
1272 if (num_cmd_matches)
1273 return real_match_sp;
1274 else if (num_alias_matches)
1275 return alias_match_sp;
1276 else if (num_user_mw_matches)
1277 return user_mw_match_sp;
1279 return user_match_sp;
1290 command_sp = lang_subcmd_sp->GetSubcommandSPExact(cmd_str);
1293 if (!command_sp && !exact && lang_subcmd) {
1296 cmd_str, lang_matches, descriptions);
1299 if (lang_matches.
GetSize() == 1) {
1301 auto pos = lang_dict.find(lang_matches[0]);
1302 if (pos != lang_dict.end())
1308 if (matches && command_sp) {
1321 lldbassert((
this == &cmd_sp->GetCommandInterpreter()) &&
1322 "tried to add a CommandObject from a different interpreter");
1327 cmd_sp->SetIsUserCommand(
false);
1329 std::string name_sstr(name);
1332 if (!can_replace || !name_iter->second->IsRemovable())
1334 name_iter->second = cmd_sp;
1346 lldbassert((
this == &cmd_sp->GetCommandInterpreter()) &&
1347 "tried to add a CommandObject from a different interpreter");
1350 "can't use the empty string for a command name");
1362 "user command \"{0}\" already exists and force replace was not set "
1363 "by --overwrite or 'settings set interpreter.require-overwrite "
1368 if (cmd_sp->IsMultiwordObject()) {
1371 "can't replace explicitly non-removable multi-word command");
1375 if (!
m_user_dict[std::string(name)]->IsRemovable()) {
1377 "can't replace explicitly non-removable command");
1383 cmd_sp->SetIsUserCommand(
true);
1385 if (cmd_sp->IsMultiwordObject())
1394 bool include_aliases)
const {
1396 Args cmd_words(cmd_str);
1398 if (cmd_str.empty())
1415 for (
size_t i = 1; i < end; ++i) {
1416 if (!cmd_obj_sp->IsMultiwordObject()) {
1441 matches, descriptions)
1447 std::string cmd_str(cmd);
1449 auto found_elem = map.find(cmd);
1450 if (found_elem == map.end())
1473 StringList *matches_ptr = matches ? matches : &tmp_list;
1485 auto found_elem = map.find(cmd);
1486 if (found_elem == map.end())
1508 StringList *matches_ptr = matches ? matches : &tmp_list;
1519 std::string &full_name)
const {
1522 full_name.assign(std::string(cmd));
1526 size_t num_alias_matches;
1529 if (num_alias_matches == 1) {
1532 const bool include_aliases =
false;
1533 const bool exact =
false;
1535 GetCommandSP(cmd, include_aliases, exact, ®ular_matches));
1536 if (cmd_obj_sp || regular_matches.
GetSize() > 0)
1563 llvm::StringRef args_string) {
1564 if (command_obj_sp.get())
1565 lldbassert((
this == &command_obj_sp->GetCommandInterpreter()) &&
1566 "tried to add a CommandObject from a different interpreter");
1568 std::unique_ptr<CommandAlias> command_alias_up(
1569 new CommandAlias(*
this, command_obj_sp, args_string, alias_name));
1571 if (command_alias_up && command_alias_up->IsValid()) {
1574 return command_alias_up.release();
1592 if (force || pos->second->IsRemovable()) {
1603 CommandObject::CommandMap::iterator pos =
m_user_dict.find(user_name);
1612 CommandObject::CommandMap::iterator pos =
m_user_mw_dict.find(multi_name);
1621 uint32_t cmd_types) {
1622 llvm::StringRef help_prologue(
GetDebugger().GetIOHandlerHelpPrologue());
1623 if (!help_prologue.empty()) {
1628 CommandObject::CommandMap::const_iterator pos;
1637 (pos->first.compare(0, 1,
"_") == 0))
1641 pos->second->GetHelp(), max_len);
1649 "Current command abbreviations "
1650 "(type '{0}help command alias' for more info):",
1658 alias_pos->second->GetHelp(), max_len);
1670 pos->second->GetHelp(), max_len);
1677 result.
AppendMessage(
"Current user-defined container commands:");
1682 pos->second->GetHelp(), max_len);
1688 "For more information on any command, type '{0}help <command-name>'.",
1693 llvm::StringRef &command_string) {
1699 size_t start = command_string.find_first_not_of(
k_white_space);
1703 if (start != std::string::npos) {
1706 if (end == std::string::npos)
1707 end = command_string.size();
1708 std::string cmd_word =
1709 std::string(command_string.substr(start, end - start));
1711 if (cmd_obj ==
nullptr)
1721 cmd_obj = sub_cmd_obj;
1733 end >= command_string.size())
1736 start = command_string.find_first_not_of(
k_white_space, end);
1742 command_string = command_string.substr(end);
1747 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
1751 if (pos == std::string::npos)
1760 const size_t s_len = s.size();
1762 while (offset < s_len) {
1763 size_t pos = s.find(
"--", offset);
1764 if (pos == std::string::npos)
1767 if (llvm::isSpace(s[pos - 1])) {
1770 if ((pos + 2 >= s_len) || llvm::isSpace(s[pos + 2])) {
1777 return std::string::npos;
1781 std::string &suffix,
char "e_char) {
1786 bool result =
false;
1789 if (!command_string.empty()) {
1790 const char first_char = command_string[0];
1791 if (first_char ==
'\'' || first_char ==
'"') {
1792 quote_char = first_char;
1793 const size_t end_quote_pos = command_string.find(quote_char, 1);
1794 if (end_quote_pos == std::string::npos) {
1795 command.swap(command_string);
1796 command_string.erase();
1798 command.assign(command_string, 1, end_quote_pos - 1);
1799 if (end_quote_pos + 1 < command_string.size())
1800 command_string.erase(0, command_string.find_first_not_of(
1803 command_string.erase();
1806 const size_t first_space_pos =
1808 if (first_space_pos == std::string::npos) {
1809 command.swap(command_string);
1810 command_string.erase();
1812 command.assign(command_string, 0, first_space_pos);
1813 command_string.erase(0, command_string.find_first_not_of(
1820 if (!command.empty()) {
1822 if (command[0] !=
'-' && command[0] !=
'_') {
1824 if (pos > 0 && pos != std::string::npos) {
1825 suffix.assign(command.begin() + pos, command.end());
1835 llvm::StringRef alias_name, std::string &raw_input_string,
1838 Args cmd_args(raw_input_string);
1842 if (!alias_cmd_obj || !alias_cmd_obj->
IsAlias()) {
1843 alias_result.clear();
1844 return alias_cmd_obj;
1846 std::pair<CommandObjectSP, OptionArgVectorSP> desugared =
1849 alias_cmd_obj = desugared.first.get();
1850 std::string alias_name_str = std::string(alias_name);
1853 cmd_args.
Unshift(alias_name_str);
1857 if (!option_arg_vector_sp.get()) {
1858 alias_result = std::string(result_str.
GetString());
1859 return alias_cmd_obj;
1866 for (
const auto &entry : *option_arg_vector) {
1867 std::tie(option, value_type, value) = entry;
1869 result_str.
Printf(
" %s", value.c_str());
1873 result_str.
Printf(
" %s", option.c_str());
1881 result_str.
Printf(
"%s", value.c_str());
1885 "need at least %d arguments to use "
1891 size_t strpos = raw_input_string.find(entry.
c_str());
1893 if (strpos != std::string::npos) {
1894 const size_t start_fudge = quote_char ==
'\0' ? 0 : 1;
1895 const size_t len_fudge = quote_char ==
'\0' ? 0 : 2;
1898 if (strpos < start_fudge) {
1899 result.
AppendError(
"unmatched quote at command beginning");
1902 llvm::StringRef arg_text = entry.
ref();
1903 if (strpos - start_fudge + arg_text.size() + len_fudge >
1904 raw_input_string.size()) {
1905 result.
AppendError(
"unmatched quote at command end");
1908 raw_input_string = raw_input_string.erase(
1909 strpos - start_fudge,
1912 if (quote_char ==
'\0')
1915 result_str.
Printf(
"%c%s%c", quote_char, entry.
c_str(), quote_char);
1919 alias_result = std::string(result_str.
GetString());
1920 return alias_cmd_obj;
1931 size_t start_backtick;
1933 while ((start_backtick = command.find(
'`', pos)) != std::string::npos) {
1938 if (start_backtick > 0 && command[start_backtick - 1] ==
'\\') {
1941 command.erase(start_backtick - 1, 1);
1943 pos = start_backtick;
1947 const size_t expr_content_start = start_backtick + 1;
1948 const size_t end_backtick = command.find(
'`', expr_content_start);
1950 if (end_backtick == std::string::npos) {
1955 if (end_backtick == expr_content_start) {
1957 command.erase(start_backtick, 2);
1961 std::string expr_str(command, expr_content_start,
1962 end_backtick - expr_content_start);
1968 command.erase(start_backtick, end_backtick - start_backtick + 1);
1969 command.insert(start_backtick, std::string(expr_str));
1970 pos = start_backtick + expr_str.size();
1992 expr_str.c_str(), exe_ctx.
GetFramePtr(), expr_result_valobj_sp, options);
1996 if (expr_result_valobj_sp)
1997 expr_result_valobj_sp =
1998 expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable(
1999 expr_result_valobj_sp->GetDynamicValueType(),
true);
2000 if (expr_result_valobj_sp->ResolveValue(scalar)) {
2003 const bool show_type =
false;
2004 scalar.
GetValue(value_strm, show_type);
2005 size_t value_string_size = value_strm.
GetSize();
2006 if (value_string_size) {
2007 expr_str = value_strm.
GetData();
2011 "in a scalar value for the "
2018 "in a scalar value for the "
2029 if (expr_result_valobj_sp)
2030 error = expr_result_valobj_sp->GetError().Clone();
2032 if (
error.Success()) {
2034 "for the expression '" + expr_str +
"'";
2046 bool status =
HandleCommand(command_line, lazy_add_to_history, result);
2054 bool force_repeat_command) {
2059 std::string parsed_command_args;
2063 const bool detailed_command_telemetry =
2069 std::string command_string(command_line);
2070 std::string original_command_string(command_string);
2071 std::string real_original_command_string(command_string);
2077 info->
target_uuid = target->GetExecutableModule() !=
nullptr
2078 ? target->GetExecutableModule()->GetUUID()
2081 if (detailed_command_telemetry)
2088 detailed_command_telemetry, command_id](
2094 llvm::StringRef command_name =
2098 if (std::string error_str = result.
GetErrorString(); !error_str.empty())
2101 if (detailed_command_telemetry)
2102 info->
args = parsed_command_args;
2106 LLDB_LOGF(log,
"Processing command: %s", command_line);
2118 bool add_to_history;
2122 add_to_history = (lazy_add_to_history ==
eLazyBoolYes);
2130 transcript_item = std::make_shared<StructuredData::Dictionary>();
2131 transcript_item->AddStringItem(
"command", command_line);
2132 transcript_item->AddIntegerItem(
2133 "timestampInEpochSeconds",
2134 std::chrono::duration_cast<std::chrono::seconds>(
2135 std::chrono::system_clock::now().time_since_epoch())
2140 bool empty_command =
false;
2141 bool comment_command =
false;
2142 if (command_string.empty())
2143 empty_command =
true;
2145 const char *k_space_characters =
"\t\n\v\f\r ";
2147 size_t non_space = command_string.find_first_not_of(k_space_characters);
2150 if (non_space == std::string::npos)
2151 empty_command =
true;
2153 comment_command =
true;
2155 llvm::StringRef search_str(command_string);
2156 search_str = search_str.drop_front(non_space);
2158 add_to_history =
false;
2159 command_string = std::string(*hist_str);
2160 original_command_string = std::string(*hist_str);
2163 command_string.c_str());
2169 if (empty_command) {
2181 command_string = command_line;
2182 original_command_string = command_line;
2188 add_to_history =
false;
2189 }
else if (comment_command) {
2229 llvm::StringRef command_name =
2231 LLDB_LOGF(log,
"HandleCommand, cmd_obj : '%s'", command_name.str().c_str());
2232 LLDB_LOGF(log,
"HandleCommand, (revised) command_string: '%s'",
2233 command_string.c_str());
2234 const bool wants_raw_input =
2236 LLDB_LOGF(log,
"HandleCommand, wants_raw_input:'%s'",
2237 wants_raw_input ?
"True" :
"False");
2245 if (cmd_obj !=
nullptr) {
2246 bool generate_repeat_command = add_to_history;
2250 generate_repeat_command |= empty_command;
2255 generate_repeat_command |= force_repeat_command;
2256 if (generate_repeat_command) {
2257 Args command_args(command_string);
2258 std::optional<std::string> repeat_command =
2260 if (repeat_command) {
2261 LLDB_LOGF(log,
"Repeat command: %s", repeat_command->data());
2271 const std::size_t actual_cmd_name_len = cmd_obj->
GetCommandName().size();
2272 if (actual_cmd_name_len < command_string.length())
2273 parsed_command_args = command_string.substr(actual_cmd_name_len);
2276 size_t pos = parsed_command_args.find_first_not_of(
k_white_space);
2277 if (pos != 0 && pos != std::string::npos)
2278 parsed_command_args.erase(0, pos);
2281 log,
"HandleCommand, command line after removing command name(s): '%s'",
2282 parsed_command_args.c_str());
2287 if (transcript_item) {
2288 transcript_item->AddStringItem(
"commandName", cmd_obj->
GetCommandName());
2289 transcript_item->AddStringItem(
"commandArguments", parsed_command_args);
2295 pos = real_original_command_string.rfind(parsed_command_args);
2296 std::optional<uint16_t> indent;
2297 if (pos != std::string::npos)
2300 cmd_obj->
Execute(parsed_command_args.c_str(), result);
2303 LLDB_LOGF(log,
"HandleCommand, command %s",
2304 (result.
Succeeded() ?
"succeeded" :
"did not succeed"));
2309 if (transcript_item) {
2314 transcript_item->AddStringItem(
"error", result.
GetErrorString());
2315 transcript_item->AddFloatItem(
"durationInSeconds",
2316 execute_time.
get().count());
2323 bool look_for_subcommand =
false;
2329 bool include_aliases =
true;
2340 &new_matches, &new_descriptions);
2347 look_for_subcommand =
true;
2362 if (command_object) {
2375 if (!first_arg.empty()) {
2380 request.
AddCompletion(*hist_str,
"Previous command history event",
2389std::optional<std::string>
2392 return std::nullopt;
2394 for (
int i = s - 1; i >= 0; --i) {
2396 if (entry.consume_front(line))
2399 return std::nullopt;
2403 EventSP prompt_change_event_sp(
2419 return default_answer;
2456 const char *alias_name,
2458 std::string &raw_input_string,
2466 std::string alias_name_str = alias_name;
2468 cmd_args.
Unshift(alias_name_str);
2474 if (option_arg_vector_sp.get()) {
2475 if (wants_raw_input) {
2479 size_t pos = raw_input_string.find(
" -- ");
2480 if (pos == std::string::npos) {
2482 raw_input_string.insert(0,
" -- ");
2488 std::vector<bool> used(old_size + 1,
false);
2495 for (
const auto &option_entry : *option_arg_vector) {
2496 std::tie(option, value_type, value) = option_entry;
2498 if (!wants_raw_input || (value !=
"--")) {
2522 "need at least %d arguments to use "
2530 if (strpos != std::string::npos) {
2531 raw_input_string = raw_input_string.erase(
2544 for (
auto entry : llvm::enumerate(cmd_args.
entries())) {
2545 if (!used[entry.index()] && !wants_raw_input)
2558 if (wants_raw_input) {
2574 const char *cptr = in_string;
2577 if (cptr[0] ==
'%') {
2581 if (isdigit(cptr[0])) {
2582 const char *start = cptr;
2583 while (isdigit(cptr[0]))
2588 if (cptr[0] ==
'\0')
2589 position = atoi(start);
2597 std::string init_file_name =
".lldbinit";
2598 if (!suffix.empty()) {
2599 init_file_name.append(
"-");
2600 init_file_name.append(suffix.str());
2611 language = *main_repl_language;
2616 std::string init_file_name =
2617 (llvm::Twine(
".lldbinit-") +
2619 llvm::Twine(
"-repl"))
2627 llvm::StringRef s =
".lldbinit";
2628 init_file.assign(s.begin(), s.end());
2660 llvm::SmallString<128> init_file;
2670 switch (should_load) {
2680 if (llvm::sys::path::parent_path(init_file) ==
2681 llvm::sys::path::parent_path(home_init_file.
GetPath())) {
2706 if (init_file.
GetPath().empty())
2710 llvm::StringRef program_name =
2711 HostInfo::GetProgramFileSpec().GetFilename().GetStringRef();
2715 init_file = program_init_file;
2722#ifdef LLDB_GLOBAL_INIT_DIRECTORY
2724 FileSpec init_file(LLDB_GLOBAL_INIT_DIRECTORY);
2738 return prefix ==
nullptr ?
"" : prefix;
2743 if (prefer_target_platform) {
2751 platform_sp =
m_debugger.GetPlatformList().GetSelectedPlatform();
2757 TargetSP target_sp = exe_ctx.GetTargetSP();
2761 ProcessSP process_sp(target_sp->GetProcessSP());
2768 for (
const auto &thread_sp : process_sp->GetThreadList().Threads()) {
2769 StopInfoSP stop_info = thread_sp->GetStopInfo();
2777 const StopReason reason = stop_info->GetStopReason();
2785 const auto stop_signal =
static_cast<int32_t
>(stop_info->GetValue());
2787 if (!signals_sp || !signals_sp->SignalIsValid(stop_signal))
2791 const auto sigint_num = signals_sp->GetSignalNumberFromName(
"SIGINT");
2792 const auto sigstop_num = signals_sp->GetSignalNumberFromName(
"SIGSTOP");
2793 if ((stop_signal != sigint_num) && (stop_signal != sigstop_num))
2814 size_t num_lines = commands.
GetSize();
2820 bool old_async_execution =
m_debugger.GetAsyncExecution();
2826 for (
size_t idx = 0; idx < num_lines; idx++) {
2834 "{0} {1}",
m_debugger.GetPrompt().str().c_str(), cmd);
2855 if (!success || !tmp_result.
Succeeded()) {
2857 if (error_msg.empty())
2858 error_msg =
"<unknown error>.\n";
2861 "command #{0}: '{1}' failed with {2}",
2862 (uint64_t)idx, cmd, error_msg);
2863 m_debugger.SetAsyncExecution(old_async_execution);
2868 (uint64_t)idx + 1, cmd, error_msg);
2889 if (idx != num_lines - 1)
2891 "Aborting reading of commands after command #%" PRIu64
2892 ": '%s' continued the target.",
2893 (uint64_t)idx + 1, cmd);
2896 "Command #{0} '{1}' continued the target.", (uint64_t)idx + 1,
2900 m_debugger.SetAsyncExecution(old_async_execution);
2909 if (idx != num_lines - 1)
2911 "Aborting reading of commands after command #%" PRIu64
2912 ": '%s' stopped with a signal or exception.",
2913 (uint64_t)idx + 1, cmd);
2916 "Command #{0} '{1}' stopped with a signal or exception.",
2917 (uint64_t)idx + 1, cmd);
2920 m_debugger.SetAsyncExecution(old_async_execution);
2927 m_debugger.SetAsyncExecution(old_async_execution);
2956 "Error reading commands from file %s - file not found.",
2961 std::string cmd_file_path = cmd_file.
GetPath();
2962 auto input_file_up =
2964 if (!input_file_up) {
2965 std::string
error = llvm::toString(input_file_up.takeError());
2967 "error: an error occurred read file '{0}': {1}\n", cmd_file_path,
2968 llvm::fmt_consume(input_file_up.takeError()));
2971 FileSP input_file_sp =
FileSP(std::move(input_file_up.get()));
3058 cmd_file_path.c_str());
3074 debugger.
GetPrompt(), llvm::StringRef(),
3104 llvm::StringRef prefix,
3105 llvm::StringRef help_text) {
3106 const uint32_t max_columns =
m_debugger.GetTerminalWidth();
3108 size_t line_width_max = max_columns - prefix.size();
3109 if (line_width_max < 16)
3110 line_width_max = help_text.size() + prefix.size();
3113 bool prefixed_yet =
false;
3115 if (help_text.empty())
3116 help_text =
"No help text";
3117 while (!help_text.empty()) {
3119 if (!prefixed_yet) {
3121 prefixed_yet =
true;
3126 llvm::StringRef this_line = help_text.substr(0, line_width_max);
3129 std::size_t first_newline = this_line.find_first_of(
"\n");
3132 std::size_t last_space = llvm::StringRef::npos;
3133 if (this_line.size() != help_text.size())
3134 last_space = this_line.find_last_of(
" \t");
3137 this_line = this_line.substr(0, std::min(first_newline, last_space));
3142 help_text = help_text.drop_front(this_line.size()).ltrim();
3148 llvm::StringRef word_text,
3149 llvm::StringRef separator,
3150 llvm::StringRef help_text,
3151 size_t max_word_len) {
3153 prefix_stream.
Printf(
" %-*s %*s ", (
int)max_word_len, word_text.data(),
3154 (
int)separator.size(), separator.data());
3159 llvm::StringRef separator,
3160 llvm::StringRef help_text,
3161 uint32_t max_word_len) {
3162 int indent_size = max_word_len + separator.size() + 2;
3167 text_strm.
Printf(
"%-*s ", (
int)max_word_len, word_text.data());
3168 text_strm << separator <<
" " << help_text;
3170 const uint32_t max_columns =
m_debugger.GetTerminalWidth();
3172 llvm::StringRef text = text_strm.
GetString();
3174 uint32_t chars_left = max_columns;
3176 auto start_new_line = [&] {
3179 chars_left = max_columns - indent_size;
3182 while (!text.empty()) {
3183 if (text.starts_with(
'\n')) {
3184 text = text.drop_front();
3193 size_t word_start_pos = text.find_first_not_of(
' ');
3194 size_t word_end_pos = text.find_first_of(
" \n", word_start_pos);
3195 size_t fragment_size =
3196 word_end_pos == llvm::StringRef::npos ? text.size() : word_end_pos;
3198 if (fragment_size > chars_left && text.starts_with(
' ')) {
3201 text = text.drop_front(word_start_pos);
3208 strm.
PutCString(text.take_front(fragment_size));
3209 text = text.drop_front(fragment_size);
3210 chars_left = fragment_size > chars_left ? 0 : chars_left - fragment_size;
3218 llvm::StringRef search_word,
StringList &commands_found,
3220 for (
const auto &pair : command_map) {
3221 llvm::StringRef command_name = pair.first;
3224 const bool search_short_help =
true;
3225 const bool search_long_help =
false;
3226 const bool search_syntax =
false;
3227 const bool search_options =
false;
3228 if (command_name.contains_insensitive(search_word) ||
3230 search_long_help, search_syntax,
3239 multiword_cmd->GetSubcommandDictionary());
3240 for (
const auto &subcommand_name : subcommands_found) {
3241 std::string qualified_name =
3242 (command_name +
" " + subcommand_name).str();
3252 bool search_builtin_commands,
3253 bool search_user_commands,
3254 bool search_alias_commands,
3255 bool search_user_mw_commands) {
3256 CommandObject::CommandMap::const_iterator pos;
3258 if (search_builtin_commands)
3262 if (search_user_commands)
3266 if (search_user_mw_commands)
3270 if (search_alias_commands)
3294 m_debugger.FlushProcessOutput(*process_sp,
true,
3323 if (!
m_debugger.IsIOHandlerThreadCurrentThread())
3326 bool was_interrupted =
3329 return was_interrupted;
3333 llvm::StringRef str,
3340 bool had_output = !str.empty();
3341 while (!str.empty()) {
3342 llvm::StringRef line;
3343 std::tie(line, str) = str.split(
'\n');
3346 stream_file.
Write(line.data(), line.size());
3347 stream_file.
Write(
"\n", 1);
3354 stream_file.
Printf(
"\n... Interrupted.\n");
3355 stream_file.
Flush();
3359 llvm::StringRef line,
const Flags &io_handler_flags)
const {
3363 llvm::StringRef command = line.trim();
3364 if (command.empty())
3374 std::string &line) {
3380 const bool allow_repeats =
3383 if (!is_interactive && !allow_repeats) {
3392 if (!is_interactive) {
3406 m_debugger.GetSelectedExecutionContext(
true);
3407 bool pushed_exe_ctx =
false;
3410 pushed_exe_ctx =
true;
3412 llvm::scope_exit finalize([
this, pushed_exe_ctx]() {
3421 if ((result.Succeeded() &&
3426 const bool inline_diagnostics = !result.GetImmediateErrorStream() &&
3428 if (inline_diagnostics) {
3429 unsigned prompt_len =
m_debugger.GetPrompt().size();
3430 if (
auto indent = result.GetDiagnosticIndent()) {
3432 result.GetInlineDiagnosticString(prompt_len + *indent);
3440 if (!result.GetImmediateOutputStream()) {
3441 llvm::StringRef output = result.GetOutputString();
3446 if (!result.GetImmediateErrorStream()) {
3447 std::string
error = result.GetErrorString(!inline_diagnostics);
3455 DefaultPrintCallback(result);
3457 DefaultPrintCallback(result);
3463 switch (result.GetStatus()) {
3477 m_result.IncrementNumberOfErrors();
3492 result.GetDidChangeProcessState() &&
3517 if (script_interpreter) {
3526 if (output_file == std::nullopt || output_file->empty()) {
3527 std::string now = llvm::to_string(std::chrono::system_clock::now());
3528 llvm::replace(now,
' ',
'_');
3530 llvm::replace(now,
':',
'-');
3531 const std::string file_name =
"lldb_session_" + now +
".log";
3536 save_location = HostInfo::GetGlobalTempDir();
3540 output_file = save_location.
GetPath();
3543 auto error_out = [&](llvm::StringRef error_message, std::string description) {
3545 output_file, description);
3547 "Failed to save session's transcripts to {0}!", *output_file);
3558 return error_out(
"Unable to create file",
3559 llvm::toString(opened_file.takeError()));
3561 FileUP file = std::move(opened_file.get());
3568 return error_out(
"Unable to write to destination file",
3569 "Bytes written do not match transcript size.");
3573 output_file->c_str());
3576 "Note: the setting interpreter.save-transcript is set to false, so the "
3577 "transcript might not have been recorded.");
3581 error = file->GetFileSpec(
const_cast<FileSpec &
>(file_spec));
3582 if (
error.Success()) {
3584 m_debugger.GetExternalEditor(), file_spec, 1))
3608 llvm::StringRef(prompt),
3615 if (io_handler_sp) {
3616 io_handler_sp->SetUserData(baton);
3627 llvm::StringRef(prompt),
3634 if (io_handler_sp) {
3635 io_handler_sp->SetUserData(baton);
3695 bool force_create =
true;
3709 m_debugger.SetIOHandlerThread(new_io_handler_thread);
3711 m_debugger.SetIOHandlerThread(old_io_handler_thread);
3723 std::string scratch_command(command_line);
3727 bool wants_raw_input =
false;
3728 std::string next_word;
3732 auto build_alias_cmd = [&](std::string &full_name) {
3733 revised_command_line.
Clear();
3735 std::string alias_result;
3738 revised_command_line.
Printf(
"%s", alias_result.c_str());
3745 char quote_char =
'\0';
3748 if (cmd_obj ==
nullptr) {
3749 std::string full_name;
3752 bool is_real_command =
3753 (!is_alias) || (cmd_obj !=
nullptr && !cmd_obj->
IsAlias());
3754 if (!is_real_command) {
3755 build_alias_cmd(full_name);
3759 revised_command_line.
Printf(
"%s", cmd_name.str().c_str());
3762 revised_command_line.
Printf(
"%s", next_word.c_str());
3773 revised_command_line.
Clear();
3774 revised_command_line.
Printf(
"%s", sub_cmd_name.str().c_str());
3775 cmd_obj = sub_cmd_obj;
3779 revised_command_line.
Printf(
" %c%s%s%c", quote_char,
3780 next_word.c_str(), suffix.c_str(),
3783 revised_command_line.
Printf(
" %s%s", next_word.c_str(),
3789 revised_command_line.
Printf(
" %c%s%s%c", quote_char,
3790 next_word.c_str(), suffix.c_str(),
3793 revised_command_line.
Printf(
" %s%s", next_word.c_str(),
3799 if (cmd_obj ==
nullptr) {
3800 const size_t num_matches = matches.
GetSize();
3805 if (alias_matches.
GetSize() == 1) {
3806 std::string full_name;
3808 build_alias_cmd(full_name);
3809 done =
static_cast<bool>(cmd_obj);
3812 error_msg.
Printf(
"ambiguous command '%s'. Possible matches:\n",
3814 for (uint32_t i = 0; i < num_matches; ++i)
3829 if (!suffix.empty()) {
3831 "command '%s' did not recognize '%s%s%s' as valid (subcommand "
3832 "might be invalid).",
3834 next_word.empty() ?
"" : next_word.c_str(),
3835 next_word.empty() ?
" -- " :
" ", suffix.c_str());
3841 if (!suffix.empty()) {
3842 switch (suffix[0]) {
3847 if (command_options &&
3849 std::string gdb_format_option(
"--gdb-format=");
3850 gdb_format_option += (suffix.c_str() + 1);
3852 std::string cmd = std::string(revised_command_line.
GetString());
3854 if (arg_terminator_idx != std::string::npos) {
3857 gdb_format_option.append(1,
' ');
3858 cmd.insert(arg_terminator_idx, gdb_format_option);
3859 revised_command_line.
Clear();
3862 revised_command_line.
Printf(
" %s", gdb_format_option.c_str());
3864 if (wants_raw_input &&
3869 "the '%s' command doesn't support the --gdb-format option",
3883 if (scratch_command.empty())
3887 if (!scratch_command.empty())
3888 revised_command_line.
Printf(
" %s", scratch_command.c_str());
3890 if (cmd_obj !=
nullptr)
3891 command_line = std::string(revised_command_line.
GetString());
3897 llvm::json::Object stats;
3899 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 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 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 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) 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.
Target & GetTargetRef() const
Returns a reference to the target object.
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.
std::string toString(FormatterBytecode::OpCodes op)
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)