aboutsummaryrefslogtreecommitdiffstats
path: root/source/Interpreter/CommandInterpreter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Interpreter/CommandInterpreter.cpp')
-rw-r--r--source/Interpreter/CommandInterpreter.cpp375
1 files changed, 138 insertions, 237 deletions
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index 8948037a6307..0c059096c6cd 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -16,7 +16,6 @@
#include "Commands/CommandObjectApropos.h"
#include "Commands/CommandObjectBreakpoint.h"
-#include "Commands/CommandObjectBugreport.h"
#include "Commands/CommandObjectCommands.h"
#include "Commands/CommandObjectDisassemble.h"
#include "Commands/CommandObjectExpression.h"
@@ -64,11 +63,14 @@
#include "lldb/Utility/Args.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/StopInfo.h"
#include "lldb/Target/TargetList.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Target/UnixSignals.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -77,10 +79,6 @@ using namespace lldb_private;
static const char *k_white_space = " \t\v";
-static constexpr bool NoGlobalSetting = true;
-static constexpr uintptr_t DefaultValueTrue = true;
-static constexpr uintptr_t DefaultValueFalse = false;
-static constexpr const char *NoCStrDefault = nullptr;
static constexpr const char *InitFileWarning =
"There is a .lldbinit file in the current directory which is not being "
"read.\n"
@@ -93,38 +91,12 @@ static constexpr const char *InitFileWarning =
"and\n"
"accept the security risk.";
-static constexpr PropertyDefinition g_properties[] = {
- {"expand-regex-aliases", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueFalse, NoCStrDefault, {},
- "If true, regular expression alias commands will show the "
- "expanded command that will be executed. This can be used to "
- "debug new regular expression alias commands."},
- {"prompt-on-quit", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueTrue, NoCStrDefault, {},
- "If true, LLDB will prompt you before quitting if there are any live "
- "processes being debugged. If false, LLDB will quit without asking in any "
- "case."},
- {"stop-command-source-on-error", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueTrue, NoCStrDefault, {},
- "If true, LLDB will stop running a 'command source' "
- "script upon encountering an error."},
- {"space-repl-prompts", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueFalse, NoCStrDefault, {},
- "If true, blank lines will be printed between between REPL submissions."},
- {"echo-commands", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueTrue, NoCStrDefault, {},
- "If true, commands will be echoed before they are evaluated."},
- {"echo-comment-commands", OptionValue::eTypeBoolean, NoGlobalSetting,
- DefaultValueTrue, NoCStrDefault, {},
- "If true, commands will be echoed even if they are pure comment lines."}};
+#define LLDB_PROPERTIES_interpreter
+#include "InterpreterProperties.inc"
enum {
- ePropertyExpandRegexAliases = 0,
- ePropertyPromptOnQuit = 1,
- ePropertyStopCmdSourceOnError = 2,
- eSpaceReplPrompts = 3,
- eEchoCommands = 4,
- eEchoCommentCommands = 5
+#define LLDB_PROPERTIES_interpreter
+#include "InterpreterPropertiesEnum.inc"
};
ConstString &CommandInterpreter::GetStaticBroadcasterClass() {
@@ -139,7 +111,7 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger,
Properties(OptionValuePropertiesSP(
new OptionValueProperties(ConstString("interpreter")))),
IOHandlerDelegate(IOHandlerDelegate::Completion::LLDBCommand),
- m_debugger(debugger), m_synchronous_execution(synchronous_execution),
+ 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),
@@ -148,20 +120,21 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger,
SetEventName(eBroadcastBitThreadShouldExit, "thread-should-exit");
SetEventName(eBroadcastBitResetPrompt, "reset-prompt");
SetEventName(eBroadcastBitQuitCommandReceived, "quit");
+ SetSynchronous(synchronous_execution);
CheckInWithManager();
- m_collection_sp->Initialize(g_properties);
+ m_collection_sp->Initialize(g_interpreter_properties);
}
bool CommandInterpreter::GetExpandRegexAliases() const {
const uint32_t idx = ePropertyExpandRegexAliases;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
bool CommandInterpreter::GetPromptOnQuit() const {
const uint32_t idx = ePropertyPromptOnQuit;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
void CommandInterpreter::SetPromptOnQuit(bool b) {
@@ -170,24 +143,24 @@ void CommandInterpreter::SetPromptOnQuit(bool b) {
}
bool CommandInterpreter::GetEchoCommands() const {
- const uint32_t idx = eEchoCommands;
+ const uint32_t idx = ePropertyEchoCommands;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
void CommandInterpreter::SetEchoCommands(bool b) {
- const uint32_t idx = eEchoCommands;
+ const uint32_t idx = ePropertyEchoCommands;
m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
bool CommandInterpreter::GetEchoCommentCommands() const {
- const uint32_t idx = eEchoCommentCommands;
+ const uint32_t idx = ePropertyEchoCommentCommands;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
void CommandInterpreter::SetEchoCommentCommands(bool b) {
- const uint32_t idx = eEchoCommentCommands;
+ const uint32_t idx = ePropertyEchoCommentCommands;
m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
@@ -223,13 +196,13 @@ void CommandInterpreter::ResolveCommand(const char *command_line,
bool CommandInterpreter::GetStopCmdSourceOnError() const {
const uint32_t idx = ePropertyStopCmdSourceOnError;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
bool CommandInterpreter::GetSpaceReplPrompts() const {
- const uint32_t idx = eSpaceReplPrompts;
+ const uint32_t idx = ePropertySpaceReplPrompts;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
- nullptr, idx, g_properties[idx].default_uint_value != 0);
+ nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0);
}
void CommandInterpreter::Initialize() {
@@ -473,8 +446,6 @@ void CommandInterpreter::LoadCommandDictionary() {
m_command_dict["apropos"] = CommandObjectSP(new CommandObjectApropos(*this));
m_command_dict["breakpoint"] =
CommandObjectSP(new CommandObjectMultiwordBreakpoint(*this));
- m_command_dict["bugreport"] =
- CommandObjectSP(new CommandObjectMultiwordBugreport(*this));
m_command_dict["command"] =
CommandObjectSP(new CommandObjectMultiwordCommands(*this));
m_command_dict["disassemble"] =
@@ -1628,8 +1599,7 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
llvm::PrettyStackTraceFormat stack_trace("HandleCommand(command = \"%s\")",
command_line);
- if (log)
- log->Printf("Processing command: %s", command_line);
+ LLDB_LOGF(log, "Processing command: %s", command_line);
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "Handling command: %s.", command_line);
@@ -1735,13 +1705,13 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
// "br s -n main", command_string is now "breakpoint set -n main".
if (log) {
llvm::StringRef command_name = cmd_obj ? cmd_obj->GetCommandName() : "<not found>";
- log->Printf("HandleCommand, cmd_obj : '%s'", command_name.str().c_str());
- log->Printf("HandleCommand, (revised) command_string: '%s'",
- command_string.c_str());
+ LLDB_LOGF(log, "HandleCommand, cmd_obj : '%s'", command_name.str().c_str());
+ LLDB_LOGF(log, "HandleCommand, (revised) command_string: '%s'",
+ command_string.c_str());
const bool wants_raw_input =
(cmd_obj != nullptr) ? cmd_obj->WantsRawCommandString() : false;
- log->Printf("HandleCommand, wants_raw_input:'%s'",
- wants_raw_input ? "True" : "False");
+ LLDB_LOGF(log, "HandleCommand, wants_raw_input:'%s'",
+ wants_raw_input ? "True" : "False");
}
// Phase 2.
@@ -1771,34 +1741,30 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
if (pos != 0 && pos != std::string::npos)
remainder.erase(0, pos);
- if (log)
- log->Printf(
- "HandleCommand, command line after removing command name(s): '%s'",
- remainder.c_str());
+ LLDB_LOGF(
+ log, "HandleCommand, command line after removing command name(s): '%s'",
+ remainder.c_str());
cmd_obj->Execute(remainder.c_str(), result);
}
- if (log)
- log->Printf("HandleCommand, command %s",
- (result.Succeeded() ? "succeeded" : "did not succeed"));
+ LLDB_LOGF(log, "HandleCommand, command %s",
+ (result.Succeeded() ? "succeeded" : "did not succeed"));
return result.Succeeded();
}
-int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
- int num_command_matches = 0;
+void CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
bool look_for_subcommand = false;
// For any of the command completions a unique match will be a complete word.
- request.SetWordComplete(true);
- if (request.GetCursorIndex() == -1) {
+ if (request.GetParsedLine().GetArgumentCount() == 0) {
// We got nothing on the command line, so return the list of commands
bool include_aliases = true;
StringList new_matches, descriptions;
- num_command_matches = GetCommandNamesMatchingPartialString(
- "", include_aliases, new_matches, descriptions);
+ GetCommandNamesMatchingPartialString("", include_aliases, new_matches,
+ descriptions);
request.AddCompletions(new_matches, descriptions);
} else if (request.GetCursorIndex() == 0) {
// The cursor is in the first argument, so just do a lookup in the
@@ -1808,24 +1774,18 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
GetCommandObject(request.GetParsedLine().GetArgumentAtIndex(0),
&new_matches, &new_descriptions);
- if (num_command_matches == 1 && cmd_obj && cmd_obj->IsMultiwordObject() &&
+ if (new_matches.GetSize() && cmd_obj && cmd_obj->IsMultiwordObject() &&
new_matches.GetStringAtIndex(0) != nullptr &&
strcmp(request.GetParsedLine().GetArgumentAtIndex(0),
new_matches.GetStringAtIndex(0)) == 0) {
- if (request.GetParsedLine().GetArgumentCount() == 1) {
- request.SetWordComplete(true);
- } else {
+ if (request.GetParsedLine().GetArgumentCount() != 1) {
look_for_subcommand = true;
- num_command_matches = 0;
new_matches.DeleteStringAtIndex(0);
new_descriptions.DeleteStringAtIndex(0);
- request.GetParsedLine().AppendArgument(llvm::StringRef());
- request.SetCursorIndex(request.GetCursorIndex() + 1);
- request.SetCursorCharPosition(0);
+ request.AppendEmptyArgument();
}
}
request.AddCompletions(new_matches, new_descriptions);
- num_command_matches = request.GetNumberOfMatches();
}
if (request.GetCursorIndex() > 0 || look_for_subcommand) {
@@ -1834,81 +1794,31 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) {
// matching initial command:
CommandObject *command_object =
GetCommandObject(request.GetParsedLine().GetArgumentAtIndex(0));
- if (command_object == nullptr) {
- return 0;
- } else {
- request.GetParsedLine().Shift();
- request.SetCursorIndex(request.GetCursorIndex() - 1);
- num_command_matches = command_object->HandleCompletion(request);
+ if (command_object) {
+ request.ShiftArguments();
+ command_object->HandleCompletion(request);
}
}
-
- return num_command_matches;
}
-int CommandInterpreter::HandleCompletion(
- const char *current_line, const char *cursor, const char *last_char,
- int match_start_point, int max_return_elements, StringList &matches,
- StringList &descriptions) {
+void CommandInterpreter::HandleCompletion(CompletionRequest &request) {
- llvm::StringRef command_line(current_line, last_char - current_line);
- CompletionResult result;
- CompletionRequest request(command_line, cursor - current_line,
- match_start_point, max_return_elements, result);
// Don't complete comments, and if the line we are completing is just the
// history repeat character, substitute the appropriate history line.
- const char *first_arg = request.GetParsedLine().GetArgumentAtIndex(0);
- if (first_arg) {
- if (first_arg[0] == m_comment_char)
- return 0;
- else if (first_arg[0] == CommandHistory::g_repeat_char) {
- if (auto hist_str = m_command_history.FindString(first_arg)) {
- matches.InsertStringAtIndex(0, *hist_str);
- descriptions.InsertStringAtIndex(0, "Previous command history event");
- return -2;
- } else
- return 0;
- }
- }
-
- // Only max_return_elements == -1 is supported at present:
- lldbassert(max_return_elements == -1);
-
- int num_command_matches = HandleCompletionMatches(request);
- result.GetMatches(matches);
- result.GetDescriptions(descriptions);
+ llvm::StringRef first_arg = request.GetParsedLine().GetArgumentAtIndex(0);
- if (num_command_matches <= 0)
- return num_command_matches;
-
- if (request.GetParsedLine().GetArgumentCount() == 0) {
- // If we got an empty string, insert nothing.
- matches.InsertStringAtIndex(0, "");
- descriptions.InsertStringAtIndex(0, "");
- } else {
- // Now figure out if there is a common substring, and if so put that in
- // element 0, otherwise put an empty string in element 0.
- std::string command_partial_str = request.GetCursorArgumentPrefix().str();
-
- std::string common_prefix;
- matches.LongestCommonPrefix(common_prefix);
- const size_t partial_name_len = command_partial_str.size();
- common_prefix.erase(0, partial_name_len);
-
- // If we matched a unique single command, add a space... Only do this if
- // the completer told us this was a complete word, however...
- if (num_command_matches == 1 && request.GetWordComplete()) {
- char quote_char = request.GetParsedLine()[request.GetCursorIndex()].quote;
- common_prefix =
- Args::EscapeLLDBCommandArgument(common_prefix, quote_char);
- if (quote_char != '\0')
- common_prefix.push_back(quote_char);
- common_prefix.push_back(' ');
+ if (!first_arg.empty()) {
+ if (first_arg.front() == m_comment_char)
+ return;
+ if (first_arg.front() == CommandHistory::g_repeat_char) {
+ if (auto hist_str = m_command_history.FindString(first_arg))
+ request.AddCompletion(*hist_str, "Previous command history event",
+ CompletionMode::RewriteLine);
+ return;
}
- matches.InsertStringAtIndex(0, common_prefix.c_str());
- descriptions.InsertStringAtIndex(0, "");
}
- return num_command_matches;
+
+ HandleCompletionMatches(request);
}
CommandInterpreter::~CommandInterpreter() {}
@@ -2051,7 +1961,7 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj,
for (auto entry : llvm::enumerate(cmd_args.entries())) {
if (!used[entry.index()] && !wants_raw_input)
- new_args.AppendArgument(entry.value().ref);
+ new_args.AppendArgument(entry.value().ref());
}
cmd_args.Clear();
@@ -2231,6 +2141,45 @@ PlatformSP CommandInterpreter::GetPlatform(bool prefer_target_platform) {
return platform_sp;
}
+bool CommandInterpreter::DidProcessStopAbnormally() const {
+ TargetSP target_sp = m_debugger.GetTargetList().GetSelectedTarget();
+ if (!target_sp)
+ return false;
+
+ ProcessSP process_sp(target_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+
+ if (eStateStopped != process_sp->GetState())
+ return false;
+
+ for (const auto &thread_sp : process_sp->GetThreadList().Threads()) {
+ StopInfoSP stop_info = thread_sp->GetStopInfo();
+ if (!stop_info)
+ return false;
+
+ const StopReason reason = stop_info->GetStopReason();
+ if (reason == eStopReasonException || reason == eStopReasonInstrumentation)
+ return true;
+
+ if (reason == eStopReasonSignal) {
+ const auto stop_signal = static_cast<int32_t>(stop_info->GetValue());
+ UnixSignalsSP signals_sp = process_sp->GetUnixSignals();
+ if (!signals_sp || !signals_sp->SignalIsValid(stop_signal))
+ // The signal is unknown, treat it as abnormal.
+ return true;
+
+ const auto sigint_num = signals_sp->GetSignalNumberFromName("SIGINT");
+ const auto sigstop_num = signals_sp->GetSignalNumberFromName("SIGSTOP");
+ if ((stop_signal != sigint_num) && (stop_signal != sigstop_num))
+ // The signal very likely implies a crash.
+ return true;
+ }
+ }
+
+ return false;
+}
+
void CommandInterpreter::HandleCommands(const StringList &commands,
ExecutionContext *override_context,
CommandInterpreterRunOptions &options,
@@ -2341,38 +2290,22 @@ void CommandInterpreter::HandleCommands(const StringList &commands,
}
// Also check for "stop on crash here:
- bool should_stop = false;
- if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash()) {
- TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget());
- if (target_sp) {
- ProcessSP process_sp(target_sp->GetProcessSP());
- if (process_sp) {
- for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) {
- StopReason reason = thread_sp->GetStopReason();
- if (reason == eStopReasonSignal || reason == eStopReasonException ||
- reason == eStopReasonInstrumentation) {
- should_stop = true;
- break;
- }
- }
- }
- }
- if (should_stop) {
- if (idx != num_lines - 1)
- result.AppendErrorWithFormat(
- "Aborting reading of commands after command #%" PRIu64
- ": '%s' stopped with a signal or exception.\n",
- (uint64_t)idx + 1, cmd);
- else
- result.AppendMessageWithFormat(
- "Command #%" PRIu64 " '%s' stopped with a signal or exception.\n",
- (uint64_t)idx + 1, cmd);
+ if (tmp_result.GetDidChangeProcessState() && options.GetStopOnCrash() &&
+ DidProcessStopAbnormally()) {
+ if (idx != num_lines - 1)
+ result.AppendErrorWithFormat(
+ "Aborting reading of commands after command #%" PRIu64
+ ": '%s' stopped with a signal or exception.\n",
+ (uint64_t)idx + 1, cmd);
+ else
+ result.AppendMessageWithFormat(
+ "Command #%" PRIu64 " '%s' stopped with a signal or exception.\n",
+ (uint64_t)idx + 1, cmd);
- result.SetStatus(tmp_result.GetStatus());
- m_debugger.SetAsyncExecution(old_async_execution);
+ result.SetStatus(tmp_result.GetStatus());
+ m_debugger.SetAsyncExecution(old_async_execution);
- return;
- }
+ return;
}
}
@@ -2405,18 +2338,18 @@ void CommandInterpreter::HandleCommandsFromFile(
return;
}
- StreamFileSP input_file_sp(new StreamFile());
std::string cmd_file_path = cmd_file.GetPath();
- Status error = FileSystem::Instance().Open(input_file_sp->GetFile(), cmd_file,
- File::eOpenOptionRead);
-
- if (error.Fail()) {
- result.AppendErrorWithFormat(
- "error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(),
- error.AsCString());
+ auto input_file_up =
+ FileSystem::Instance().Open(cmd_file, File::eOpenOptionRead);
+ if (!input_file_up) {
+ std::string error = llvm::toString(input_file_up.takeError());
+ 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()));
Debugger &debugger = GetDebugger();
@@ -2502,8 +2435,8 @@ void CommandInterpreter::HandleCommandsFromFile(
}
if (flags & eHandleCommandFlagPrintResult) {
- debugger.GetOutputFile()->Printf("Executing commands in '%s'.\n",
- cmd_file_path.c_str());
+ debugger.GetOutputFile().Printf("Executing commands in '%s'.\n",
+ cmd_file_path.c_str());
}
// Used for inheriting the right settings when "command source" might
@@ -2541,6 +2474,9 @@ void CommandInterpreter::HandleCommandsFromFile(
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;
}
@@ -2701,32 +2637,14 @@ void CommandInterpreter::UpdateExecutionContext(
}
}
-size_t CommandInterpreter::GetProcessOutput() {
- // The process has stuff waiting for stderr; get it and write it out to the
- // appropriate place.
- char stdio_buffer[1024];
- size_t len;
- size_t total_bytes = 0;
- Status error;
+void CommandInterpreter::GetProcessOutput() {
TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget());
- if (target_sp) {
- ProcessSP process_sp(target_sp->GetProcessSP());
- if (process_sp) {
- while ((len = process_sp->GetSTDOUT(stdio_buffer, sizeof(stdio_buffer),
- error)) > 0) {
- size_t bytes_written = len;
- m_debugger.GetOutputFile()->Write(stdio_buffer, bytes_written);
- total_bytes += len;
- }
- while ((len = process_sp->GetSTDERR(stdio_buffer, sizeof(stdio_buffer),
- error)) > 0) {
- size_t bytes_written = len;
- m_debugger.GetErrorFile()->Write(stdio_buffer, bytes_written);
- total_bytes += len;
- }
- }
- }
- return total_bytes;
+ if (!target_sp)
+ return;
+
+ if (ProcessSP process_sp = target_sp->GetProcessSP())
+ m_debugger.FlushProcessOutput(*process_sp, /*flush_stdout*/ true,
+ /*flush_stderr*/ true);
}
void CommandInterpreter::StartHandlingCommand() {
@@ -2818,8 +2736,8 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
// from a file) we need to echo the command out so we don't just see the
// command output and no command...
if (EchoCommandNonInteractive(line, io_handler.GetFlags()))
- io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(),
- line.c_str());
+ io_handler.GetOutputStreamFileSP()->Printf(
+ "%s%s\n", io_handler.GetPrompt(), line.c_str());
}
StartHandlingCommand();
@@ -2836,13 +2754,13 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
if (!result.GetImmediateOutputStream()) {
llvm::StringRef output = result.GetOutputData();
- PrintCommandOutput(*io_handler.GetOutputStreamFile(), output);
+ PrintCommandOutput(*io_handler.GetOutputStreamFileSP(), output);
}
// Now emit the command error text from the command we just executed
if (!result.GetImmediateErrorStream()) {
llvm::StringRef error = result.GetErrorData();
- PrintCommandOutput(*io_handler.GetErrorStreamFile(), error);
+ PrintCommandOutput(*io_handler.GetErrorStreamFileSP(), error);
}
}
@@ -2875,27 +2793,10 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler,
// Finally, if we're going to stop on crash, check that here:
if (!m_quit_requested && result.GetDidChangeProcessState() &&
- io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash)) {
- bool should_stop = false;
- TargetSP target_sp(m_debugger.GetTargetList().GetSelectedTarget());
- if (target_sp) {
- ProcessSP process_sp(target_sp->GetProcessSP());
- if (process_sp) {
- for (ThreadSP thread_sp : process_sp->GetThreadList().Threads()) {
- StopReason reason = thread_sp->GetStopReason();
- if ((reason == eStopReasonSignal || reason == eStopReasonException ||
- reason == eStopReasonInstrumentation) &&
- !result.GetAbnormalStopWasExpected()) {
- should_stop = true;
- break;
- }
- }
- }
- }
- if (should_stop) {
- io_handler.SetIsDone(true);
- m_stopped_for_crash = true;
- }
+ io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash) &&
+ DidProcessStopAbnormally()) {
+ io_handler.SetIsDone(true);
+ m_stopped_for_crash = true;
}
}
@@ -3009,8 +2910,8 @@ CommandInterpreter::GetIOHandler(bool force_create,
m_command_io_handler_sp = std::make_shared<IOHandlerEditline>(
m_debugger, IOHandler::Type::CommandInterpreter,
- m_debugger.GetInputFile(), m_debugger.GetOutputFile(),
- m_debugger.GetErrorFile(), flags, "lldb", m_debugger.GetPrompt(),
+ m_debugger.GetInputFileSP(), m_debugger.GetOutputStreamSP(),
+ m_debugger.GetErrorStreamSP(), flags, "lldb", m_debugger.GetPrompt(),
llvm::StringRef(), // Continuation prompt
false, // Don't enable multiple line input, just single line commands
m_debugger.GetUseColor(),