diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp | 132 |
1 files changed, 92 insertions, 40 deletions
diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp index 6ef209b20fc6..8b24c72d7733 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp @@ -9,12 +9,15 @@ #include <cstdlib> #include <limits> #include <memory> +#include <optional> #include <string> #include <vector> #include "Commands/CommandObjectApropos.h" #include "Commands/CommandObjectBreakpoint.h" #include "Commands/CommandObjectCommands.h" +#include "Commands/CommandObjectDWIMPrint.h" +#include "Commands/CommandObjectDiagnostics.h" #include "Commands/CommandObjectDisassemble.h" #include "Commands/CommandObjectExpression.h" #include "Commands/CommandObjectFrame.h" @@ -29,7 +32,6 @@ #include "Commands/CommandObjectQuit.h" #include "Commands/CommandObjectRegexCommand.h" #include "Commands/CommandObjectRegister.h" -#include "Commands/CommandObjectReproducer.h" #include "Commands/CommandObjectScript.h" #include "Commands/CommandObjectSession.h" #include "Commands/CommandObjectSettings.h" @@ -47,7 +49,6 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Reproducer.h" #include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" @@ -105,6 +106,11 @@ static constexpr const char *InitFileWarning = "and\n" "accept the security risk."; +const char *CommandInterpreter::g_no_argument = "<no-argument>"; +const char *CommandInterpreter::g_need_argument = "<need-argument>"; +const char *CommandInterpreter::g_argument = "<argument>"; + + #define LLDB_PROPERTIES_interpreter #include "InterpreterProperties.inc" @@ -166,6 +172,17 @@ void CommandInterpreter::SetSaveSessionOnQuit(bool enable) { m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, enable); } +bool CommandInterpreter::GetOpenTranscriptInEditor() const { + const uint32_t idx = ePropertyOpenTranscriptInEditor; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); +} + +void CommandInterpreter::SetOpenTranscriptInEditor(bool enable) { + const uint32_t idx = ePropertyOpenTranscriptInEditor; + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, enable); +} + FileSpec CommandInterpreter::GetSaveSessionDirectory() const { const uint32_t idx = ePropertySaveSessionDirectory; return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); @@ -515,7 +532,9 @@ void CommandInterpreter::LoadCommandDictionary() { REGISTER_COMMAND_OBJECT("apropos", CommandObjectApropos); REGISTER_COMMAND_OBJECT("breakpoint", CommandObjectMultiwordBreakpoint); REGISTER_COMMAND_OBJECT("command", CommandObjectMultiwordCommands); + REGISTER_COMMAND_OBJECT("diagnostics", CommandObjectDiagnostics); REGISTER_COMMAND_OBJECT("disassemble", CommandObjectDisassemble); + REGISTER_COMMAND_OBJECT("dwim-print", CommandObjectDWIMPrint); REGISTER_COMMAND_OBJECT("expression", CommandObjectExpression); REGISTER_COMMAND_OBJECT("frame", CommandObjectMultiwordFrame); REGISTER_COMMAND_OBJECT("gui", CommandObjectGUI); @@ -527,7 +546,6 @@ void CommandInterpreter::LoadCommandDictionary() { REGISTER_COMMAND_OBJECT("process", CommandObjectMultiwordProcess); REGISTER_COMMAND_OBJECT("quit", CommandObjectQuit); REGISTER_COMMAND_OBJECT("register", CommandObjectRegister); - REGISTER_COMMAND_OBJECT("reproducer", CommandObjectReproducer); REGISTER_COMMAND_OBJECT("script", CommandObjectScript); REGISTER_COMMAND_OBJECT("settings", CommandObjectMultiwordSettings); REGISTER_COMMAND_OBJECT("session", CommandObjectSession); @@ -561,7 +579,7 @@ void CommandInterpreter::LoadCommandDictionary() { "breakpoint set --name '%1'"}}; // clang-format on - size_t num_regexes = llvm::array_lengthof(break_regexes); + size_t num_regexes = std::size(break_regexes); std::unique_ptr<CommandObjectRegexCommand> break_regex_cmd_up( new CommandObjectRegexCommand( @@ -1634,7 +1652,7 @@ CommandObject *CommandInterpreter::BuildAliasResult( std::string value; for (const auto &entry : *option_arg_vector) { std::tie(option, value_type, value) = entry; - if (option == "<argument>") { + if (option == g_argument) { result_str.Printf(" %s", value.c_str()); continue; } @@ -1656,11 +1674,33 @@ CommandObject *CommandInterpreter::BuildAliasResult( index); return nullptr; } else { - size_t strpos = raw_input_string.find(cmd_args.GetArgumentAtIndex(index)); - if (strpos != std::string::npos) + const Args::ArgEntry &entry = cmd_args[index]; + size_t strpos = raw_input_string.find(entry.c_str()); + const char quote_char = entry.GetQuoteChar(); + if (strpos != std::string::npos) { + const size_t start_fudge = quote_char == '\0' ? 0 : 1; + const size_t len_fudge = quote_char == '\0' ? 0 : 2; + + // Make sure we aren't going outside the bounds of the cmd string: + if (strpos < start_fudge) { + result.AppendError("Unmatched quote at command beginning."); + return nullptr; + } + llvm::StringRef arg_text = entry.ref(); + if (strpos - start_fudge + arg_text.size() + len_fudge + > raw_input_string.size()) { + result.AppendError("Unmatched quote at command end."); + return nullptr; + } raw_input_string = raw_input_string.erase( - strpos, strlen(cmd_args.GetArgumentAtIndex(index))); - result_str.Printf("%s", cmd_args.GetArgumentAtIndex(index)); + strpos - start_fudge, + strlen(cmd_args.GetArgumentAtIndex(index)) + len_fudge); + } + if (quote_char == '\0') + result_str.Printf("%s", cmd_args.GetArgumentAtIndex(index)); + else + result_str.Printf("%c%s%c", quote_char, + entry.c_str(), quote_char); } } @@ -1725,7 +1765,7 @@ Status CommandInterpreter::PreprocessCommand(std::string &command) { options.SetIgnoreBreakpoints(true); options.SetKeepInMemory(false); options.SetTryAllThreads(true); - options.SetTimeout(llvm::None); + options.SetTimeout(std::nullopt); ExpressionResults expr_result = target.EvaluateExpression(expr_str.c_str(), exe_ctx.GetFramePtr(), @@ -1911,13 +1951,6 @@ bool CommandInterpreter::HandleCommand(const char *command_line, return true; } - Status error(PreprocessCommand(command_string)); - - if (error.Fail()) { - result.AppendError(error.AsCString()); - return false; - } - // Phase 1. // Before we do ANY kind of argument processing, we need to figure out what @@ -1935,6 +1968,20 @@ bool CommandInterpreter::HandleCommand(const char *command_line, CommandObject *cmd_obj = ResolveCommandImpl(command_string, result); + // We have to preprocess the whole command string for Raw commands, since we + // don't know the structure of the command. For parsed commands, we only + // treat backticks as quote characters specially. + // FIXME: We probably want to have raw commands do their own preprocessing. + // For instance, I don't think people expect substitution in expr expressions. + if (cmd_obj && cmd_obj->WantsRawCommandString()) { + Status error(PreprocessCommand(command_string)); + + if (error.Fail()) { + result.AppendError(error.AsCString()); + return false; + } + } + // Although the user may have abbreviated the command, the command_string now // has the command expanded to the full name. For example, if the input was // "br s -n main", command_string is now "breakpoint set -n main". @@ -1960,7 +2007,7 @@ bool CommandInterpreter::HandleCommand(const char *command_line, // repeat command, even though we don't add repeat commands to the history. if (add_to_history || empty_command) { Args command_args(command_string); - llvm::Optional<std::string> repeat_command = + std::optional<std::string> repeat_command = cmd_obj->GetRepeatCommand(command_args, 0); if (repeat_command) m_repeat_command.assign(*repeat_command); @@ -2064,17 +2111,17 @@ void CommandInterpreter::HandleCompletion(CompletionRequest &request) { HandleCompletionMatches(request); } -llvm::Optional<std::string> +std::optional<std::string> CommandInterpreter::GetAutoSuggestionForCommand(llvm::StringRef line) { if (line.empty()) - return llvm::None; + return std::nullopt; const size_t s = m_command_history.GetSize(); for (int i = s - 1; i >= 0; --i) { llvm::StringRef entry = m_command_history.GetStringAtIndex(i); if (entry.consume_front(line)) return entry.str(); } - return llvm::None; + return std::nullopt; } void CommandInterpreter::UpdatePrompt(llvm::StringRef new_prompt) { @@ -2163,7 +2210,7 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj, std::string value; for (const auto &option_entry : *option_arg_vector) { std::tie(option, value_type, value) = option_entry; - if (option == "<argument>") { + if (option == g_argument) { if (!wants_raw_input || (value != "--")) { // Since we inserted this above, make sure we don't insert it twice new_args.AppendArgument(value); @@ -2174,7 +2221,7 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj, if (value_type != OptionParser::eOptionalArgument) new_args.AppendArgument(option); - if (value == "<no-argument>") + if (value == g_no_argument) continue; int index = GetOptionArgumentPosition(value.c_str()); @@ -2440,8 +2487,12 @@ bool CommandInterpreter::DidProcessStopAbnormally() const { for (const auto &thread_sp : process_sp->GetThreadList().Threads()) { StopInfoSP stop_info = thread_sp->GetStopInfo(); - if (!stop_info) - return false; + if (!stop_info) { + // If there's no stop_info, keep iterating through the other threads; + // it's enough that any thread has got a stop_info that indicates + // an abnormal stop, to consider the process to be stopped abnormally. + continue; + } const StopReason reason = stop_info->GetStopReason(); if (reason == eStopReasonException || @@ -2742,7 +2793,7 @@ void CommandInterpreter::HandleCommandsFromFile(FileSpec &cmd_file, // or written debugger.GetPrompt(), llvm::StringRef(), false, // Not multi-line - debugger.GetUseColor(), 0, *this, nullptr)); + debugger.GetUseColor(), 0, *this)); const bool old_async_execution = debugger.GetAsyncExecution(); // Set synchronous execution if we are not stopping on continue @@ -2766,9 +2817,6 @@ void CommandInterpreter::HandleCommandsFromFile(FileSpec &cmd_file, bool CommandInterpreter::GetSynchronous() { return m_synchronous_execution; } void CommandInterpreter::SetSynchronous(bool value) { - // Asynchronous mode is not supported during reproducer replay. - if (repro::Reproducer::Instance().GetLoader()) - return; m_synchronous_execution = value; } @@ -3144,8 +3192,8 @@ bool CommandInterpreter::IOHandlerInterrupt(IOHandler &io_handler) { } bool CommandInterpreter::SaveTranscript( - CommandReturnObject &result, llvm::Optional<std::string> output_file) { - if (output_file == llvm::None || output_file->empty()) { + CommandReturnObject &result, std::optional<std::string> output_file) { + if (output_file == std::nullopt || output_file->empty()) { std::string now = llvm::to_string(std::chrono::system_clock::now()); std::replace(now.begin(), now.end(), ' ', '_'); const std::string file_name = "lldb_session_" + now + ".log"; @@ -3192,6 +3240,13 @@ bool CommandInterpreter::SaveTranscript( result.AppendMessageWithFormat("Session's transcripts saved to %s\n", output_file->c_str()); + if (GetOpenTranscriptInEditor() && Host::IsInteractiveGraphicSession()) { + const FileSpec file_spec; + error = file->GetFileSpec(const_cast<FileSpec &>(file_spec)); + if (error.Success()) + Host::OpenFileInExternalEditor(file_spec, 1); + } + return true; } @@ -3215,9 +3270,8 @@ void CommandInterpreter::GetLLDBCommandsFromIOHandler( llvm::StringRef(), // Continuation prompt true, // Get multiple lines debugger.GetUseColor(), - 0, // Don't show line numbers - delegate, // IOHandlerDelegate - nullptr)); // FileShadowCollector + 0, // Don't show line numbers + delegate)); // IOHandlerDelegate if (io_handler_sp) { io_handler_sp->SetUserData(baton); @@ -3235,9 +3289,8 @@ void CommandInterpreter::GetPythonCommandsFromIOHandler( llvm::StringRef(), // Continuation prompt true, // Get multiple lines debugger.GetUseColor(), - 0, // Don't show line numbers - delegate, // IOHandlerDelegate - nullptr)); // FileShadowCollector + 0, // Don't show line numbers + delegate)); // IOHandlerDelegate if (io_handler_sp) { io_handler_sp->SetUserData(baton); @@ -3288,9 +3341,8 @@ CommandInterpreter::GetIOHandler(bool force_create, llvm::StringRef(), // Continuation prompt false, // Don't enable multiple line input, just single line commands m_debugger.GetUseColor(), - 0, // Don't show line numbers - *this, // IOHandlerDelegate - GetDebugger().GetInputRecorder()); + 0, // Don't show line numbers + *this); // IOHandlerDelegate } return m_command_io_handler_sp; } |