diff options
Diffstat (limited to 'lldb/source/Interpreter/CommandInterpreter.cpp')
-rw-r--r-- | lldb/source/Interpreter/CommandInterpreter.cpp | 220 |
1 files changed, 116 insertions, 104 deletions
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index fb503fe0afb0..00e9ccb762c3 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// +#include <cstdlib> #include <limits> #include <memory> -#include <stdlib.h> #include <string> #include <vector> @@ -76,6 +76,7 @@ #include "lldb/Target/UnixSignals.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/FormatAdapters.h" #include "llvm/Support/Path.h" @@ -121,9 +122,8 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger, IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand), m_debugger(debugger), m_synchronous_execution(true), m_skip_lldbinit_files(false), m_skip_app_init_files(false), - m_command_io_handler_sp(), m_comment_char('#'), - m_batch_command_mode(false), m_truncation_warning(eNoTruncation), - m_command_source_depth(0), m_result(), m_transcript_stream() { + m_comment_char('#'), m_batch_command_mode(false), + m_truncation_warning(eNoTruncation), m_command_source_depth(0) { SetEventName(eBroadcastBitThreadShouldExit, "thread-should-exit"); SetEventName(eBroadcastBitResetPrompt, "reset-prompt"); SetEventName(eBroadcastBitQuitCommandReceived, "quit"); @@ -160,6 +160,16 @@ void CommandInterpreter::SetSaveSessionOnQuit(bool enable) { m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, enable); } +FileSpec CommandInterpreter::GetSaveSessionDirectory() const { + const uint32_t idx = ePropertySaveSessionDirectory; + return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); +} + +void CommandInterpreter::SetSaveSessionDirectory(llvm::StringRef path) { + const uint32_t idx = ePropertySaveSessionDirectory; + m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, path); +} + bool CommandInterpreter::GetEchoCommands() const { const uint32_t idx = ePropertyEchoCommands; return m_collection_sp->GetPropertyAtIndexAsBoolean( @@ -223,6 +233,12 @@ bool CommandInterpreter::GetSpaceReplPrompts() const { nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); } +bool CommandInterpreter::GetRepeatPreviousCommand() const { + const uint32_t idx = ePropertyRepeatPreviousCommand; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); +} + void CommandInterpreter::Initialize() { LLDB_SCOPED_TIMER(); @@ -416,17 +432,14 @@ void CommandInterpreter::Initialize() { cmd_obj_sp = GetCommandSPExact("process launch"); if (cmd_obj_sp) { alias_arguments_vector_sp = std::make_shared<OptionArgVector>(); -#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) +#if defined(__APPLE__) +#if defined(TARGET_OS_IPHONE) AddAlias("r", cmd_obj_sp, "--"); AddAlias("run", cmd_obj_sp, "--"); #else -#if defined(__APPLE__) - std::string shell_option; - shell_option.append("--shell-expand-args"); - shell_option.append(" true"); - shell_option.append(" --"); AddAlias("r", cmd_obj_sp, "--shell-expand-args true --"); AddAlias("run", cmd_obj_sp, "--shell-expand-args true --"); +#endif #else StreamString defaultshell; defaultshell.Printf("--shell=%s --", @@ -434,7 +447,6 @@ void CommandInterpreter::Initialize() { AddAlias("r", cmd_obj_sp, defaultshell.GetString()); AddAlias("run", cmd_obj_sp, defaultshell.GetString()); #endif -#endif } cmd_obj_sp = GetCommandSPExact("target symbols add"); @@ -1463,7 +1475,6 @@ CommandObject *CommandInterpreter::BuildAliasResult( "need at least %d arguments to use " "this alias.\n", index); - result.SetStatus(eReturnStatusFailed); return nullptr; } else { size_t strpos = raw_input_string.find(cmd_args.GetArgumentAtIndex(index)); @@ -1631,12 +1642,18 @@ Status CommandInterpreter::PreprocessCommand(std::string &command) { bool CommandInterpreter::HandleCommand(const char *command_line, LazyBool lazy_add_to_history, - CommandReturnObject &result, - ExecutionContext *override_context, - bool repeat_on_empty_command, - bool no_context_switching) + const ExecutionContext &override_context, + CommandReturnObject &result) { + + OverrideExecutionContext(override_context); + bool status = HandleCommand(command_line, lazy_add_to_history, result); + RestoreExecutionContext(); + return status; +} -{ +bool CommandInterpreter::HandleCommand(const char *command_line, + LazyBool lazy_add_to_history, + CommandReturnObject &result) { std::string command_string(command_line); std::string original_command_string(command_line); @@ -1648,12 +1665,8 @@ bool CommandInterpreter::HandleCommand(const char *command_line, LLDB_LOGF(log, "Processing command: %s", command_line); LLDB_SCOPED_TIMERF("Processing command: %s.", command_line); - if (!no_context_switching) - UpdateExecutionContext(override_context); - if (WasInterrupted()) { result.AppendError("interrupted"); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1689,33 +1702,31 @@ bool CommandInterpreter::HandleCommand(const char *command_line, } else { result.AppendErrorWithFormat("Could not find entry: %s in history", command_string.c_str()); - result.SetStatus(eReturnStatusFailed); return false; } } } if (empty_command) { - if (repeat_on_empty_command) { - if (m_command_history.IsEmpty()) { - result.AppendError("empty command"); - result.SetStatus(eReturnStatusFailed); - return false; - } else { - command_line = m_repeat_command.c_str(); - command_string = command_line; - original_command_string = command_line; - if (m_repeat_command.empty()) { - result.AppendError("No auto repeat."); - result.SetStatus(eReturnStatusFailed); - return false; - } - } - add_to_history = false; - } else { + if (!GetRepeatPreviousCommand()) { result.SetStatus(eReturnStatusSuccessFinishNoResult); return true; } + + if (m_command_history.IsEmpty()) { + result.AppendError("empty command"); + return false; + } + + command_line = m_repeat_command.c_str(); + command_string = command_line; + original_command_string = command_line; + if (m_repeat_command.empty()) { + result.AppendError("No auto repeat."); + return false; + } + + add_to_history = false; } else if (comment_command) { result.SetStatus(eReturnStatusSuccessFinishNoResult); return true; @@ -1725,7 +1736,6 @@ bool CommandInterpreter::HandleCommand(const char *command_line, if (error.Fail()) { result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); return false; } @@ -1852,8 +1862,6 @@ void CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) { void CommandInterpreter::HandleCompletion(CompletionRequest &request) { - UpdateExecutionContext(nullptr); - // Don't complete comments, and if the line we are completing is just the // history repeat character, substitute the appropriate history line. llvm::StringRef first_arg = request.GetParsedLine().GetArgumentAtIndex(0); @@ -1885,8 +1893,6 @@ CommandInterpreter::GetAutoSuggestionForCommand(llvm::StringRef line) { return llvm::None; } -CommandInterpreter::~CommandInterpreter() {} - void CommandInterpreter::UpdatePrompt(llvm::StringRef new_prompt) { EventSP prompt_change_event_sp( new Event(eBroadcastBitResetPrompt, new EventDataBytes(new_prompt))); @@ -1997,7 +2003,6 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj, "need at least %d arguments to use " "this alias.\n", index); - result.SetStatus(eReturnStatusFailed); return; } else { // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string @@ -2128,13 +2133,12 @@ void CommandInterpreter::SourceInitFile(FileSpec file, // broadcasting of the commands back to any appropriate listener (see // CommandObjectSource::Execute for more details). const bool saved_batch = SetBatchCommandMode(true); - ExecutionContext *ctx = nullptr; CommandInterpreterRunOptions options; options.SetSilent(true); options.SetPrintErrors(true); options.SetStopOnError(false); options.SetStopOnContinue(true); - HandleCommandsFromFile(file, ctx, options, result); + HandleCommandsFromFile(file, options, result); SetBatchCommandMode(saved_batch); } @@ -2168,7 +2172,6 @@ void CommandInterpreter::SourceInitFileCwd(CommandReturnObject &result) { result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { result.AppendError(InitFileWarning); - result.SetStatus(eReturnStatusFailed); } } } @@ -2225,7 +2228,8 @@ PlatformSP CommandInterpreter::GetPlatform(bool prefer_target_platform) { } bool CommandInterpreter::DidProcessStopAbnormally() const { - TargetSP target_sp = m_debugger.GetTargetList().GetSelectedTarget(); + auto exe_ctx = GetExecutionContext(); + TargetSP target_sp = exe_ctx.GetTargetSP(); if (!target_sp) return false; @@ -2242,7 +2246,9 @@ bool CommandInterpreter::DidProcessStopAbnormally() const { return false; const StopReason reason = stop_info->GetStopReason(); - if (reason == eStopReasonException || reason == eStopReasonInstrumentation) + if (reason == eStopReasonException || + reason == eStopReasonInstrumentation || + reason == eStopReasonProcessorTrace) return true; if (reason == eStopReasonSignal) { @@ -2263,9 +2269,19 @@ bool CommandInterpreter::DidProcessStopAbnormally() const { return false; } +void +CommandInterpreter::HandleCommands(const StringList &commands, + const ExecutionContext &override_context, + const CommandInterpreterRunOptions &options, + CommandReturnObject &result) { + + OverrideExecutionContext(override_context); + HandleCommands(commands, options, result); + RestoreExecutionContext(); +} + void CommandInterpreter::HandleCommands(const StringList &commands, - ExecutionContext *override_context, - CommandInterpreterRunOptions &options, + const CommandInterpreterRunOptions &options, CommandReturnObject &result) { size_t num_lines = commands.GetSize(); @@ -2275,13 +2291,6 @@ void CommandInterpreter::HandleCommands(const StringList &commands, bool old_async_execution = m_debugger.GetAsyncExecution(); - // If we've been given an execution context, set it at the start, but don't - // keep resetting it or we will cause series of commands that change the - // context, then do an operation that relies on that context to fail. - - if (override_context != nullptr) - UpdateExecutionContext(override_context); - if (!options.GetStopOnContinue()) { m_debugger.SetAsyncExecution(false); } @@ -2299,20 +2308,14 @@ void CommandInterpreter::HandleCommands(const StringList &commands, CommandReturnObject tmp_result(m_debugger.GetUseColor()); tmp_result.SetInteractive(result.GetInteractive()); - - // If override_context is not NULL, pass no_context_switching = true for - // HandleCommand() since we updated our context already. + tmp_result.SetSuppressImmediateOutput(true); // We might call into a regex or alias command, in which case the // add_to_history will get lost. This m_command_source_depth dingus is the // way we turn off adding to the history in that case, so set it up here. if (!options.GetAddToHistory()) m_command_source_depth++; - bool success = - HandleCommand(cmd, options.m_add_to_history, tmp_result, - nullptr, /* override_context */ - true, /* repeat_on_empty_command */ - override_context != nullptr /* no_context_switching */); + bool success = HandleCommand(cmd, options.m_add_to_history, tmp_result); if (!options.GetAddToHistory()) m_command_source_depth--; @@ -2330,7 +2333,6 @@ void CommandInterpreter::HandleCommands(const StringList &commands, "Aborting reading of commands after command #%" PRIu64 ": '%s' failed with %s", (uint64_t)idx, cmd, error_msg.str().c_str()); - result.SetStatus(eReturnStatusFailed); m_debugger.SetAsyncExecution(old_async_execution); return; } else if (options.GetPrintResults()) { @@ -2413,13 +2415,19 @@ enum { }; void CommandInterpreter::HandleCommandsFromFile( - FileSpec &cmd_file, ExecutionContext *context, - CommandInterpreterRunOptions &options, CommandReturnObject &result) { + FileSpec &cmd_file, const ExecutionContext &context, + const CommandInterpreterRunOptions &options, CommandReturnObject &result) { + OverrideExecutionContext(context); + HandleCommandsFromFile(cmd_file, options, result); + RestoreExecutionContext(); +} + +void CommandInterpreter::HandleCommandsFromFile(FileSpec &cmd_file, + const CommandInterpreterRunOptions &options, CommandReturnObject &result) { if (!FileSystem::Instance().Exists(cmd_file)) { result.AppendErrorWithFormat( "Error reading commands from file %s - file not found.\n", cmd_file.GetFilename().AsCString("<Unknown>")); - result.SetStatus(eReturnStatusFailed); return; } @@ -2431,7 +2439,6 @@ void CommandInterpreter::HandleCommandsFromFile( result.AppendErrorWithFormatv( "error: an error occurred read file '{0}': {1}\n", cmd_file_path, llvm::fmt_consume(input_file_up.takeError())); - result.SetStatus(eReturnStatusFailed); return; } FileSP input_file_sp = FileSP(std::move(input_file_up.get())); @@ -2678,7 +2685,7 @@ void CommandInterpreter::FindCommandsForApropos( const bool search_long_help = false; const bool search_syntax = false; const bool search_options = false; - if (command_name.contains_lower(search_word) || + if (command_name.contains_insensitive(search_word) || cmd_obj->HelpTextContainsWord(search_word, search_short_help, search_long_help, search_syntax, search_options)) { @@ -2715,23 +2722,24 @@ void CommandInterpreter::FindCommandsForApropos(llvm::StringRef search_word, m_alias_dict); } -void CommandInterpreter::UpdateExecutionContext( - ExecutionContext *override_context) { - if (override_context != nullptr) { - m_exe_ctx_ref = *override_context; - } else { - const bool adopt_selected = true; - m_exe_ctx_ref.SetTargetPtr(m_debugger.GetSelectedTarget().get(), - adopt_selected); - } +ExecutionContext CommandInterpreter::GetExecutionContext() const { + return !m_overriden_exe_contexts.empty() + ? m_overriden_exe_contexts.top() + : m_debugger.GetSelectedExecutionContext(); } -void CommandInterpreter::GetProcessOutput() { - TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget()); - if (!target_sp) - return; +void CommandInterpreter::OverrideExecutionContext( + const ExecutionContext &override_context) { + m_overriden_exe_contexts.push(override_context); +} + +void CommandInterpreter::RestoreExecutionContext() { + if (!m_overriden_exe_contexts.empty()) + m_overriden_exe_contexts.pop(); +} - if (ProcessSP process_sp = target_sp->GetProcessSP()) +void CommandInterpreter::GetProcessOutput() { + if (ProcessSP process_sp = GetExecutionContext().GetProcessSP()) m_debugger.FlushProcessOutput(*process_sp, /*flush_stdout*/ true, /*flush_stderr*/ true); } @@ -2831,6 +2839,11 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, StartHandlingCommand(); + OverrideExecutionContext(m_debugger.GetSelectedExecutionContext()); + auto finalize = llvm::make_scope_exit([this]() { + RestoreExecutionContext(); + }); + lldb_private::CommandReturnObject result(m_debugger.GetUseColor()); HandleCommand(line.c_str(), eLazyBoolCalculate, result); @@ -2922,9 +2935,15 @@ bool CommandInterpreter::SaveTranscript( 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"; - FileSpec tmp = HostInfo::GetGlobalTempDir(); - tmp.AppendPathComponent(file_name); - output_file = tmp.GetPath(); + + FileSpec save_location = GetSaveSessionDirectory(); + + if (!save_location) + save_location = HostInfo::GetGlobalTempDir(); + + FileSystem::Instance().Resolve(save_location); + save_location.AppendPathComponent(file_name); + output_file = save_location.GetPath(); } auto error_out = [&](llvm::StringRef error_message, std::string description) { @@ -2955,6 +2974,7 @@ bool CommandInterpreter::SaveTranscript( return error_out("Unable to write to destination file", "Bytes written do not match transcript size."); + result.SetStatus(eReturnStatusSuccessFinishNoResult); result.AppendMessageWithFormat("Session's transcripts saved to %s\n", output_file->c_str()); @@ -2973,9 +2993,9 @@ void CommandInterpreter::GetLLDBCommandsFromIOHandler( IOHandlerSP io_handler_sp( new IOHandlerEditline(debugger, IOHandler::Type::CommandList, "lldb", // Name of input reader for history - llvm::StringRef::withNullAsEmpty(prompt), // Prompt - llvm::StringRef(), // Continuation prompt - true, // Get multiple lines + llvm::StringRef(prompt), // Prompt + llvm::StringRef(), // Continuation prompt + true, // Get multiple lines debugger.GetUseColor(), 0, // Don't show line numbers delegate, // IOHandlerDelegate @@ -2993,9 +3013,9 @@ void CommandInterpreter::GetPythonCommandsFromIOHandler( IOHandlerSP io_handler_sp( new IOHandlerEditline(debugger, IOHandler::Type::PythonCode, "lldb-python", // Name of input reader for history - llvm::StringRef::withNullAsEmpty(prompt), // Prompt - llvm::StringRef(), // Continuation prompt - true, // Get multiple lines + llvm::StringRef(prompt), // Prompt + llvm::StringRef(), // Continuation prompt + true, // Get multiple lines debugger.GetUseColor(), 0, // Don't show line numbers delegate, // IOHandlerDelegate @@ -3088,7 +3108,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, CommandObject *cmd_obj = nullptr; StreamString revised_command_line; bool wants_raw_input = false; - size_t actual_cmd_name_len = 0; std::string next_word; StringList matches; bool done = false; @@ -3110,12 +3129,10 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, revised_command_line.Printf("%s", alias_result.c_str()); if (cmd_obj) { wants_raw_input = cmd_obj->WantsRawCommandString(); - actual_cmd_name_len = cmd_obj->GetCommandName().size(); } } else { if (cmd_obj) { llvm::StringRef cmd_name = cmd_obj->GetCommandName(); - actual_cmd_name_len += cmd_name.size(); revised_command_line.Printf("%s", cmd_name.str().c_str()); wants_raw_input = cmd_obj->WantsRawCommandString(); } else { @@ -3130,7 +3147,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, // The subcommand's name includes the parent command's name, so // restart rather than append to the revised_command_line. llvm::StringRef sub_cmd_name = sub_cmd_obj->GetCommandName(); - actual_cmd_name_len = sub_cmd_name.size() + 1; revised_command_line.Clear(); revised_command_line.Printf("%s", sub_cmd_name.str().c_str()); cmd_obj = sub_cmd_obj; @@ -3174,7 +3190,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, result.AppendErrorWithFormat("'%s' is not a valid command.\n", next_word.c_str()); } - result.SetStatus(eReturnStatusFailed); return nullptr; } @@ -3186,7 +3201,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, cmd_obj->GetCommandName().str().c_str(), next_word.empty() ? "" : next_word.c_str(), next_word.empty() ? " -- " : " ", suffix.c_str()); - result.SetStatus(eReturnStatusFailed); return nullptr; } } else { @@ -3222,7 +3236,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, result.AppendErrorWithFormat( "the '%s' command doesn't support the --gdb-format option\n", cmd_obj->GetCommandName().str().c_str()); - result.SetStatus(eReturnStatusFailed); return nullptr; } } @@ -3231,7 +3244,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, default: result.AppendErrorWithFormat( "unknown command shorthand suffix: '%s'\n", suffix.c_str()); - result.SetStatus(eReturnStatusFailed); return nullptr; } } |