65#include "lldb/Host/Config.h"
67#if LLDB_ENABLE_LIBEDIT
90#include "llvm/ADT/STLExtras.h"
91#include "llvm/ADT/ScopeExit.h"
92#include "llvm/ADT/SmallString.h"
93#include "llvm/Support/FormatAdapters.h"
94#include "llvm/Support/Path.h"
95#include "llvm/Support/PrettyStackTrace.h"
96#include "llvm/Support/ScopedPrinter.h"
97#include "llvm/Telemetry/Telemetry.h"
100#include <TargetConditionals.h>
109 R
"(there is a .lldbinit file in the current directory which is not being read.
110To silence this warning without sourcing in the local .lldbinit, add the following to the lldbinit file in your home directory:
111 settings set target.load-cwd-lldbinit false\n"
112To allow lldb to source .lldbinit files in the current working directory, set the value of this variable to true.
113Only do so if you understand and accept the security risk)";
119#define LLDB_PROPERTIES_interpreter
120#include "InterpreterProperties.inc"
123#define LLDB_PROPERTIES_interpreter
124#include "InterpreterPropertiesEnum.inc"
128 static constexpr llvm::StringLiteral class_name(
"lldb.commandInterpreter");
133 bool synchronous_execution)
152 const uint32_t idx = ePropertyExpandRegexAliases;
154 idx, g_interpreter_properties[idx].default_uint_value != 0);
158 const uint32_t idx = ePropertyPromptOnQuit;
160 idx, g_interpreter_properties[idx].default_uint_value != 0);
164 const uint32_t idx = ePropertyPromptOnQuit;
169 const uint32_t idx = ePropertySaveTranscript;
171 idx, g_interpreter_properties[idx].default_uint_value != 0);
175 const uint32_t idx = ePropertySaveTranscript;
180 const uint32_t idx = ePropertySaveSessionOnQuit;
182 idx, g_interpreter_properties[idx].default_uint_value != 0);
186 const uint32_t idx = ePropertySaveSessionOnQuit;
191 const uint32_t idx = ePropertyOpenTranscriptInEditor;
193 idx, g_interpreter_properties[idx].default_uint_value != 0);
197 const uint32_t idx = ePropertyOpenTranscriptInEditor;
202 const uint32_t idx = ePropertySaveSessionDirectory;
207 const uint32_t idx = ePropertySaveSessionDirectory;
212 const uint32_t idx = ePropertyEchoCommands;
214 idx, g_interpreter_properties[idx].default_uint_value != 0);
218 const uint32_t idx = ePropertyEchoCommands;
223 const uint32_t idx = ePropertyEchoCommentCommands;
225 idx, g_interpreter_properties[idx].default_uint_value != 0);
229 const uint32_t idx = ePropertyEchoCommentCommands;
255 std::string command = command_line;
263 const uint32_t idx = ePropertyStopCmdSourceOnError;
265 idx, g_interpreter_properties[idx].default_uint_value != 0);
269 const uint32_t idx = ePropertySpaceReplPrompts;
271 idx, g_interpreter_properties[idx].default_uint_value != 0);
275 const uint32_t idx = ePropertyRepeatPreviousCommand;
277 idx, g_interpreter_properties[idx].default_uint_value != 0);
281 const uint32_t idx = ePropertyRequireCommandOverwrite;
283 idx, g_interpreter_properties[idx].default_uint_value != 0);
346 "sif", cmd_obj_sp,
"--end-linenumber block --step-in-target %1");
348 sif_alias->
SetHelp(
"Step through the current block, stopping if you step "
349 "directly into a function whose name matches the "
350 "TargetFunctionName.");
351 sif_alias->
SetSyntax(
"sif <TargetFunctionName>");
426 if (
auto *sys_bt =
AddAlias(
"sys_bt", cmd_obj_sp,
"--provider 0")) {
427 sys_bt->SetHelp(
"Show the base unwinder backtrace (without frame "
428 "providers). Equivalent to 'thread backtrace "
445 alias_arguments_vector_sp = std::make_shared<OptionArgVector>();
451 if (
auto *po =
AddAlias(
"po", cmd_obj_sp,
"-O --")) {
452 po->SetHelp(
"Evaluate an expression on the current thread. Displays any "
453 "returned value with formatting "
454 "controlled by the type's author.");
465 AddAlias(
"parray", cmd_obj_sp,
"--element-count %1 --");
468 "parray <COUNT> <EXPRESSION> -- lldb will evaluate EXPRESSION "
469 "to get a typed-pointer-to-an-array in memory, and will display "
470 "COUNT elements of that type from the array.");
474 "poarray", cmd_obj_sp,
"--object-description --element-count %1 --");
477 "poarray <COUNT> <EXPRESSION> -- lldb will "
478 "evaluate EXPRESSION to get the address of an array of COUNT "
479 "objects in memory, and will call po on them.");
488 shell_alias->
SetHelp(
"Run a shell command on the host.");
490 shell_alias->
SetSyntax(
"shell <shell-command>");
501 alias_arguments_vector_sp = std::make_shared<OptionArgVector>();
502#if defined(__APPLE__)
507 AddAlias(
"r", cmd_obj_sp,
"--shell-expand-args true --");
508 AddAlias(
"run", cmd_obj_sp,
"--shell-expand-args true --");
512 defaultshell.
Printf(
"--shell=%s --",
513 HostInfo::GetDefaultShell().GetPath().c_str());
526 AddAlias(
"rbreak", cmd_obj_sp,
"--func-regex %1");
533 AddAlias(
"vo", cmd_obj_sp,
"--object-description");
572#define REGISTER_COMMAND_OBJECT(NAME, CLASS) \
573 m_command_dict[NAME] = std::make_shared<CLASS>(*this);
610 const char *break_regexes[][2] = {
611 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
612 "breakpoint set --file '%1' --line %2 --column %3"},
613 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
614 "breakpoint set --file '%1' --line %2"},
615 {
"^/([^/]+)/$",
"breakpoint set --source-pattern-regexp '%1'"},
616 {
"^([[:digit:]]+)[[:space:]]*$",
"breakpoint set --line %1"},
617 {
"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
"breakpoint set --address %1"},
618 {
"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$",
619 "breakpoint set --name '%1'"},
620 {
"^(-.*)$",
"breakpoint set %1"},
621 {
"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$",
622 "breakpoint set --name '%2' --shlib '%1'"},
623 {
"^\\&(.*[^[:space:]])[[:space:]]*$",
624 "breakpoint set --name '%1' --skip-prologue=0"},
625 {
"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$",
626 "breakpoint set --name '%1'"}};
629 size_t num_regexes = std::size(break_regexes);
631 std::unique_ptr<CommandObjectRegexCommand> break_regex_cmd_up(
633 *
this,
"_regexp-break",
634 "Set a breakpoint using one of several shorthand formats, or list "
635 "the existing breakpoints if no arguments are provided.",
637 "_regexp-break <filename>:<linenum>:<colnum>\n"
638 " main.c:12:21 // Break at line 12 and column "
640 "_regexp-break <filename>:<linenum>\n"
641 " main.c:12 // Break at line 12 of "
643 "_regexp-break <linenum>\n"
644 " 12 // Break at line 12 of current "
646 "_regexp-break 0x<address>\n"
647 " 0x1234000 // Break at address "
649 "_regexp-break <name>\n"
650 " main // Break in 'main' after the "
652 "_regexp-break &<name>\n"
653 " &main // Break at first instruction "
655 "_regexp-break <module>`<name>\n"
656 " libc.so`malloc // Break in 'malloc' from "
658 "_regexp-break /<source-regex>/\n"
659 " /break here/ // Break on source lines in "
661 " // containing text 'break "
664 " // List the existing "
668 if (break_regex_cmd_up) {
670 for (
size_t i = 0; i < num_regexes; i++) {
671 success = break_regex_cmd_up->AddRegexCommand(break_regexes[i][0],
672 break_regexes[i][1]);
677 break_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
681 m_command_dict[std::string(break_regex_cmd_sp->GetCommandName())] =
690 const char *break_add_regexes[][2] = {
691 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
692 "breakpoint add file --file '%1' --line %2 --column %3"},
693 {
"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$",
694 "breakpoint add file --file '%1' --line %2"},
695 {
"^/([^/]+)/$",
"breakpoint add pattern -- %1"},
696 {
"^([[:digit:]]+)[[:space:]]*$",
697 "breakpoint add file --line %1"},
698 {
"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
699 "breakpoint add address %1"},
700 {
"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$",
701 "breakpoint add name '%1'"},
703 "breakpoint add name '%1'"},
704 {
"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$",
705 "breakpoint add name '%2' --shlib '%1'"},
706 {
"^\\&(.*[^[:space:]])[[:space:]]*$",
707 "breakpoint add name '%1' --skip-prologue=0"},
708 {
"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$",
709 "breakpoint add name '%1'"}};
712 size_t num_add_regexes = std::size(break_add_regexes);
714 std::unique_ptr<CommandObjectRegexCommand> break_add_regex_cmd_up(
716 *
this,
"_regexp-break-add",
717 "Set a breakpoint using one of several shorthand formats, or list "
718 "the existing breakpoints if no arguments are provided.",
720 "_regexp-break-add <filename>:<linenum>:<colnum>\n"
721 " main.c:12:21 // Break at line 12 and column "
723 "_regexp-break-add <filename>:<linenum>\n"
724 " main.c:12 // Break at line 12 of "
726 "_regexp-break-add <linenum>\n"
727 " 12 // Break at line 12 of current "
729 "_regexp-break-add 0x<address>\n"
730 " 0x1234000 // Break at address "
732 "_regexp-break-add <name>\n"
733 " main // Break in 'main' after the "
735 "_regexp-break-add &<name>\n"
736 " &main // Break at first instruction "
738 "_regexp-break-add <module>`<name>\n"
739 " libc.so`malloc // Break in 'malloc' from "
741 "_regexp-break-add /<source-regex>/\n"
742 " /break here/ // Break on source lines in "
744 " // containing text 'break "
746 "_regexp-break-add\n"
747 " // List the existing "
751 if (break_add_regex_cmd_up) {
753 for (
size_t i = 0; i < num_add_regexes; i++) {
754 success = break_add_regex_cmd_up->AddRegexCommand(
755 break_add_regexes[i][0], break_add_regexes[i][1]);
760 break_add_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
763 CommandObjectSP break_add_regex_cmd_sp(break_add_regex_cmd_up.release());
764 m_command_dict[std::string(break_add_regex_cmd_sp->GetCommandName())] =
765 break_add_regex_cmd_sp;
769 std::unique_ptr<CommandObjectRegexCommand> tbreak_regex_cmd_up(
771 *
this,
"_regexp-tbreak",
772 "Set a one-shot breakpoint using one of several shorthand formats.",
774 "_regexp-break <filename>:<linenum>:<colnum>\n"
775 " main.c:12:21 // Break at line 12 and column "
777 "_regexp-break <filename>:<linenum>\n"
778 " main.c:12 // Break at line 12 of "
780 "_regexp-break <linenum>\n"
781 " 12 // Break at line 12 of current "
783 "_regexp-break 0x<address>\n"
784 " 0x1234000 // Break at address "
786 "_regexp-break <name>\n"
787 " main // Break in 'main' after the "
789 "_regexp-break &<name>\n"
790 " &main // Break at first instruction "
792 "_regexp-break <module>`<name>\n"
793 " libc.so`malloc // Break in 'malloc' from "
795 "_regexp-break /<source-regex>/\n"
796 " /break here/ // Break on source lines in "
798 " // containing text 'break "
802 if (tbreak_regex_cmd_up) {
804 for (
size_t i = 0; i < num_regexes; i++) {
805 std::string command = break_regexes[i][1];
808 tbreak_regex_cmd_up->AddRegexCommand(break_regexes[i][0], command);
813 tbreak_regex_cmd_up->AddRegexCommand(
"^$",
"breakpoint list --full");
817 m_command_dict[std::string(tbreak_regex_cmd_sp->GetCommandName())] =
822 std::unique_ptr<CommandObjectRegexCommand> attach_regex_cmd_up(
824 *
this,
"_regexp-attach",
"Attach to process by ID or name.",
825 "_regexp-attach <pid> | <process-name>", 0,
false));
826 if (attach_regex_cmd_up) {
827 if (attach_regex_cmd_up->AddRegexCommand(
"^([0-9]+)[[:space:]]*$",
828 "process attach --pid %1") &&
829 attach_regex_cmd_up->AddRegexCommand(
830 "^(-.*|.* -.*)$",
"process attach %1") &&
833 attach_regex_cmd_up->AddRegexCommand(
"^(.+)$",
834 "process attach --name '%1'") &&
835 attach_regex_cmd_up->AddRegexCommand(
"^$",
"process attach")) {
837 m_command_dict[std::string(attach_regex_cmd_sp->GetCommandName())] =
842 std::unique_ptr<CommandObjectRegexCommand> down_regex_cmd_up(
844 "Select a newer stack frame. Defaults to "
845 "moving one frame, a numeric argument can "
846 "specify an arbitrary number.",
847 "_regexp-down [<count>]", 0,
false));
848 if (down_regex_cmd_up) {
849 if (down_regex_cmd_up->AddRegexCommand(
"^$",
"frame select -r -1") &&
850 down_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
851 "frame select -r -%1")) {
853 m_command_dict[std::string(down_regex_cmd_sp->GetCommandName())] =
858 std::unique_ptr<CommandObjectRegexCommand> up_regex_cmd_up(
861 "Select an older stack frame. Defaults to moving one "
862 "frame, a numeric argument can specify an arbitrary number.",
863 "_regexp-up [<count>]", 0,
false));
864 if (up_regex_cmd_up) {
865 if (up_regex_cmd_up->AddRegexCommand(
"^$",
"frame select -r 1") &&
866 up_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
"frame select -r %1")) {
873 std::unique_ptr<CommandObjectRegexCommand> display_regex_cmd_up(
875 *
this,
"_regexp-display",
876 "Evaluate an expression at every stop (see 'help target stop-hook'.)",
877 "_regexp-display expression", 0,
false));
878 if (display_regex_cmd_up) {
879 if (display_regex_cmd_up->AddRegexCommand(
880 "^(.+)$",
"target stop-hook add -o \"expr -- %1\"")) {
882 m_command_dict[std::string(display_regex_cmd_sp->GetCommandName())] =
883 display_regex_cmd_sp;
887 std::unique_ptr<CommandObjectRegexCommand> undisplay_regex_cmd_up(
889 "Stop displaying expression at every "
890 "stop (specified by stop-hook index.)",
891 "_regexp-undisplay stop-hook-number", 0,
893 if (undisplay_regex_cmd_up) {
894 if (undisplay_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
895 "target stop-hook delete %1")) {
896 CommandObjectSP undisplay_regex_cmd_sp(undisplay_regex_cmd_up.release());
897 m_command_dict[std::string(undisplay_regex_cmd_sp->GetCommandName())] =
898 undisplay_regex_cmd_sp;
902 std::unique_ptr<CommandObjectRegexCommand> connect_gdb_remote_cmd_up(
905 "Connect to a process via remote GDB server.\n"
906 "If no host is specified, localhost is assumed.\n"
907 "gdb-remote is an abbreviation for 'process connect --plugin "
908 "gdb-remote connect://<hostname>:<port>'\n",
909 "gdb-remote [<hostname>:]<portnum>", 0,
false));
910 if (connect_gdb_remote_cmd_up) {
911 if (connect_gdb_remote_cmd_up->AddRegexCommand(
912 "^([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)$",
913 "process connect --plugin gdb-remote connect://%1:%2") &&
914 connect_gdb_remote_cmd_up->AddRegexCommand(
916 "process connect --plugin gdb-remote connect://localhost:%1")) {
918 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
922 std::unique_ptr<CommandObjectRegexCommand> connect_kdp_remote_cmd_up(
925 "Connect to a process via remote KDP server.\n"
926 "If no UDP port is specified, port 41139 is assumed.\n"
927 "kdp-remote is an abbreviation for 'process connect --plugin "
928 "kdp-remote udp://<hostname>:<port>'\n",
929 "kdp-remote <hostname>[:<portnum>]", 0,
false));
930 if (connect_kdp_remote_cmd_up) {
931 if (connect_kdp_remote_cmd_up->AddRegexCommand(
932 "^([^:]+:[[:digit:]]+)$",
933 "process connect --plugin kdp-remote udp://%1") &&
934 connect_kdp_remote_cmd_up->AddRegexCommand(
935 "^(.+)$",
"process connect --plugin kdp-remote udp://%1:41139")) {
937 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
941 std::unique_ptr<CommandObjectRegexCommand> bt_regex_cmd_up(
944 "Show backtrace of the current thread's call stack. Any numeric "
945 "argument displays at most that many frames. The argument 'all' "
946 "displays all threads. Use 'settings set frame-format' to customize "
947 "the printing of individual frames and 'settings set thread-format' "
948 "to customize the thread header. Frame recognizers may filter the "
949 "list. Use 'thread backtrace -u (--unfiltered)' to see them all.",
950 "bt [<digit> | all]", 0,
false));
951 if (bt_regex_cmd_up) {
956 if (bt_regex_cmd_up->AddRegexCommand(
"^([[:digit:]]+)[[:space:]]*$",
957 "thread backtrace -c %1") &&
958 bt_regex_cmd_up->AddRegexCommand(
"^(-[^[:space:]].*)$",
959 "thread backtrace %1") &&
960 bt_regex_cmd_up->AddRegexCommand(
"^all[[:space:]]*$",
961 "thread backtrace all") &&
962 bt_regex_cmd_up->AddRegexCommand(
"^[[:space:]]*$",
963 "thread backtrace")) {
965 m_command_dict[std::string(command_sp->GetCommandName())] = command_sp;
969 std::unique_ptr<CommandObjectRegexCommand> list_regex_cmd_up(
971 *
this,
"_regexp-list",
972 "List relevant source code using one of several shorthand formats.",
974 "_regexp-list <file>:<line> // List around specific file/line\n"
975 "_regexp-list <line> // List current file around specified "
977 "_regexp-list <function-name> // List specified function\n"
978 "_regexp-list 0x<address> // List around specified address\n"
979 "_regexp-list -[<count>] // List previous <count> lines\n"
980 "_regexp-list // List subsequent lines",
982 if (list_regex_cmd_up) {
983 if (list_regex_cmd_up->AddRegexCommand(
"^([0-9]+)[[:space:]]*$",
984 "source list --line %1") &&
985 list_regex_cmd_up->AddRegexCommand(
986 "^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]"
988 "source list --file '%1' --line %2") &&
989 list_regex_cmd_up->AddRegexCommand(
990 "^\\*?(0x[[:xdigit:]]+)[[:space:]]*$",
991 "source list --address %1") &&
992 list_regex_cmd_up->AddRegexCommand(
"^-[[:space:]]*$",
993 "source list --reverse") &&
994 list_regex_cmd_up->AddRegexCommand(
995 "^-([[:digit:]]+)[[:space:]]*$",
996 "source list --reverse --count %1") &&
997 list_regex_cmd_up->AddRegexCommand(
"^(.+)$",
998 "source list --name \"%1\"") &&
999 list_regex_cmd_up->AddRegexCommand(
"^$",
"source list")) {
1001 m_command_dict[std::string(list_regex_cmd_sp->GetCommandName())] =
1006 std::unique_ptr<CommandObjectRegexCommand> env_regex_cmd_up(
1008 *
this,
"_regexp-env",
1009 "Shorthand for viewing and setting environment variables.",
1011 "_regexp-env // Show environment\n"
1012 "_regexp-env <name>=<value> // Set an environment variable",
1014 if (env_regex_cmd_up) {
1015 if (env_regex_cmd_up->AddRegexCommand(
"^$",
1016 "settings show target.env-vars") &&
1017 env_regex_cmd_up->AddRegexCommand(
"^([A-Za-z_][A-Za-z_0-9]*=.*)$",
1018 "settings set target.env-vars %1")) {
1020 m_command_dict[std::string(env_regex_cmd_sp->GetCommandName())] =
1025 std::unique_ptr<CommandObjectRegexCommand> jump_regex_cmd_up(
1027 *
this,
"_regexp-jump",
"Set the program counter to a new address.",
1029 "_regexp-jump <line>\n"
1030 "_regexp-jump +<line-offset> | -<line-offset>\n"
1031 "_regexp-jump <file>:<line>\n"
1032 "_regexp-jump *<addr>\n",
1034 if (jump_regex_cmd_up) {
1035 if (jump_regex_cmd_up->AddRegexCommand(
"^\\*(.*)$",
1036 "thread jump --addr %1") &&
1037 jump_regex_cmd_up->AddRegexCommand(
"^([0-9]+)$",
1038 "thread jump --line %1") &&
1039 jump_regex_cmd_up->AddRegexCommand(
"^([^:]+):([0-9]+)$",
1040 "thread jump --file %1 --line %2") &&
1041 jump_regex_cmd_up->AddRegexCommand(
"^([+\\-][0-9]+)$",
1042 "thread jump --by %1")) {
1044 m_command_dict[std::string(jump_regex_cmd_sp->GetCommandName())] =
1049 std::shared_ptr<CommandObjectRegexCommand> step_regex_cmd_sp(
1051 *
this,
"_regexp-step",
1052 "Single step, optionally to a specific function.",
1054 "_regexp-step // Single step\n"
1055 "_regexp-step <function-name> // Step into the named function\n",
1057 if (step_regex_cmd_sp) {
1058 if (step_regex_cmd_sp->AddRegexCommand(
"^[[:space:]]*$",
1059 "thread step-in") &&
1060 step_regex_cmd_sp->AddRegexCommand(
"^[[:space:]]*(-.+)$",
1061 "thread step-in %1") &&
1062 step_regex_cmd_sp->AddRegexCommand(
1063 "^[[:space:]]*(.+)[[:space:]]*$",
1064 "thread step-in --end-linenumber block --step-in-target %1")) {
1065 m_command_dict[std::string(step_regex_cmd_sp->GetCommandName())] =
1072 const char *cmd_str,
bool include_aliases,
StringList &matches,
1077 if (include_aliases) {
1090 auto get_multi_or_report_error =
1095 "Path component: '%s' not found", name);
1098 if (!cmd_sp->IsUserCommand()) {
1100 "Path component: '%s' is not a user "
1106 if (!cmd_as_multi) {
1108 "Path component: '%s' is not a container "
1113 return cmd_as_multi;
1117 if (num_args == 0) {
1122 if (num_args == 1 && leaf_is_command) {
1132 get_multi_or_report_error(cur_cmd_sp, cur_name);
1133 if (cur_as_multi ==
nullptr)
1136 size_t num_path_elements = num_args - (leaf_is_command ? 1 : 0);
1137 for (
size_t cursor = 1; cursor < num_path_elements && cur_as_multi !=
nullptr;
1141 cur_as_multi = get_multi_or_report_error(cur_cmd_sp, cur_name);
1143 return cur_as_multi;
1150 auto frame_language =
1163 auto lang_name =
plugin->GetPluginName();
1165 return language_cmd_sp->GetSubcommandSPExact(lang_name);
1174 std::string cmd = std::string(cmd_str);
1179 command_sp = pos->second;
1185 command_sp = alias_pos->second;
1191 command_sp = pos->second;
1197 command_sp = pos->second;
1202 if (!exact && !command_sp) {
1208 if (matches ==
nullptr)
1209 matches = &local_matches;
1211 unsigned int num_cmd_matches = 0;
1212 unsigned int num_alias_matches = 0;
1213 unsigned int num_user_matches = 0;
1214 unsigned int num_user_mw_matches = 0;
1222 *matches, descriptions);
1225 if (num_cmd_matches == 1) {
1229 real_match_sp = pos->second;
1234 *matches, descriptions);
1237 if (num_alias_matches == 1) {
1241 alias_match_sp = alias_pos->second;
1246 *matches, descriptions);
1249 if (num_user_matches == 1) {
1255 user_match_sp = pos->second;
1263 if (num_user_mw_matches == 1) {
1269 user_mw_match_sp = pos->second;
1275 if (num_user_matches + num_user_mw_matches + num_cmd_matches +
1276 num_alias_matches ==
1278 if (num_cmd_matches)
1279 return real_match_sp;
1280 else if (num_alias_matches)
1281 return alias_match_sp;
1282 else if (num_user_mw_matches)
1283 return user_mw_match_sp;
1285 return user_match_sp;
1296 command_sp = lang_subcmd_sp->GetSubcommandSPExact(cmd_str);
1299 if (!command_sp && !exact && lang_subcmd) {
1302 cmd_str, lang_matches, descriptions);
1305 if (lang_matches.
GetSize() == 1) {
1307 auto pos = lang_dict.find(lang_matches[0]);
1308 if (pos != lang_dict.end())
1314 if (matches && command_sp) {
1327 lldbassert((
this == &cmd_sp->GetCommandInterpreter()) &&
1328 "tried to add a CommandObject from a different interpreter");
1333 cmd_sp->SetIsUserCommand(
false);
1335 std::string name_sstr(name);
1338 if (!can_replace || !name_iter->second->IsRemovable())
1340 name_iter->second = cmd_sp;
1352 lldbassert((
this == &cmd_sp->GetCommandInterpreter()) &&
1353 "tried to add a CommandObject from a different interpreter");
1356 "can't use the empty string for a command name");
1368 "user command \"{0}\" already exists and force replace was not set "
1369 "by --overwrite or 'settings set interpreter.require-overwrite "
1374 if (cmd_sp->IsMultiwordObject()) {
1377 "can't replace explicitly non-removable multi-word command");
1381 if (!
m_user_dict[std::string(name)]->IsRemovable()) {
1383 "can't replace explicitly non-removable command");
1389 cmd_sp->SetIsUserCommand(
true);
1391 if (cmd_sp->IsMultiwordObject())
1400 bool include_aliases)
const {
1402 Args cmd_words(cmd_str);
1404 if (cmd_str.empty())
1421 for (
size_t i = 1; i < end; ++i) {
1422 if (!cmd_obj_sp->IsMultiwordObject()) {
1447 matches, descriptions)
1453 std::string cmd_str(cmd);
1455 auto found_elem = map.find(cmd);
1456 if (found_elem == map.end())
1479 StringList *matches_ptr = matches ? matches : &tmp_list;
1491 auto found_elem = map.find(cmd);
1492 if (found_elem == map.end())
1514 StringList *matches_ptr = matches ? matches : &tmp_list;
1525 std::string &full_name)
const {
1528 full_name.assign(std::string(cmd));
1532 size_t num_alias_matches;
1535 if (num_alias_matches == 1) {
1538 const bool include_aliases =
false;
1539 const bool exact =
false;
1541 GetCommandSP(cmd, include_aliases, exact, ®ular_matches));
1542 if (cmd_obj_sp || regular_matches.
GetSize() > 0)
1569 llvm::StringRef args_string) {
1570 if (command_obj_sp.get())
1571 lldbassert((
this == &command_obj_sp->GetCommandInterpreter()) &&
1572 "tried to add a CommandObject from a different interpreter");
1574 std::unique_ptr<CommandAlias> command_alias_up(
1575 new CommandAlias(*
this, command_obj_sp, args_string, alias_name));
1577 if (command_alias_up && command_alias_up->IsValid()) {
1580 return command_alias_up.release();
1598 if (force || pos->second->IsRemovable()) {
1609 CommandObject::CommandMap::iterator pos =
m_user_dict.find(user_name);
1618 CommandObject::CommandMap::iterator pos =
m_user_mw_dict.find(multi_name);
1627 uint32_t cmd_types) {
1628 llvm::StringRef help_prologue(
GetDebugger().GetIOHandlerHelpPrologue());
1629 if (!help_prologue.empty()) {
1634 CommandObject::CommandMap::const_iterator pos;
1643 (pos->first.compare(0, 1,
"_") == 0))
1647 pos->second->GetHelp(), max_len);
1655 "Current command abbreviations "
1656 "(type '{0}help command alias' for more info):",
1664 alias_pos->second->GetHelp(), max_len);
1676 pos->second->GetHelp(), max_len);
1683 result.
AppendMessage(
"Current user-defined container commands:");
1688 pos->second->GetHelp(), max_len);
1694 "For more information on any command, type '{0}help <command-name>'.",
1699 llvm::StringRef &command_string) {
1705 size_t start = command_string.find_first_not_of(
k_white_space);
1709 if (start != std::string::npos) {
1712 if (end == std::string::npos)
1713 end = command_string.size();
1714 std::string cmd_word =
1715 std::string(command_string.substr(start, end - start));
1717 if (cmd_obj ==
nullptr)
1727 cmd_obj = sub_cmd_obj;
1739 end >= command_string.size())
1742 start = command_string.find_first_not_of(
k_white_space, end);
1748 command_string = command_string.substr(end);
1753 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
1757 if (pos == std::string::npos)
1766 const size_t s_len = s.size();
1768 while (offset < s_len) {
1769 size_t pos = s.find(
"--", offset);
1770 if (pos == std::string::npos)
1773 if (llvm::isSpace(s[pos - 1])) {
1776 if ((pos + 2 >= s_len) || llvm::isSpace(s[pos + 2])) {
1783 return std::string::npos;
1787 std::string &suffix,
char "e_char) {
1792 bool result =
false;
1795 if (!command_string.empty()) {
1796 const char first_char = command_string[0];
1797 if (first_char ==
'\'' || first_char ==
'"') {
1798 quote_char = first_char;
1799 const size_t end_quote_pos = command_string.find(quote_char, 1);
1800 if (end_quote_pos == std::string::npos) {
1801 command.swap(command_string);
1802 command_string.erase();
1804 command.assign(command_string, 1, end_quote_pos - 1);
1805 if (end_quote_pos + 1 < command_string.size())
1806 command_string.erase(0, command_string.find_first_not_of(
1809 command_string.erase();
1812 const size_t first_space_pos =
1814 if (first_space_pos == std::string::npos) {
1815 command.swap(command_string);
1816 command_string.erase();
1818 command.assign(command_string, 0, first_space_pos);
1819 command_string.erase(0, command_string.find_first_not_of(
1826 if (!command.empty()) {
1828 if (command[0] !=
'-' && command[0] !=
'_') {
1830 if (pos > 0 && pos != std::string::npos) {
1831 suffix.assign(command.begin() + pos, command.end());
1841 llvm::StringRef alias_name, std::string &raw_input_string,
1844 Args cmd_args(raw_input_string);
1848 if (!alias_cmd_obj || !alias_cmd_obj->
IsAlias()) {
1849 alias_result.clear();
1850 return alias_cmd_obj;
1852 std::pair<CommandObjectSP, OptionArgVectorSP> desugared =
1855 alias_cmd_obj = desugared.first.get();
1856 std::string alias_name_str = std::string(alias_name);
1859 cmd_args.
Unshift(alias_name_str);
1863 if (!option_arg_vector_sp.get()) {
1864 alias_result = std::string(result_str.
GetString());
1865 return alias_cmd_obj;
1872 for (
const auto &entry : *option_arg_vector) {
1873 std::tie(option, value_type, value) = entry;
1875 result_str.
Printf(
" %s", value.c_str());
1879 result_str.
Printf(
" %s", option.c_str());
1891 "need at least %d arguments to use "
1897 size_t strpos = raw_input_string.find(entry.
c_str());
1899 if (strpos != std::string::npos) {
1900 const size_t start_fudge = quote_char ==
'\0' ? 0 : 1;
1901 const size_t len_fudge = quote_char ==
'\0' ? 0 : 2;
1904 if (strpos < start_fudge) {
1905 result.
AppendError(
"unmatched quote at command beginning");
1908 llvm::StringRef arg_text = entry.
ref();
1909 if (strpos - start_fudge + arg_text.size() + len_fudge >
1910 raw_input_string.size()) {
1911 result.
AppendError(
"unmatched quote at command end");
1914 raw_input_string = raw_input_string.erase(
1915 strpos - start_fudge,
1918 if (quote_char ==
'\0')
1921 result_str.
Printf(
"%c%s%c", quote_char, entry.
c_str(), quote_char);
1925 alias_result = std::string(result_str.
GetString());
1926 return alias_cmd_obj;
1937 size_t start_backtick;
1939 while ((start_backtick = command.find(
'`', pos)) != std::string::npos) {
1944 if (start_backtick > 0 && command[start_backtick - 1] ==
'\\') {
1947 command.erase(start_backtick - 1, 1);
1949 pos = start_backtick;
1953 const size_t expr_content_start = start_backtick + 1;
1954 const size_t end_backtick = command.find(
'`', expr_content_start);
1956 if (end_backtick == std::string::npos) {
1961 if (end_backtick == expr_content_start) {
1963 command.erase(start_backtick, 2);
1967 std::string expr_str(command, expr_content_start,
1968 end_backtick - expr_content_start);
1974 command.erase(start_backtick, end_backtick - start_backtick + 1);
1975 command.insert(start_backtick, std::string(expr_str));
1976 pos = start_backtick + expr_str.size();
1998 expr_str.c_str(), exe_ctx.
GetFramePtr(), expr_result_valobj_sp, options);
2002 if (expr_result_valobj_sp)
2003 expr_result_valobj_sp =
2004 expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable(
2005 expr_result_valobj_sp->GetDynamicValueType(),
true);
2012 if (expr_result_valobj_sp &&
2013 expr_result_valobj_sp->GetCompilerType().IsArrayType()) {
2015 expr_result_valobj_sp->GetAddressOf(
true)
2021 if (scalar.
IsValid() || expr_result_valobj_sp->ResolveValue(scalar)) {
2024 const bool show_type =
false;
2025 scalar.
GetValue(value_strm, show_type);
2026 size_t value_string_size = value_strm.
GetSize();
2027 if (value_string_size) {
2028 expr_str = value_strm.
GetData();
2032 "in a scalar value for the "
2039 "in a scalar value for the "
2050 if (expr_result_valobj_sp)
2051 error = expr_result_valobj_sp->GetError().Clone();
2053 if (
error.Success()) {
2055 "for the expression '" + expr_str +
"'";
2067 bool status =
HandleCommand(command_line, lazy_add_to_history, result);
2075 bool force_repeat_command) {
2080 std::string parsed_command_args;
2084 const bool detailed_command_telemetry =
2090 std::string command_string(command_line);
2091 std::string original_command_string(command_string);
2092 std::string real_original_command_string(command_string);
2098 info->
target_uuid = target->GetExecutableModule() !=
nullptr
2099 ? target->GetExecutableModule()->GetUUID()
2102 if (detailed_command_telemetry)
2109 detailed_command_telemetry, command_id](
2115 llvm::StringRef command_name =
2119 if (std::string error_str = result.
GetErrorString(); !error_str.empty())
2122 if (detailed_command_telemetry)
2123 info->
args = parsed_command_args;
2127 LLDB_LOGF(log,
"Processing command: %s", command_line);
2139 bool add_to_history;
2143 add_to_history = (lazy_add_to_history ==
eLazyBoolYes);
2151 transcript_item = std::make_shared<StructuredData::Dictionary>();
2152 transcript_item->AddStringItem(
"command", command_line);
2153 transcript_item->AddIntegerItem(
2154 "timestampInEpochSeconds",
2155 std::chrono::duration_cast<std::chrono::seconds>(
2156 std::chrono::system_clock::now().time_since_epoch())
2161 bool empty_command =
false;
2162 bool comment_command =
false;
2163 if (command_string.empty())
2164 empty_command =
true;
2166 const char *k_space_characters =
"\t\n\v\f\r ";
2168 size_t non_space = command_string.find_first_not_of(k_space_characters);
2171 if (non_space == std::string::npos)
2172 empty_command =
true;
2174 comment_command =
true;
2176 llvm::StringRef search_str(command_string);
2177 search_str = search_str.drop_front(non_space);
2179 add_to_history =
false;
2180 command_string = std::string(*hist_str);
2181 original_command_string = std::string(*hist_str);
2184 command_string.c_str());
2190 if (empty_command) {
2202 command_string = command_line;
2203 original_command_string = command_line;
2209 add_to_history =
false;
2210 }
else if (comment_command) {
2250 llvm::StringRef command_name =
2252 LLDB_LOGF(log,
"HandleCommand, cmd_obj : '%s'", command_name.str().c_str());
2253 LLDB_LOGF(log,
"HandleCommand, (revised) command_string: '%s'",
2254 command_string.c_str());
2255 const bool wants_raw_input =
2257 LLDB_LOGF(log,
"HandleCommand, wants_raw_input:'%s'",
2258 wants_raw_input ?
"True" :
"False");
2266 if (cmd_obj !=
nullptr) {
2267 bool generate_repeat_command = add_to_history;
2271 generate_repeat_command |= empty_command;
2276 generate_repeat_command |= force_repeat_command;
2277 if (generate_repeat_command) {
2278 Args command_args(command_string);
2279 std::optional<std::string> repeat_command =
2281 if (repeat_command) {
2282 LLDB_LOGF(log,
"Repeat command: %s", repeat_command->data());
2292 const std::size_t actual_cmd_name_len = cmd_obj->
GetCommandName().size();
2293 if (actual_cmd_name_len < command_string.length())
2294 parsed_command_args = command_string.substr(actual_cmd_name_len);
2297 size_t pos = parsed_command_args.find_first_not_of(
k_white_space);
2298 if (pos != 0 && pos != std::string::npos)
2299 parsed_command_args.erase(0, pos);
2302 log,
"HandleCommand, command line after removing command name(s): '%s'",
2303 parsed_command_args.c_str());
2308 if (transcript_item) {
2309 transcript_item->AddStringItem(
"commandName", cmd_obj->
GetCommandName());
2310 transcript_item->AddStringItem(
"commandArguments", parsed_command_args);
2316 pos = real_original_command_string.rfind(parsed_command_args);
2317 std::optional<uint16_t> indent;
2318 if (pos != std::string::npos)
2321 cmd_obj->
Execute(parsed_command_args.c_str(), result);
2324 LLDB_LOGF(log,
"HandleCommand, command %s",
2325 (result.
Succeeded() ?
"succeeded" :
"did not succeed"));
2330 if (transcript_item) {
2335 transcript_item->AddStringItem(
"error", result.
GetErrorString());
2336 transcript_item->AddFloatItem(
"durationInSeconds",
2337 execute_time.
get().count());
2344 bool look_for_subcommand =
false;
2350 bool include_aliases =
true;
2361 &new_matches, &new_descriptions);
2368 look_for_subcommand =
true;
2383 if (command_object) {
2396 if (!first_arg.empty()) {
2401 request.
AddCompletion(*hist_str,
"Previous command history event",
2410std::optional<std::string>
2413 return std::nullopt;
2415 for (
int i = s - 1; i >= 0; --i) {
2417 if (entry.consume_front(line))
2420 return std::nullopt;
2424 EventSP prompt_change_event_sp(
2440 return default_answer;
2477 const char *alias_name,
2479 std::string &raw_input_string,
2487 std::string alias_name_str = alias_name;
2489 cmd_args.
Unshift(alias_name_str);
2495 if (option_arg_vector_sp.get()) {
2496 if (wants_raw_input) {
2500 size_t pos = raw_input_string.find(
" -- ");
2501 if (pos == std::string::npos) {
2503 raw_input_string.insert(0,
" -- ");
2509 std::vector<bool> used(old_size + 1,
false);
2516 for (
const auto &option_entry : *option_arg_vector) {
2517 std::tie(option, value_type, value) = option_entry;
2519 if (!wants_raw_input || (value !=
"--")) {
2543 "need at least %d arguments to use "
2551 if (strpos != std::string::npos) {
2552 raw_input_string = raw_input_string.erase(
2565 for (
auto entry : llvm::enumerate(cmd_args.
entries())) {
2566 if (!used[entry.index()] && !wants_raw_input)
2579 if (wants_raw_input) {
2595 const char *cptr = in_string;
2598 if (cptr[0] ==
'%') {
2602 if (isdigit(cptr[0])) {
2603 const char *start = cptr;
2604 while (isdigit(cptr[0]))
2609 if (cptr[0] ==
'\0')
2610 position = atoi(start);
2618 std::string init_file_name =
".lldbinit";
2619 if (!suffix.empty()) {
2620 init_file_name.append(
"-");
2621 init_file_name.append(suffix.str());
2632 language = *main_repl_language;
2637 std::string init_file_name =
2638 (llvm::Twine(
".lldbinit-") +
2640 llvm::Twine(
"-repl"))
2648 llvm::StringRef s =
".lldbinit";
2649 init_file.assign(s.begin(), s.end());
2681 llvm::SmallString<128> init_file;
2691 switch (should_load) {
2701 if (llvm::sys::path::parent_path(init_file) ==
2702 llvm::sys::path::parent_path(home_init_file.
GetPath())) {
2727 if (init_file.
GetPath().empty())
2731 FileSpec program_file_spec = HostInfo::GetProgramFileSpec();
2732 llvm::StringRef program_name = program_file_spec.
GetFilename();
2736 init_file = program_init_file;
2743#ifdef LLDB_GLOBAL_INIT_DIRECTORY
2745 FileSpec init_file(LLDB_GLOBAL_INIT_DIRECTORY);
2759 return prefix ==
nullptr ?
"" : prefix;
2764 if (prefer_target_platform) {
2772 platform_sp =
m_debugger.GetPlatformList().GetSelectedPlatform();
2778 TargetSP target_sp = exe_ctx.GetTargetSP();
2782 ProcessSP process_sp(target_sp->GetProcessSP());
2789 for (
const auto &thread_sp : process_sp->GetThreadList().Threads()) {
2790 StopInfoSP stop_info = thread_sp->GetStopInfo();
2798 const StopReason reason = stop_info->GetStopReason();
2806 const auto stop_signal =
static_cast<int32_t
>(stop_info->GetValue());
2808 if (!signals_sp || !signals_sp->SignalIsValid(stop_signal))
2812 const auto sigint_num = signals_sp->GetSignalNumberFromName(
"SIGINT");
2813 const auto sigstop_num = signals_sp->GetSignalNumberFromName(
"SIGSTOP");
2814 if ((stop_signal != sigint_num) && (stop_signal != sigstop_num))
2835 size_t num_lines = commands.
GetSize();
2841 bool old_async_execution =
m_debugger.GetAsyncExecution();
2847 for (
size_t idx = 0; idx < num_lines; idx++) {
2855 "{0} {1}",
m_debugger.GetPrompt().str().c_str(), cmd);
2876 if (!success || !tmp_result.
Succeeded()) {
2878 if (error_msg.empty())
2879 error_msg =
"<unknown error>.\n";
2882 "command #{0}: '{1}' failed with {2}",
2883 (uint64_t)idx, cmd, error_msg);
2884 m_debugger.SetAsyncExecution(old_async_execution);
2889 (uint64_t)idx + 1, cmd, error_msg);
2910 if (idx != num_lines - 1)
2912 "Aborting reading of commands after command #%" PRIu64
2913 ": '%s' continued the target",
2914 (uint64_t)idx + 1, cmd);
2917 "Command #{0} '{1}' continued the target.", (uint64_t)idx + 1,
2921 m_debugger.SetAsyncExecution(old_async_execution);
2930 if (idx != num_lines - 1)
2932 "Aborting reading of commands after command #%" PRIu64
2933 ": '%s' stopped with a signal or exception",
2934 (uint64_t)idx + 1, cmd);
2937 "Command #{0} '{1}' stopped with a signal or exception.",
2938 (uint64_t)idx + 1, cmd);
2941 m_debugger.SetAsyncExecution(old_async_execution);
2948 m_debugger.SetAsyncExecution(old_async_execution);
2977 "Error reading commands from file {0} - file not found",
2982 std::string cmd_file_path = cmd_file.
GetPath();
2983 auto input_file_up =
2985 if (!input_file_up) {
2987 "error: an error occurred read file '{0}': {1}\n", cmd_file_path,
2988 llvm::fmt_consume(input_file_up.takeError()));
2991 FileSP input_file_sp =
FileSP(std::move(input_file_up.get()));
3078 cmd_file_path.c_str());
3094 debugger.
GetPrompt(), llvm::StringRef(),
3124 Stream &strm, llvm::StringRef prefix, llvm::StringRef help_text,
3125 std::optional<Stream::HighlightSettings> highlight) {
3126 const uint32_t max_columns =
m_debugger.GetTerminalWidth();
3128 size_t line_width_max = max_columns - prefix.size();
3129 if (line_width_max < 16)
3130 line_width_max = help_text.size() + prefix.size();
3134 std::string highlighted_storage;
3138 highlighted_storage = std::string(ss.
GetString());
3139 help_text = highlighted_storage;
3143 bool prefixed_yet =
false;
3145 if (help_text.empty())
3146 help_text =
"No help text";
3147 while (!help_text.empty()) {
3149 if (!prefixed_yet) {
3151 prefixed_yet =
true;
3156 llvm::StringRef this_line = help_text.substr(0, line_width_max);
3159 std::size_t first_newline = this_line.find_first_of(
"\n");
3162 std::size_t last_space = llvm::StringRef::npos;
3163 if (this_line.size() != help_text.size())
3164 last_space = this_line.find_last_of(
" \t");
3167 this_line = this_line.substr(0, std::min(first_newline, last_space));
3172 help_text = help_text.drop_front(this_line.size()).ltrim();
3178 Stream &strm, llvm::StringRef word_text, llvm::StringRef separator,
3179 llvm::StringRef help_text,
size_t max_word_len,
3180 std::optional<Stream::HighlightSettings> highlight) {
3182 prefix_stream.
Printf(
" %-*s %*s ", (
int)max_word_len, word_text.data(),
3183 (
int)separator.size(), separator.data());
3189 llvm::StringRef separator,
3190 llvm::StringRef help_text,
3191 uint32_t max_word_len) {
3192 int indent_size = max_word_len + separator.size() + 2;
3197 text_strm.
Printf(
"%-*s ", (
int)max_word_len, word_text.data());
3198 text_strm << separator <<
" " << help_text;
3200 const uint32_t max_columns =
m_debugger.GetTerminalWidth();
3202 llvm::StringRef text = text_strm.
GetString();
3204 uint32_t chars_left = max_columns;
3206 auto start_new_line = [&] {
3209 chars_left = max_columns - indent_size;
3212 while (!text.empty()) {
3213 if (text.starts_with(
'\n')) {
3214 text = text.drop_front();
3223 size_t word_start_pos = text.find_first_not_of(
' ');
3224 size_t word_end_pos = text.find_first_of(
" \n", word_start_pos);
3225 size_t fragment_size =
3226 word_end_pos == llvm::StringRef::npos ? text.size() : word_end_pos;
3228 if (fragment_size > chars_left && text.starts_with(
' ')) {
3231 text = text.drop_front(word_start_pos);
3238 strm.
PutCString(text.take_front(fragment_size));
3239 text = text.drop_front(fragment_size);
3240 chars_left = fragment_size > chars_left ? 0 : chars_left - fragment_size;
3248 llvm::StringRef search_word,
StringList &commands_found,
3250 for (
const auto &pair : command_map) {
3251 llvm::StringRef command_name = pair.first;
3254 const bool search_short_help =
true;
3255 const bool search_long_help =
false;
3256 const bool search_syntax =
false;
3257 const bool search_options =
false;
3258 if (command_name.contains_insensitive(search_word) ||
3260 search_long_help, search_syntax,
3269 multiword_cmd->GetSubcommandDictionary());
3270 for (
const auto &subcommand_name : subcommands_found) {
3271 std::string qualified_name =
3272 (command_name +
" " + subcommand_name).str();
3282 bool search_builtin_commands,
3283 bool search_user_commands,
3284 bool search_alias_commands,
3285 bool search_user_mw_commands) {
3286 if (search_builtin_commands)
3290 if (search_user_commands)
3294 if (search_user_mw_commands)
3298 if (search_alias_commands)
3306 return m_debugger.GetSelectedExecutionContext(adopt_dummy_target);
3310 if (!adopt_dummy_target && candidate_target &&
3313 return candidate_context;
3328 m_debugger.FlushProcessOutput(*process_sp,
true,
3357 if (!
m_debugger.IsIOHandlerThreadCurrentThread())
3360 bool was_interrupted =
3363 return was_interrupted;
3367 llvm::StringRef str,
3374 bool had_output = !str.empty();
3375 while (!str.empty()) {
3376 llvm::StringRef line;
3377 std::tie(line, str) = str.split(
'\n');
3380 stream_file.
Write(line.data(), line.size());
3381 stream_file.
Write(
"\n", 1);
3388 stream_file.
PutCString(
"\n... Interrupted.\n");
3389 stream_file.
Flush();
3393 llvm::StringRef line,
const Flags &io_handler_flags)
const {
3397 llvm::StringRef command = line.trim();
3398 if (command.empty())
3408 std::string &line) {
3414 const bool allow_repeats =
3417 if (!is_interactive && !allow_repeats) {
3426 if (!is_interactive) {
3440 m_debugger.GetSelectedExecutionContext(
true);
3441 bool pushed_exe_ctx =
false;
3444 pushed_exe_ctx =
true;
3446 llvm::scope_exit finalize([
this, pushed_exe_ctx]() {
3455 if ((result.Succeeded() &&
3460 const bool inline_diagnostics = !result.GetImmediateErrorStream() &&
3462 if (inline_diagnostics) {
3463 unsigned prompt_len =
m_debugger.GetPrompt().size();
3464 if (
auto indent = result.GetDiagnosticIndent()) {
3466 result.GetInlineDiagnosticString(prompt_len + *indent);
3474 if (!result.GetImmediateOutputStream()) {
3475 llvm::StringRef output = result.GetOutputString();
3480 if (!result.GetImmediateErrorStream()) {
3481 std::string
error = result.GetErrorString(!inline_diagnostics);
3489 DefaultPrintCallback(result);
3491 DefaultPrintCallback(result);
3497 switch (result.GetStatus()) {
3511 m_result.IncrementNumberOfErrors();
3526 result.GetDidChangeProcessState() &&
3551 if (script_interpreter) {
3560 if (output_file == std::nullopt || output_file->empty()) {
3561 std::string now = llvm::to_string(std::chrono::system_clock::now());
3562 llvm::replace(now,
' ',
'_');
3564 llvm::replace(now,
':',
'-');
3565 const std::string file_name =
"lldb_session_" + now +
".log";
3570 save_location = HostInfo::GetGlobalTempDir();
3574 output_file = save_location.
GetPath();
3577 auto error_out = [&](llvm::StringRef error_message, std::string description) {
3579 output_file, description);
3581 "Failed to save session's transcripts to {0}!", *output_file);
3592 return error_out(
"Unable to create file",
3593 llvm::toString(opened_file.takeError()));
3595 FileUP file = std::move(opened_file.get());
3602 return error_out(
"Unable to write to destination file",
3603 "Bytes written do not match transcript size.");
3607 output_file->c_str());
3610 "Note: the setting interpreter.save-transcript is set to false, so the "
3611 "transcript might not have been recorded.");
3615 error = file->GetFileSpec(
const_cast<FileSpec &
>(file_spec));
3616 if (
error.Success()) {
3618 m_debugger.GetExternalEditor(), file_spec, 1))
3642 llvm::StringRef(prompt),
3649 if (io_handler_sp) {
3650 io_handler_sp->SetUserData(baton);
3661 llvm::StringRef(prompt),
3668 if (io_handler_sp) {
3669 io_handler_sp->SetUserData(baton);
3729 bool force_create =
true;
3743 m_debugger.SetIOHandlerThread(new_io_handler_thread);
3745 m_debugger.SetIOHandlerThread(old_io_handler_thread);
3757 std::string scratch_command(command_line);
3761 bool wants_raw_input =
false;
3762 std::string next_word;
3766 auto build_alias_cmd = [&](std::string &full_name) {
3767 revised_command_line.
Clear();
3769 std::string alias_result;
3772 revised_command_line.
PutCString(alias_result);
3779 char quote_char =
'\0';
3782 if (cmd_obj ==
nullptr) {
3783 std::string full_name;
3786 bool is_real_command =
3787 (!is_alias) || (cmd_obj !=
nullptr && !cmd_obj->
IsAlias());
3788 if (!is_real_command) {
3789 build_alias_cmd(full_name);
3807 revised_command_line.
Clear();
3808 revised_command_line.
PutCString(sub_cmd_name);
3809 cmd_obj = sub_cmd_obj;
3813 revised_command_line.
Printf(
" %c%s%s%c", quote_char,
3814 next_word.c_str(), suffix.c_str(),
3817 revised_command_line.
Printf(
" %s%s", next_word.c_str(),
3823 revised_command_line.
Printf(
" %c%s%s%c", quote_char,
3824 next_word.c_str(), suffix.c_str(),
3827 revised_command_line.
Printf(
" %s%s", next_word.c_str(),
3833 if (cmd_obj ==
nullptr) {
3834 const size_t num_matches = matches.
GetSize();
3839 if (alias_matches.
GetSize() == 1) {
3840 std::string full_name;
3842 build_alias_cmd(full_name);
3843 done =
static_cast<bool>(cmd_obj);
3846 error_msg.
Printf(
"ambiguous command '%s'. Possible matches:\n",
3848 for (uint32_t i = 0; i < num_matches; ++i)
3863 if (!suffix.empty()) {
3865 "command '%s' did not recognize '%s%s%s' as valid (subcommand "
3866 "might be invalid)",
3868 next_word.empty() ?
"" : next_word.c_str(),
3869 next_word.empty() ?
" -- " :
" ", suffix.c_str());
3875 if (!suffix.empty()) {
3876 switch (suffix[0]) {
3881 if (command_options &&
3883 std::string gdb_format_option(
"--gdb-format=");
3884 gdb_format_option += (suffix.c_str() + 1);
3886 std::string cmd = std::string(revised_command_line.
GetString());
3888 if (arg_terminator_idx != std::string::npos) {
3891 gdb_format_option.append(1,
' ');
3892 cmd.insert(arg_terminator_idx, gdb_format_option);
3893 revised_command_line.
Clear();
3896 revised_command_line.
Printf(
" %s", gdb_format_option.c_str());
3898 if (wants_raw_input &&
3903 "the '%s' command doesn't support the --gdb-format option",
3917 if (scratch_command.empty())
3921 if (!scratch_command.empty())
3922 revised_command_line.
Printf(
" %s", scratch_command.c_str());
3924 if (cmd_obj !=
nullptr)
3925 command_line = std::string(revised_command_line.
GetString());
3931 llvm::json::Object stats;
3933 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()
#define LLDB_INVALID_ADDRESS
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)