diff options
Diffstat (limited to 'source/Interpreter/CommandInterpreter.cpp')
-rw-r--r-- | source/Interpreter/CommandInterpreter.cpp | 375 |
1 files changed, 138 insertions, 237 deletions
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp index 8948037a6307b..0c059096c6cdb 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(), |