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 "
443 alias_arguments_vector_sp = std::make_shared<OptionArgVector>();
449 if (
auto *po =
AddAlias(
"po", cmd_obj_sp,
"-O --")) {
450 po->SetHelp(
"Evaluate an expression on the current thread. Displays any "
451 "returned value with formatting "
452 "controlled by the type's author.");
463 AddAlias(
"parray", cmd_obj_sp,
"--element-count %1 --");
466 "parray <COUNT> <EXPRESSION> -- lldb will evaluate EXPRESSION "
467 "to get a typed-pointer-to-an-array in memory, and will display "
468 "COUNT elements of that type from the array.");
472 "poarray", cmd_obj_sp,
"--object-description --element-count %1 --");
475 "poarray <COUNT> <EXPRESSION> -- lldb will "
476 "evaluate EXPRESSION to get the address of an array of COUNT "
477 "objects in memory, and will call po on them.");
486 shell_alias->
SetHelp(
"Run a shell command on the host.");
488 shell_alias->
SetSyntax(
"shell <shell-command>");
499 alias_arguments_vector_sp = std::make_shared<OptionArgVector>();
500#if defined(__APPLE__)
505 AddAlias(
"r", cmd_obj_sp,
"--shell-expand-args true --");
506 AddAlias(
"run", cmd_obj_sp,
"--shell-expand-args true --");
510 defaultshell.
Printf(
"--shell=%s --",
511 HostInfo::GetDefaultShell().GetPath().c_str());
524 AddAlias(
"rbreak", cmd_obj_sp,
"--func-regex %1");
531 AddAlias(
"vo", cmd_obj_sp,
"--object-description");
570#define REGISTER_COMMAND_OBJECT(NAME, CLASS) \
571 m_command_dict[NAME] = std::make_shared<CLASS>(*this);
608 const char *break_regexes[][2] = {
609 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
610 "breakpoint set --file '%1' --line %2 --column %3"},
611 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
612 "breakpoint set --file '%1' --line %2"},
613 {
"^/([^/]+)/$",
"breakpoint set --source-pattern-regexp '%1'"},
614 {
"^([[:digit:]]+)[[:space:]]*$",
"breakpoint set --line %1"},
615 {
"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
"breakpoint set --address %1"},
616 {
"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$",
617 "breakpoint set --name '%1'"},
618 {
"^(-.*)$",
"breakpoint set %1"},
619 {
"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$",
620 "breakpoint set --name '%2' --shlib '%1'"},
621 {
"^\\&(.*[^[:space:]])[[:space:]]*$",
622 "breakpoint set --name '%1' --skip-prologue=0"},
623 {
"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$",
624 "breakpoint set --name '%1'"}};
627 size_t num_regexes = std::size(break_regexes);
629 std::unique_ptr<CommandObjectRegexCommand> break_regex_cmd_up(
631 *
this,
"_regexp-break",
632 "Set a breakpoint using one of several shorthand formats, or list "
633 "the existing breakpoints if no arguments are provided.",
635 "_regexp-break <filename>:<linenum>:<colnum>\n"
636 " main.c:12:21 // Break at line 12 and column "
638 "_regexp-break <filename>:<linenum>\n"
639 " main.c:12 // Break at line 12 of "
641 "_regexp-break <linenum>\n"
642 " 12 // Break at line 12 of current "
644 "_regexp-break 0x<address>\n"
645 " 0x1234000 // Break at address "
647 "_regexp-break <name>\n"
648 " main // Break in 'main' after the "
650 "_regexp-break &<name>\n"
651 " &main // Break at first instruction "
653 "_regexp-break <module>`<name>\n"
654 " libc.so`malloc // Break in 'malloc' from "
656 "_regexp-break /<source-regex>/\n"
657 " /break here/ // Break on source lines in "
659 " // containing text 'break "
662 " // List the existing "
666 if (break_regex_cmd_up) {
668 for (
size_t i = 0; i < num_regexes; i++) {
669 success = break_regex_cmd_up->AddRegexCommand(break_regexes[i][0],
670 break_regexes[i][1]);
675 break_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
679 m_command_dict[std::string(break_regex_cmd_sp->GetCommandName())] =
688 const char *break_add_regexes[][2] = {
689 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
690 "breakpoint add file --file '%1' --line %2 --column %3"},
691 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
692 "breakpoint add file --file '%1' --line %2"},
693 {
"^/([^/]+)/$",
"breakpoint add pattern -- %1"},
694 {
"^([[:digit:]]+)[[:space:]]*$",
695 "breakpoint add file --line %1"},
696 {
"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
697 "breakpoint add address %1"},
698 {
"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$",
699 "breakpoint add name '%1'"},
701 "breakpoint add name '%1'"},
702 {
"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$",
703 "breakpoint add name '%2' --shlib '%1'"},
704 {
"^\\&(.*[^[:space:]])[[:space:]]*$",
705 "breakpoint add name '%1' --skip-prologue=0"},
706 {
"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$",
707 "breakpoint add name '%1'"}};
710 size_t num_add_regexes = std::size(break_add_regexes);
712 std::unique_ptr<CommandObjectRegexCommand> break_add_regex_cmd_up(
714 *
this,
"_regexp-break-add",
715 "Set a breakpoint using one of several shorthand formats, or list "
716 "the existing breakpoints if no arguments are provided.",
718 "_regexp-break-add <filename>:<linenum>:<colnum>\n"
719 " main.c:12:21 // Break at line 12 and column "
721 "_regexp-break-add <filename>:<linenum>\n"
722 " main.c:12 // Break at line 12 of "
724 "_regexp-break-add <linenum>\n"
725 " 12 // Break at line 12 of current "
727 "_regexp-break-add 0x<address>\n"
728 " 0x1234000 // Break at address "
730 "_regexp-break-add <name>\n"
731 " main // Break in 'main' after the "
733 "_regexp-break-add &<name>\n"
734 " &main // Break at first instruction "
736 "_regexp-break-add <module>`<name>\n"
737 " libc.so`malloc // Break in 'malloc' from "
739 "_regexp-break-add /<source-regex>/\n"
740 " /break here/ // Break on source lines in "
742 " // containing text 'break "
744 "_regexp-break-add\n"
745 " // List the existing "
749 if (break_add_regex_cmd_up) {
751 for (
size_t i = 0; i < num_add_regexes; i++) {
752 success = break_add_regex_cmd_up->AddRegexCommand(
753 break_add_regexes[i][0], break_add_regexes[i][1]);
758 break_add_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
761 CommandObjectSP break_add_regex_cmd_sp(break_add_regex_cmd_up.release());
762 m_command_dict[std::string(break_add_regex_cmd_sp->GetCommandName())] =
763 break_add_regex_cmd_sp;
767 std::unique_ptr<CommandObjectRegexCommand> tbreak_regex_cmd_up(
769 *
this,
"_regexp-tbreak",
770 "Set a one-shot breakpoint using one of several shorthand formats.",
772 "_regexp-break <filename>:<linenum>:<colnum>\n"
773 " main.c:12:21 // Break at line 12 and column "
775 "_regexp-break <filename>:<linenum>\n"
776 " main.c:12 // Break at line 12 of "
778 "_regexp-break <linenum>\n"
779 " 12 // Break at line 12 of current "
781 "_regexp-break 0x<address>\n"
782 " 0x1234000 // Break at address "
784 "_regexp-break <name>\n"
785 " main // Break in 'main' after the "
787 "_regexp-break &<name>\n"
788 " &main // Break at first instruction "
790 "_regexp-break <module>`<name>\n"
791 " libc.so`malloc // Break in 'malloc' from "
793 "_regexp-break /<source-regex>/\n"
794 " /break here/ // Break on source lines in "
796 " // containing text 'break "
800 if (tbreak_regex_cmd_up) {
802 for (
size_t i = 0; i < num_regexes; i++) {
803 std::string command = break_regexes[i][1];
806 tbreak_regex_cmd_up->AddRegexCommand(break_regexes[i][0], command);
811 tbreak_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
815 m_command_dict[std::string(tbreak_regex_cmd_sp->GetCommandName())] =
820 std::unique_ptr<CommandObjectRegexCommand> attach_regex_cmd_up(
822 *
this,
"_regexp-attach",
"Attach to process by ID or name.",
823 "_regexp-attach <pid> | <process-name>", 0,
false));
824 if (attach_regex_cmd_up) {
825 if (attach_regex_cmd_up->AddRegexCommand(
"^([0-9]+)[[:space:]]*$",
826 "process attach --pid %1") &&
827 attach_regex_cmd_up->AddRegexCommand(
828 "^(-.*|.* -.*)$",
"process attach %1") &&
831 attach_regex_cmd_up->AddRegexCommand(
"^(.+)$",
832 "process attach --name '%1'") &&
833 attach_regex_cmd_up->AddRegexCommand(
"^$",
"process attach")) {
835 m_command_dict[std::string(attach_regex_cmd_sp->GetCommandName())] =
840 std::unique_ptr<CommandObjectRegexCommand> down_regex_cmd_up(
842 "Select a newer stack frame. Defaults to "
843 "moving one frame, a numeric argument can "
844 "specify an arbitrary number.",
845 "_regexp-down [<count>]", 0,
false));
846 if (down_regex_cmd_up) {
847 if (down_regex_cmd_up->AddRegexCommand(
"^$",
"frame select -r -1") &&
848 down_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
849 "frame select -r -%1")) {
851 m_command_dict[std::string(down_regex_cmd_sp->GetCommandName())] =
856 std::unique_ptr<CommandObjectRegexCommand> up_regex_cmd_up(
859 "Select an older stack frame. Defaults to moving one "
860 "frame, a numeric argument can specify an arbitrary number.",
861 "_regexp-up [<count>]", 0,
false));
862 if (up_regex_cmd_up) {
863 if (up_regex_cmd_up->AddRegexCommand(
"^$",
"frame select -r 1") &&
864 up_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
"frame select -r %1")) {
871 std::unique_ptr<CommandObjectRegexCommand> display_regex_cmd_up(
873 *
this,
"_regexp-display",
874 "Evaluate an expression at every stop (see 'help target stop-hook'.)",
875 "_regexp-display expression", 0,
false));
876 if (display_regex_cmd_up) {
877 if (display_regex_cmd_up->AddRegexCommand(
878 "^(.+)$",
"target stop-hook add -o \"expr -- %1\"")) {
880 m_command_dict[std::string(display_regex_cmd_sp->GetCommandName())] =
881 display_regex_cmd_sp;
885 std::unique_ptr<CommandObjectRegexCommand> undisplay_regex_cmd_up(
887 "Stop displaying expression at every "
888 "stop (specified by stop-hook index.)",
889 "_regexp-undisplay stop-hook-number", 0,
891 if (undisplay_regex_cmd_up) {
892 if (undisplay_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
893 "target stop-hook delete %1")) {
894 CommandObjectSP undisplay_regex_cmd_sp(undisplay_regex_cmd_up.release());
895 m_command_dict[std::string(undisplay_regex_cmd_sp->GetCommandName())] =
896 undisplay_regex_cmd_sp;
900 std::unique_ptr<CommandObjectRegexCommand> connect_gdb_remote_cmd_up(
903 "Connect to a process via remote GDB server.\n"
904 "If no host is specified, localhost is assumed.\n"
905 "gdb-remote is an abbreviation for 'process connect --plugin "
906 "gdb-remote connect://<hostname>:<port>'\n",
907 "gdb-remote [<hostname>:]<portnum>", 0,
false));
908 if (connect_gdb_remote_cmd_up) {
909 if (connect_gdb_remote_cmd_up->AddRegexCommand(
910 "^([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)$",
911 "process connect --plugin gdb-remote connect://%1:%2") &&
912 connect_gdb_remote_cmd_up->AddRegexCommand(
914 "process connect --plugin gdb-remote connect://localhost:%1")) {
916 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
920 std::unique_ptr<CommandObjectRegexCommand> connect_kdp_remote_cmd_up(
923 "Connect to a process via remote KDP server.\n"
924 "If no UDP port is specified, port 41139 is assumed.\n"
925 "kdp-remote is an abbreviation for 'process connect --plugin "
926 "kdp-remote udp://<hostname>:<port>'\n",
927 "kdp-remote <hostname>[:<portnum>]", 0,
false));
928 if (connect_kdp_remote_cmd_up) {
929 if (connect_kdp_remote_cmd_up->AddRegexCommand(
930 "^([^:]+:[[:digit:]]+)$",
931 "process connect --plugin kdp-remote udp://%1") &&
932 connect_kdp_remote_cmd_up->AddRegexCommand(
933 "^(.+)$",
"process connect --plugin kdp-remote udp://%1:41139")) {
935 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
939 std::unique_ptr<CommandObjectRegexCommand> bt_regex_cmd_up(
942 "Show backtrace of the current thread's call stack. Any numeric "
943 "argument displays at most that many frames. The argument 'all' "
944 "displays all threads. Use 'settings set frame-format' to customize "
945 "the printing of individual frames and 'settings set thread-format' "
946 "to customize the thread header. Frame recognizers may filter the "
947 "list. Use 'thread backtrace -u (--unfiltered)' to see them all.",
948 "bt [<digit> | all]", 0,
false));
949 if (bt_regex_cmd_up) {
954 if (bt_regex_cmd_up->AddRegexCommand(
"^([[:digit:]]+)[[:space:]]*$",
955 "thread backtrace -c %1") &&
956 bt_regex_cmd_up->AddRegexCommand(
"^(-[^[:space:]].*)$",
957 "thread backtrace %1") &&
958 bt_regex_cmd_up->AddRegexCommand(
"^all[[:space:]]*$",
959 "thread backtrace all") &&
960 bt_regex_cmd_up->AddRegexCommand(
"^[[:space:]]*$",
961 "thread backtrace")) {
963 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
967 std::unique_ptr<CommandObjectRegexCommand> list_regex_cmd_up(
969 *
this,
"_regexp-list",
970 "List relevant source code using one of several shorthand formats.",
972 "_regexp-list <file>:<line> // List around specific file/line\n"
973 "_regexp-list <line> // List current file around specified "
975 "_regexp-list <function-name> // List specified function\n"
976 "_regexp-list 0x<address> // List around specified address\n"
977 "_regexp-list -[<count>] // List previous <count> lines\n"
978 "_regexp-list // List subsequent lines",
980 if (list_regex_cmd_up) {
981 if (list_regex_cmd_up->AddRegexCommand(
"^([0-9]+)[[:space:]]*$",
982 "source list --line %1") &&
983 list_regex_cmd_up->AddRegexCommand(
984 "^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]"
986 "source list --file '%1' --line %2") &&
987 list_regex_cmd_up->AddRegexCommand(
988 "^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
989 "source list --address %1") &&
990 list_regex_cmd_up->AddRegexCommand(
"^-[[:space:]]*$",
991 "source list --reverse") &&
992 list_regex_cmd_up->AddRegexCommand(
993 "^-([[:digit:]]+)[[:space:]]*$",
994 "source list --reverse --count %1") &&
995 list_regex_cmd_up->AddRegexCommand(
"^(.+)$",
996 "source list --name \"%1\"") &&
997 list_regex_cmd_up->AddRegexCommand(
"^$",
"source list")) {
999 m_command_dict[std::string(list_regex_cmd_sp->GetCommandName())] =
1004 std::unique_ptr<CommandObjectRegexCommand> env_regex_cmd_up(
1006 *
this,
"_regexp-env",
1007 "Shorthand for viewing and setting environment variables.",
1009 "_regexp-env // Show environment\n"
1010 "_regexp-env <name>=<value> // Set an environment variable",
1012 if (env_regex_cmd_up) {
1013 if (env_regex_cmd_up->AddRegexCommand(
"^$",
1014 "settings show target.env-vars") &&
1015 env_regex_cmd_up->AddRegexCommand(
"^([A-Za-z_][A-Za-z_0-9]*=.*)$",
1016 "settings set target.env-vars %1")) {
1018 m_command_dict[std::string(env_regex_cmd_sp->GetCommandName())] =
1023 std::unique_ptr<CommandObjectRegexCommand> jump_regex_cmd_up(
1025 *
this,
"_regexp-jump",
"Set the program counter to a new address.",
1027 "_regexp-jump <line>\n"
1028 "_regexp-jump +<line-offset> | -<line-offset>\n"
1029 "_regexp-jump <file>:<line>\n"
1030 "_regexp-jump *<addr>\n",
1032 if (jump_regex_cmd_up) {
1033 if (jump_regex_cmd_up->AddRegexCommand(
"^\\*(.*)$",
1034 "thread jump --addr %1") &&
1035 jump_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
1036 "thread jump --line %1") &&
1037 jump_regex_cmd_up->AddRegexCommand(
"^([^:]+):([0-9]+)$",
1038 "thread jump --file %1 --line %2") &&
1039 jump_regex_cmd_up->AddRegexCommand(
"^([+\\-][0-9]+)$",
1040 "thread jump --by %1")) {
1042 m_command_dict[std::string(jump_regex_cmd_sp->GetCommandName())] =
1047 std::shared_ptr<CommandObjectRegexCommand> step_regex_cmd_sp(
1049 *
this,
"_regexp-step",
1050 "Single step, optionally to a specific function.",
1052 "_regexp-step // Single step\n"
1053 "_regexp-step <function-name> // Step into the named function\n",
1055 if (step_regex_cmd_sp) {
1056 if (step_regex_cmd_sp->AddRegexCommand(
"^[[:space:]]*$",
1057 "thread step-in") &&
1058 step_regex_cmd_sp->AddRegexCommand(
"^[[:space:]]*(-.+)$",
1059 "thread step-in %1") &&
1060 step_regex_cmd_sp->AddRegexCommand(
1061 "^[[:space:]]*(.+)[[:space:]]*$",
1062 "thread step-in --end-linenumber block --step-in-target %1")) {
1063 m_command_dict[std::string(step_regex_cmd_sp->GetCommandName())] =
1070 const char *cmd_str,
bool include_aliases,
StringList &matches,
1075 if (include_aliases) {
1088 auto get_multi_or_report_error =
1093 "Path component: '%s' not found", name);
1096 if (!cmd_sp->IsUserCommand()) {
1098 "Path component: '%s' is not a user "
1104 if (!cmd_as_multi) {
1106 "Path component: '%s' is not a container "
1111 return cmd_as_multi;
1115 if (num_args == 0) {
1120 if (num_args == 1 && leaf_is_command) {
1130 get_multi_or_report_error(cur_cmd_sp, cur_name);
1131 if (cur_as_multi ==
nullptr)
1134 size_t num_path_elements = num_args - (leaf_is_command ? 1 : 0);
1135 for (
size_t cursor = 1; cursor < num_path_elements && cur_as_multi !=
nullptr;
1139 cur_as_multi = get_multi_or_report_error(cur_cmd_sp, cur_name);
1141 return cur_as_multi;
1148 auto frame_language =
1161 auto lang_name =
plugin->GetPluginName();
1163 return language_cmd_sp->GetSubcommandSPExact(lang_name);
1172 std::string cmd = std::string(cmd_str);
1177 command_sp = pos->second;
1183 command_sp = alias_pos->second;
1189 command_sp = pos->second;
1195 command_sp = pos->second;
1200 if (!exact && !command_sp) {
1206 if (matches ==
nullptr)
1207 matches = &local_matches;
1209 unsigned int num_cmd_matches = 0;
1210 unsigned int num_alias_matches = 0;
1211 unsigned int num_user_matches = 0;
1212 unsigned int num_user_mw_matches = 0;
1220 *matches, descriptions);
1223 if (num_cmd_matches == 1) {
1227 real_match_sp = pos->second;
1232 *matches, descriptions);
1235 if (num_alias_matches == 1) {
1239 alias_match_sp = alias_pos->second;
1244 *matches, descriptions);
1247 if (num_user_matches == 1) {
1253 user_match_sp = pos->second;
1261 if (num_user_mw_matches == 1) {
1267 user_mw_match_sp = pos->second;
1273 if (num_user_matches + num_user_mw_matches + num_cmd_matches +
1274 num_alias_matches ==
1276 if (num_cmd_matches)
1277 return real_match_sp;
1278 else if (num_alias_matches)
1279 return alias_match_sp;
1280 else if (num_user_mw_matches)
1281 return user_mw_match_sp;
1283 return user_match_sp;
1294 command_sp = lang_subcmd_sp->GetSubcommandSPExact(cmd_str);
1297 if (!command_sp && !exact && lang_subcmd) {
1300 cmd_str, lang_matches, descriptions);
1303 if (lang_matches.
GetSize() == 1) {
1305 auto pos = lang_dict.find(lang_matches[0]);
1306 if (pos != lang_dict.end())
1312 if (matches && command_sp) {
1325 lldbassert((
this == &cmd_sp->GetCommandInterpreter()) &&
1326 "tried to add a CommandObject from a different interpreter");
1331 cmd_sp->SetIsUserCommand(
false);
1333 std::string name_sstr(name);
1336 if (!can_replace || !name_iter->second->IsRemovable())
1338 name_iter->second = cmd_sp;
1350 lldbassert((
this == &cmd_sp->GetCommandInterpreter()) &&
1351 "tried to add a CommandObject from a different interpreter");
1354 "can't use the empty string for a command name");
1366 "user command \"{0}\" already exists and force replace was not set "
1367 "by --overwrite or 'settings set interpreter.require-overwrite "
1372 if (cmd_sp->IsMultiwordObject()) {
1375 "can't replace explicitly non-removable multi-word command");
1379 if (!
m_user_dict[std::string(name)]->IsRemovable()) {
1381 "can't replace explicitly non-removable command");
1387 cmd_sp->SetIsUserCommand(
true);
1389 if (cmd_sp->IsMultiwordObject())
1398 bool include_aliases)
const {
1400 Args cmd_words(cmd_str);
1402 if (cmd_str.empty())
1419 for (
size_t i = 1; i < end; ++i) {
1420 if (!cmd_obj_sp->IsMultiwordObject()) {
1445 matches, descriptions)
1451 std::string cmd_str(cmd);
1453 auto found_elem = map.find(cmd);
1454 if (found_elem == map.end())
1477 StringList *matches_ptr = matches ? matches : &tmp_list;
1489 auto found_elem = map.find(cmd);
1490 if (found_elem == map.end())
1512 StringList *matches_ptr = matches ? matches : &tmp_list;
1523 std::string &full_name)
const {
1526 full_name.assign(std::string(cmd));
1530 size_t num_alias_matches;
1533 if (num_alias_matches == 1) {
1536 const bool include_aliases =
false;
1537 const bool exact =
false;
1539 GetCommandSP(cmd, include_aliases, exact, ®ular_matches));
1540 if (cmd_obj_sp || regular_matches.
GetSize() > 0)
1567 llvm::StringRef args_string) {
1568 if (command_obj_sp.get())
1569 lldbassert((
this == &command_obj_sp->GetCommandInterpreter()) &&
1570 "tried to add a CommandObject from a different interpreter");
1572 std::unique_ptr<CommandAlias> command_alias_up(
1573 new CommandAlias(*
this, command_obj_sp, args_string, alias_name));
1575 if (command_alias_up && command_alias_up->IsValid()) {
1578 return command_alias_up.release();
1596 if (force || pos->second->IsRemovable()) {
1607 CommandObject::CommandMap::iterator pos =
m_user_dict.find(user_name);
1616 CommandObject::CommandMap::iterator pos =
m_user_mw_dict.find(multi_name);
1625 uint32_t cmd_types) {
1626 llvm::StringRef help_prologue(
GetDebugger().GetIOHandlerHelpPrologue());
1627 if (!help_prologue.empty()) {
1632 CommandObject::CommandMap::const_iterator pos;
1641 (pos->first.compare(0, 1,
"_") == 0))
1645 pos->second->GetHelp(), max_len);
1653 "Current command abbreviations "
1654 "(type '{0}help command alias' for more info):",
1662 alias_pos->second->GetHelp(), max_len);
1674 pos->second->GetHelp(), max_len);
1681 result.
AppendMessage(
"Current user-defined container commands:");
1686 pos->second->GetHelp(), max_len);
1692 "For more information on any command, type '{0}help <command-name>'.",
1697 llvm::StringRef &command_string) {
1703 size_t start = command_string.find_first_not_of(
k_white_space);
1707 if (start != std::string::npos) {
1710 if (end == std::string::npos)
1711 end = command_string.size();
1712 std::string cmd_word =
1713 std::string(command_string.substr(start, end - start));
1715 if (cmd_obj ==
nullptr)
1725 cmd_obj = sub_cmd_obj;
1737 end >= command_string.size())
1740 start = command_string.find_first_not_of(
k_white_space, end);
1746 command_string = command_string.substr(end);
1751 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
1755 if (pos == std::string::npos)
1764 const size_t s_len = s.size();
1766 while (offset < s_len) {
1767 size_t pos = s.find(
"--", offset);
1768 if (pos == std::string::npos)
1771 if (llvm::isSpace(s[pos - 1])) {
1774 if ((pos + 2 >= s_len) || llvm::isSpace(s[pos + 2])) {
1781 return std::string::npos;
1785 std::string &suffix,
char "e_char) {
1790 bool result =
false;
1793 if (!command_string.empty()) {
1794 const char first_char = command_string[0];
1795 if (first_char ==
'\'' || first_char ==
'"') {
1796 quote_char = first_char;
1797 const size_t end_quote_pos = command_string.find(quote_char, 1);
1798 if (end_quote_pos == std::string::npos) {
1799 command.swap(command_string);
1800 command_string.erase();
1802 command.assign(command_string, 1, end_quote_pos - 1);
1803 if (end_quote_pos + 1 < command_string.size())
1804 command_string.erase(0, command_string.find_first_not_of(
1807 command_string.erase();
1810 const size_t first_space_pos =
1812 if (first_space_pos == std::string::npos) {
1813 command.swap(command_string);
1814 command_string.erase();
1816 command.assign(command_string, 0, first_space_pos);
1817 command_string.erase(0, command_string.find_first_not_of(
1824 if (!command.empty()) {
1826 if (command[0] !=
'-' && command[0] !=
'_') {
1828 if (pos > 0 && pos != std::string::npos) {
1829 suffix.assign(command.begin() + pos, command.end());
1839 llvm::StringRef alias_name, std::string &raw_input_string,
1842 Args cmd_args(raw_input_string);
1846 if (!alias_cmd_obj || !alias_cmd_obj->
IsAlias()) {
1847 alias_result.clear();
1848 return alias_cmd_obj;
1850 std::pair<CommandObjectSP, OptionArgVectorSP> desugared =
1853 alias_cmd_obj = desugared.first.get();
1854 std::string alias_name_str = std::string(alias_name);
1857 cmd_args.
Unshift(alias_name_str);
1861 if (!option_arg_vector_sp.get()) {
1862 alias_result = std::string(result_str.
GetString());
1863 return alias_cmd_obj;
1870 for (
const auto &entry : *option_arg_vector) {
1871 std::tie(option, value_type, value) = entry;
1873 result_str.
Printf(
" %s", value.c_str());
1877 result_str.
Printf(
" %s", option.c_str());
1885 result_str.
Printf(
"%s", value.c_str());
1889 "need at least %d arguments to use "
1895 size_t strpos = raw_input_string.find(entry.
c_str());
1897 if (strpos != std::string::npos) {
1898 const size_t start_fudge = quote_char ==
'\0' ? 0 : 1;
1899 const size_t len_fudge = quote_char ==
'\0' ? 0 : 2;
1902 if (strpos < start_fudge) {
1903 result.
AppendError(
"unmatched quote at command beginning");
1906 llvm::StringRef arg_text = entry.
ref();
1907 if (strpos - start_fudge + arg_text.size() + len_fudge >
1908 raw_input_string.size()) {
1909 result.
AppendError(
"unmatched quote at command end");
1912 raw_input_string = raw_input_string.erase(
1913 strpos - start_fudge,
1916 if (quote_char ==
'\0')
1919 result_str.
Printf(
"%c%s%c", quote_char, entry.
c_str(), quote_char);
1923 alias_result = std::string(result_str.
GetString());
1924 return alias_cmd_obj;
1935 size_t start_backtick;
1937 while ((start_backtick = command.find(
'`', pos)) != std::string::npos) {
1942 if (start_backtick > 0 && command[start_backtick - 1] ==
'\\') {
1945 command.erase(start_backtick - 1, 1);
1947 pos = start_backtick;
1951 const size_t expr_content_start = start_backtick + 1;
1952 const size_t end_backtick = command.find(
'`', expr_content_start);
1954 if (end_backtick == std::string::npos) {
1959 if (end_backtick == expr_content_start) {
1961 command.erase(start_backtick, 2);
1965 std::string expr_str(command, expr_content_start,
1966 end_backtick - expr_content_start);
1972 command.erase(start_backtick, end_backtick - start_backtick + 1);
1973 command.insert(start_backtick, std::string(expr_str));
1974 pos = start_backtick + expr_str.size();
1996 expr_str.c_str(), exe_ctx.
GetFramePtr(), expr_result_valobj_sp, options);
2000 if (expr_result_valobj_sp)
2001 expr_result_valobj_sp =
2002 expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable(
2003 expr_result_valobj_sp->GetDynamicValueType(),
true);
2004 if (expr_result_valobj_sp->ResolveValue(scalar)) {
2007 const bool show_type =
false;
2008 scalar.
GetValue(value_strm, show_type);
2009 size_t value_string_size = value_strm.
GetSize();
2010 if (value_string_size) {
2011 expr_str = value_strm.
GetData();
2015 "in a scalar value for the "
2022 "in a scalar value for the "
2033 if (expr_result_valobj_sp)
2034 error = expr_result_valobj_sp->GetError().Clone();
2036 if (
error.Success()) {
2038 "for the expression '" + expr_str +
"'";
2050 bool status =
HandleCommand(command_line, lazy_add_to_history, result);
2058 bool force_repeat_command) {
2063 std::string parsed_command_args;
2067 const bool detailed_command_telemetry =
2073 std::string command_string(command_line);
2074 std::string original_command_string(command_string);
2075 std::string real_original_command_string(command_string);
2081 info->
target_uuid = target->GetExecutableModule() !=
nullptr
2082 ? target->GetExecutableModule()->GetUUID()
2085 if (detailed_command_telemetry)
2092 detailed_command_telemetry, command_id](
2098 llvm::StringRef command_name =
2102 if (std::string error_str = result.
GetErrorString(); !error_str.empty())
2105 if (detailed_command_telemetry)
2106 info->
args = parsed_command_args;
2110 LLDB_LOGF(log,
"Processing command: %s", command_line);
2122 bool add_to_history;
2126 add_to_history = (lazy_add_to_history ==
eLazyBoolYes);
2134 transcript_item = std::make_shared<StructuredData::Dictionary>();
2135 transcript_item->AddStringItem(
"command", command_line);
2136 transcript_item->AddIntegerItem(
2137 "timestampInEpochSeconds",
2138 std::chrono::duration_cast<std::chrono::seconds>(
2139 std::chrono::system_clock::now().time_since_epoch())
2144 bool empty_command =
false;
2145 bool comment_command =
false;
2146 if (command_string.empty())
2147 empty_command =
true;
2149 const char *k_space_characters =
"\t\n\v\f\r ";
2151 size_t non_space = command_string.find_first_not_of(k_space_characters);
2154 if (non_space == std::string::npos)
2155 empty_command =
true;
2157 comment_command =
true;
2159 llvm::StringRef search_str(command_string);
2160 search_str = search_str.drop_front(non_space);
2162 add_to_history =
false;
2163 command_string = std::string(*hist_str);
2164 original_command_string = std::string(*hist_str);
2167 command_string.c_str());
2173 if (empty_command) {
2185 command_string = command_line;
2186 original_command_string = command_line;
2192 add_to_history =
false;
2193 }
else if (comment_command) {
2233 llvm::StringRef command_name =
2235 LLDB_LOGF(log,
"HandleCommand, cmd_obj : '%s'", command_name.str().c_str());
2236 LLDB_LOGF(log,
"HandleCommand, (revised) command_string: '%s'",
2237 command_string.c_str());
2238 const bool wants_raw_input =
2240 LLDB_LOGF(log,
"HandleCommand, wants_raw_input:'%s'",
2241 wants_raw_input ?
"True" :
"False");
2249 if (cmd_obj !=
nullptr) {
2250 bool generate_repeat_command = add_to_history;
2254 generate_repeat_command |= empty_command;
2259 generate_repeat_command |= force_repeat_command;
2260 if (generate_repeat_command) {
2261 Args command_args(command_string);
2262 std::optional<std::string> repeat_command =
2264 if (repeat_command) {
2265 LLDB_LOGF(log,
"Repeat command: %s", repeat_command->data());
2275 const std::size_t actual_cmd_name_len = cmd_obj->
GetCommandName().size();
2276 if (actual_cmd_name_len < command_string.length())
2277 parsed_command_args = command_string.substr(actual_cmd_name_len);
2280 size_t pos = parsed_command_args.find_first_not_of(
k_white_space);
2281 if (pos != 0 && pos != std::string::npos)
2282 parsed_command_args.erase(0, pos);
2285 log,
"HandleCommand, command line after removing command name(s): '%s'",
2286 parsed_command_args.c_str());
2291 if (transcript_item) {
2292 transcript_item->AddStringItem(
"commandName", cmd_obj->
GetCommandName());
2293 transcript_item->AddStringItem(
"commandArguments", parsed_command_args);
2299 pos = real_original_command_string.rfind(parsed_command_args);
2300 std::optional<uint16_t> indent;
2301 if (pos != std::string::npos)
2304 cmd_obj->
Execute(parsed_command_args.c_str(), result);
2307 LLDB_LOGF(log,
"HandleCommand, command %s",
2308 (result.
Succeeded() ?
"succeeded" :
"did not succeed"));
2313 if (transcript_item) {
2318 transcript_item->AddStringItem(
"error", result.
GetErrorString());
2319 transcript_item->AddFloatItem(
"durationInSeconds",
2320 execute_time.
get().count());
2327 bool look_for_subcommand =
false;
2333 bool include_aliases =
true;
2344 &new_matches, &new_descriptions);
2351 look_for_subcommand =
true;
2366 if (command_object) {
2379 if (!first_arg.empty()) {
2384 request.
AddCompletion(*hist_str,
"Previous command history event",
2393std::optional<std::string>
2396 return std::nullopt;
2398 for (
int i = s - 1; i >= 0; --i) {
2400 if (entry.consume_front(line))
2403 return std::nullopt;
2407 EventSP prompt_change_event_sp(
2423 return default_answer;
2460 const char *alias_name,
2462 std::string &raw_input_string,
2470 std::string alias_name_str = alias_name;
2472 cmd_args.
Unshift(alias_name_str);
2478 if (option_arg_vector_sp.get()) {
2479 if (wants_raw_input) {
2483 size_t pos = raw_input_string.find(
" -- ");
2484 if (pos == std::string::npos) {
2486 raw_input_string.insert(0,
" -- ");
2492 std::vector<bool> used(old_size + 1,
false);
2499 for (
const auto &option_entry : *option_arg_vector) {
2500 std::tie(option, value_type, value) = option_entry;
2502 if (!wants_raw_input || (value !=
"--")) {
2526 "need at least %d arguments to use "
2534 if (strpos != std::string::npos) {
2535 raw_input_string = raw_input_string.erase(
2548 for (
auto entry : llvm::enumerate(cmd_args.
entries())) {
2549 if (!used[entry.index()] && !wants_raw_input)
2562 if (wants_raw_input) {
2578 const char *cptr = in_string;
2581 if (cptr[0] ==
'%') {
2585 if (isdigit(cptr[0])) {
2586 const char *start = cptr;
2587 while (isdigit(cptr[0]))
2592 if (cptr[0] ==
'\0')
2593 position = atoi(start);
2601 std::string init_file_name =
".lldbinit";
2602 if (!suffix.empty()) {
2603 init_file_name.append(
"-");
2604 init_file_name.append(suffix.str());
2615 language = *main_repl_language;
2620 std::string init_file_name =
2621 (llvm::Twine(
".lldbinit-") +
2623 llvm::Twine(
"-repl"))
2631 llvm::StringRef s =
".lldbinit";
2632 init_file.assign(s.begin(), s.end());
2664 llvm::SmallString<128> init_file;
2674 switch (should_load) {
2684 if (llvm::sys::path::parent_path(init_file) ==
2685 llvm::sys::path::parent_path(home_init_file.
GetPath())) {
2710 if (init_file.
GetPath().empty())
2714 llvm::StringRef program_name = HostInfo::GetProgramFileSpec().GetFilename();
2718 init_file = program_init_file;
2725#ifdef LLDB_GLOBAL_INIT_DIRECTORY
2727 FileSpec init_file(LLDB_GLOBAL_INIT_DIRECTORY);
2741 return prefix ==
nullptr ?
"" : prefix;
2746 if (prefer_target_platform) {
2754 platform_sp =
m_debugger.GetPlatformList().GetSelectedPlatform();
2760 TargetSP target_sp = exe_ctx.GetTargetSP();
2764 ProcessSP process_sp(target_sp->GetProcessSP());
2771 for (
const auto &thread_sp : process_sp->GetThreadList().Threads()) {
2772 StopInfoSP stop_info = thread_sp->GetStopInfo();
2780 const StopReason reason = stop_info->GetStopReason();
2788 const auto stop_signal =
static_cast<int32_t
>(stop_info->GetValue());
2790 if (!signals_sp || !signals_sp->SignalIsValid(stop_signal))
2794 const auto sigint_num = signals_sp->GetSignalNumberFromName(
"SIGINT");
2795 const auto sigstop_num = signals_sp->GetSignalNumberFromName(
"SIGSTOP");
2796 if ((stop_signal != sigint_num) && (stop_signal != sigstop_num))
2817 size_t num_lines = commands.
GetSize();
2823 bool old_async_execution =
m_debugger.GetAsyncExecution();
2829 for (
size_t idx = 0; idx < num_lines; idx++) {
2837 "{0} {1}",
m_debugger.GetPrompt().str().c_str(), cmd);
2858 if (!success || !tmp_result.
Succeeded()) {
2860 if (error_msg.empty())
2861 error_msg =
"<unknown error>.\n";
2864 "command #{0}: '{1}' failed with {2}",
2865 (uint64_t)idx, cmd, error_msg);
2866 m_debugger.SetAsyncExecution(old_async_execution);
2871 (uint64_t)idx + 1, cmd, error_msg);
2892 if (idx != num_lines - 1)
2894 "Aborting reading of commands after command #%" PRIu64
2895 ": '%s' continued the target",
2896 (uint64_t)idx + 1, cmd);
2899 "Command #{0} '{1}' continued the target.", (uint64_t)idx + 1,
2903 m_debugger.SetAsyncExecution(old_async_execution);
2912 if (idx != num_lines - 1)
2914 "Aborting reading of commands after command #%" PRIu64
2915 ": '%s' stopped with a signal or exception",
2916 (uint64_t)idx + 1, cmd);
2919 "Command #{0} '{1}' stopped with a signal or exception.",
2920 (uint64_t)idx + 1, cmd);
2923 m_debugger.SetAsyncExecution(old_async_execution);
2930 m_debugger.SetAsyncExecution(old_async_execution);
2959 "Error reading commands from file {0} - file not found",
2964 std::string cmd_file_path = cmd_file.
GetPath();
2965 auto input_file_up =
2967 if (!input_file_up) {
2969 "error: an error occurred read file '{0}': {1}\n", cmd_file_path,
2970 llvm::fmt_consume(input_file_up.takeError()));
2973 FileSP input_file_sp =
FileSP(std::move(input_file_up.get()));
3060 cmd_file_path.c_str());
3076 debugger.
GetPrompt(), llvm::StringRef(),
3106 Stream &strm, llvm::StringRef prefix, llvm::StringRef help_text,
3107 std::optional<Stream::HighlightSettings> highlight) {
3108 const uint32_t max_columns =
m_debugger.GetTerminalWidth();
3110 size_t line_width_max = max_columns - prefix.size();
3111 if (line_width_max < 16)
3112 line_width_max = help_text.size() + prefix.size();
3116 std::string highlighted_storage;
3120 highlighted_storage = std::string(ss.
GetString());
3121 help_text = highlighted_storage;
3125 bool prefixed_yet =
false;
3127 if (help_text.empty())
3128 help_text =
"No help text";
3129 while (!help_text.empty()) {
3131 if (!prefixed_yet) {
3133 prefixed_yet =
true;
3138 llvm::StringRef this_line = help_text.substr(0, line_width_max);
3141 std::size_t first_newline = this_line.find_first_of(
"\n");
3144 std::size_t last_space = llvm::StringRef::npos;
3145 if (this_line.size() != help_text.size())
3146 last_space = this_line.find_last_of(
" \t");
3149 this_line = this_line.substr(0, std::min(first_newline, last_space));
3154 help_text = help_text.drop_front(this_line.size()).ltrim();
3160 Stream &strm, llvm::StringRef word_text, llvm::StringRef separator,
3161 llvm::StringRef help_text,
size_t max_word_len,
3162 std::optional<Stream::HighlightSettings> highlight) {
3164 prefix_stream.
Printf(
" %-*s %*s ", (
int)max_word_len, word_text.data(),
3165 (
int)separator.size(), separator.data());
3171 llvm::StringRef separator,
3172 llvm::StringRef help_text,
3173 uint32_t max_word_len) {
3174 int indent_size = max_word_len + separator.size() + 2;
3179 text_strm.
Printf(
"%-*s ", (
int)max_word_len, word_text.data());
3180 text_strm << separator <<
" " << help_text;
3182 const uint32_t max_columns =
m_debugger.GetTerminalWidth();
3184 llvm::StringRef text = text_strm.
GetString();
3186 uint32_t chars_left = max_columns;
3188 auto start_new_line = [&] {
3191 chars_left = max_columns - indent_size;
3194 while (!text.empty()) {
3195 if (text.starts_with(
'\n')) {
3196 text = text.drop_front();
3205 size_t word_start_pos = text.find_first_not_of(
' ');
3206 size_t word_end_pos = text.find_first_of(
" \n", word_start_pos);
3207 size_t fragment_size =
3208 word_end_pos == llvm::StringRef::npos ? text.size() : word_end_pos;
3210 if (fragment_size > chars_left && text.starts_with(
' ')) {
3213 text = text.drop_front(word_start_pos);
3220 strm.
PutCString(text.take_front(fragment_size));
3221 text = text.drop_front(fragment_size);
3222 chars_left = fragment_size > chars_left ? 0 : chars_left - fragment_size;
3230 llvm::StringRef search_word,
StringList &commands_found,
3232 for (
const auto &pair : command_map) {
3233 llvm::StringRef command_name = pair.first;
3236 const bool search_short_help =
true;
3237 const bool search_long_help =
false;
3238 const bool search_syntax =
false;
3239 const bool search_options =
false;
3240 if (command_name.contains_insensitive(search_word) ||
3242 search_long_help, search_syntax,
3251 multiword_cmd->GetSubcommandDictionary());
3252 for (
const auto &subcommand_name : subcommands_found) {
3253 std::string qualified_name =
3254 (command_name +
" " + subcommand_name).str();
3264 bool search_builtin_commands,
3265 bool search_user_commands,
3266 bool search_alias_commands,
3267 bool search_user_mw_commands) {
3268 if (search_builtin_commands)
3272 if (search_user_commands)
3276 if (search_user_mw_commands)
3280 if (search_alias_commands)
3288 return m_debugger.GetSelectedExecutionContext(adopt_dummy_target);
3292 if (!adopt_dummy_target && candidate_target &&
3295 return candidate_context;
3310 m_debugger.FlushProcessOutput(*process_sp,
true,
3339 if (!
m_debugger.IsIOHandlerThreadCurrentThread())
3342 bool was_interrupted =
3345 return was_interrupted;
3349 llvm::StringRef str,
3356 bool had_output = !str.empty();
3357 while (!str.empty()) {
3358 llvm::StringRef line;
3359 std::tie(line, str) = str.split(
'\n');
3362 stream_file.
Write(line.data(), line.size());
3363 stream_file.
Write(
"\n", 1);
3370 stream_file.
Printf(
"\n... Interrupted.\n");
3371 stream_file.
Flush();
3375 llvm::StringRef line,
const Flags &io_handler_flags)
const {
3379 llvm::StringRef command = line.trim();
3380 if (command.empty())
3390 std::string &line) {
3396 const bool allow_repeats =
3399 if (!is_interactive && !allow_repeats) {
3408 if (!is_interactive) {
3422 m_debugger.GetSelectedExecutionContext(
true);
3423 bool pushed_exe_ctx =
false;
3426 pushed_exe_ctx =
true;
3428 llvm::scope_exit finalize([
this, pushed_exe_ctx]() {
3437 if ((result.Succeeded() &&
3442 const bool inline_diagnostics = !result.GetImmediateErrorStream() &&
3444 if (inline_diagnostics) {
3445 unsigned prompt_len =
m_debugger.GetPrompt().size();
3446 if (
auto indent = result.GetDiagnosticIndent()) {
3448 result.GetInlineDiagnosticString(prompt_len + *indent);
3456 if (!result.GetImmediateOutputStream()) {
3457 llvm::StringRef output = result.GetOutputString();
3462 if (!result.GetImmediateErrorStream()) {
3463 std::string
error = result.GetErrorString(!inline_diagnostics);
3471 DefaultPrintCallback(result);
3473 DefaultPrintCallback(result);
3479 switch (result.GetStatus()) {
3493 m_result.IncrementNumberOfErrors();
3508 result.GetDidChangeProcessState() &&
3533 if (script_interpreter) {
3542 if (output_file == std::nullopt || output_file->empty()) {
3543 std::string now = llvm::to_string(std::chrono::system_clock::now());
3544 llvm::replace(now,
' ',
'_');
3546 llvm::replace(now,
':',
'-');
3547 const std::string file_name =
"lldb_session_" + now +
".log";
3552 save_location = HostInfo::GetGlobalTempDir();
3556 output_file = save_location.
GetPath();
3559 auto error_out = [&](llvm::StringRef error_message, std::string description) {
3561 output_file, description);
3563 "Failed to save session's transcripts to {0}!", *output_file);
3574 return error_out(
"Unable to create file",
3575 llvm::toString(opened_file.takeError()));
3577 FileUP file = std::move(opened_file.get());
3584 return error_out(
"Unable to write to destination file",
3585 "Bytes written do not match transcript size.");
3589 output_file->c_str());
3592 "Note: the setting interpreter.save-transcript is set to false, so the "
3593 "transcript might not have been recorded.");
3597 error = file->GetFileSpec(
const_cast<FileSpec &
>(file_spec));
3598 if (
error.Success()) {
3600 m_debugger.GetExternalEditor(), file_spec, 1))
3624 llvm::StringRef(prompt),
3631 if (io_handler_sp) {
3632 io_handler_sp->SetUserData(baton);
3643 llvm::StringRef(prompt),
3650 if (io_handler_sp) {
3651 io_handler_sp->SetUserData(baton);
3711 bool force_create =
true;
3725 m_debugger.SetIOHandlerThread(new_io_handler_thread);
3727 m_debugger.SetIOHandlerThread(old_io_handler_thread);
3739 std::string scratch_command(command_line);
3743 bool wants_raw_input =
false;
3744 std::string next_word;
3748 auto build_alias_cmd = [&](std::string &full_name) {
3749 revised_command_line.
Clear();
3751 std::string alias_result;
3754 revised_command_line.
Printf(
"%s", alias_result.c_str());
3761 char quote_char =
'\0';
3764 if (cmd_obj ==
nullptr) {
3765 std::string full_name;
3768 bool is_real_command =
3769 (!is_alias) || (cmd_obj !=
nullptr && !cmd_obj->
IsAlias());
3770 if (!is_real_command) {
3771 build_alias_cmd(full_name);
3775 revised_command_line.
Printf(
"%s", cmd_name.str().c_str());
3778 revised_command_line.
Printf(
"%s", next_word.c_str());
3789 revised_command_line.
Clear();
3790 revised_command_line.
Printf(
"%s", sub_cmd_name.str().c_str());
3791 cmd_obj = sub_cmd_obj;
3795 revised_command_line.
Printf(
" %c%s%s%c", quote_char,
3796 next_word.c_str(), suffix.c_str(),
3799 revised_command_line.
Printf(
" %s%s", next_word.c_str(),
3805 revised_command_line.
Printf(
" %c%s%s%c", quote_char,
3806 next_word.c_str(), suffix.c_str(),
3809 revised_command_line.
Printf(
" %s%s", next_word.c_str(),
3815 if (cmd_obj ==
nullptr) {
3816 const size_t num_matches = matches.
GetSize();
3821 if (alias_matches.
GetSize() == 1) {
3822 std::string full_name;
3824 build_alias_cmd(full_name);
3825 done =
static_cast<bool>(cmd_obj);
3828 error_msg.
Printf(
"ambiguous command '%s'. Possible matches:\n",
3830 for (uint32_t i = 0; i < num_matches; ++i)
3845 if (!suffix.empty()) {
3847 "command '%s' did not recognize '%s%s%s' as valid (subcommand "
3848 "might be invalid)",
3850 next_word.empty() ?
"" : next_word.c_str(),
3851 next_word.empty() ?
" -- " :
" ", suffix.c_str());
3857 if (!suffix.empty()) {
3858 switch (suffix[0]) {
3863 if (command_options &&
3865 std::string gdb_format_option(
"--gdb-format=");
3866 gdb_format_option += (suffix.c_str() + 1);
3868 std::string cmd = std::string(revised_command_line.
GetString());
3870 if (arg_terminator_idx != std::string::npos) {
3873 gdb_format_option.append(1,
' ');
3874 cmd.insert(arg_terminator_idx, gdb_format_option);
3875 revised_command_line.
Clear();
3878 revised_command_line.
Printf(
" %s", gdb_format_option.c_str());
3880 if (wants_raw_input &&
3885 "the '%s' command doesn't support the --gdb-format option",
3899 if (scratch_command.empty())
3903 if (!scratch_command.empty())
3904 revised_command_line.
Printf(
" %s", scratch_command.c_str());
3906 if (cmd_obj !=
nullptr)
3907 command_line = std::string(revised_command_line.
GetString());
3913 llvm::json::Object stats;
3915 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 OutputFormattedHelpText(Stream &strm, llvm::StringRef prefix, llvm::StringRef help_text, std::optional< Stream::HighlightSettings > highlight=std::nullopt)
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
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
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
ExecutionContext GetExecutionContext(bool adopt_dummy_target=true) const
Returns the execution context the interpreter should run a command in.
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
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)
void MakeAbsolute(const FileSpec &dir)
Make the FileSpec absolute by treating it relative to dir.
llvm::StringRef GetFilename() const
Filename string const get accessor.
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 llvm::Error OpenFileInExternalEditor(llvm::StringRef editor, const FileSpec &file_spec, uint32_t line_no, bool foreground=false)
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.
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.
void PutCStringColorHighlighted(llvm::StringRef text, std::optional< HighlightSettings > settings=std::nullopt)
Output a C string to the stream with color highlighting.
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()
bool IsDummyTarget() const
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)