aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Interpreter/CommandInterpreter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Interpreter/CommandInterpreter.cpp')
-rw-r--r--lldb/source/Interpreter/CommandInterpreter.cpp220
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;
}
}