diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h --- a/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -26,6 +26,32 @@ #include namespace lldb_private { +class CommandInterpreter; + +class CommandInterpreterRunResult { +public: + CommandInterpreterRunResult() + : m_num_errors(0), m_result(lldb::eCommandInterpreterResultSuccess) {} + + uint32_t GetNumErrors() const { return m_num_errors; } + + lldb::CommandInterpreterResult GetResult() const { return m_result; } + + bool IsResult(lldb::CommandInterpreterResult result) { + return m_result = result; + } + +protected: + friend CommandInterpreter; + + void IncrementNumberOfErrors() { m_num_errors++; } + + void SetResult(lldb::CommandInterpreterResult result) { m_result = result; } + +private: + int m_num_errors; + lldb::CommandInterpreterResult m_result; +}; class CommandInterpreterRunOptions { public: @@ -442,7 +468,8 @@ bool IsActive(); - void RunCommandInterpreter(CommandInterpreterRunOptions &options); + CommandInterpreterRunResult + RunCommandInterpreter(CommandInterpreterRunOptions &options); void GetLLDBCommandsFromIOHandler(const char *prompt, IOHandlerDelegate &delegate, @@ -489,16 +516,10 @@ bool GetStopCmdSourceOnError() const; - uint32_t GetNumErrors() const { return m_num_errors; } - - bool GetQuitRequested() const { return m_quit_requested; } - lldb::IOHandlerSP GetIOHandler(bool force_create = false, CommandInterpreterRunOptions *options = nullptr); - bool GetStoppedForCrash() const { return m_stopped_for_crash; } - bool GetSpaceReplPrompts() const; protected: @@ -589,9 +610,7 @@ // the user has been told uint32_t m_command_source_depth; std::vector m_command_source_flags; - uint32_t m_num_errors; - bool m_quit_requested; - bool m_stopped_for_crash; + CommandInterpreterRunResult m_result; // The exit code the user has requested when calling the 'quit' command. // No value means the user hasn't set a custom exit code so far. diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -1081,6 +1081,20 @@ eTypeSummaryCapped = true, eTypeSummaryUncapped = false }; + +/// The result from a command interpreter run. +enum CommandInterpreterResult { + /// Command interpreter finished successfully. + eCommandInterpreterResultSuccess, + /// Stopped because the corresponding option was set and the inferior + /// crashed. + eCommandInterpreterResultInferiorCrash, + /// Stopped because the corresponding option was set and a command returned + /// an error. + eCommandInterpreterResultCommandError, + /// Stopped because quit was requested. + eCommandInterpreterResultQuitRequested, +}; } // namespace lldb #endif // LLDB_LLDB_ENUMERATIONS_H diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -1190,10 +1190,13 @@ options.SetAutoHandleEvents(auto_handle_events); options.SetSpawnThread(spawn_thread); CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter(); - interp.RunCommandInterpreter(options.ref()); - num_errors = interp.GetNumErrors(); - quit_requested = interp.GetQuitRequested(); - stopped_for_crash = interp.GetStoppedForCrash(); + CommandInterpreterRunResult result = + interp.RunCommandInterpreter(options.ref()); + num_errors = result.GetNumErrors(); + quit_requested = + result.IsResult(lldb::eCommandInterpreterResultQuitRequested); + stopped_for_crash = + result.IsResult(lldb::eCommandInterpreterResultInferiorCrash); } } diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -116,8 +116,7 @@ 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_num_errors(0), m_quit_requested(false), - m_stopped_for_crash(false) { + m_command_source_depth(0) { SetEventName(eBroadcastBitThreadShouldExit, "thread-should-exit"); SetEventName(eBroadcastBitResetPrompt, "reset-prompt"); SetEventName(eBroadcastBitQuitCommandReceived, "quit"); @@ -2816,23 +2815,24 @@ break; case eReturnStatusFailed: - m_num_errors++; + m_result.IncrementNumberOfErrors(); if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError)) io_handler.SetIsDone(true); break; case eReturnStatusQuit: - m_quit_requested = true; + m_result.SetResult(lldb::eCommandInterpreterResultQuitRequested); io_handler.SetIsDone(true); break; } // Finally, if we're going to stop on crash, check that here: - if (!m_quit_requested && result.GetDidChangeProcessState() && + if (m_result.IsResult(lldb::eCommandInterpreterResultSuccess) && + result.GetDidChangeProcessState() && io_handler.GetFlags().Test(eHandleCommandFlagStopOnCrash) && DidProcessStopAbnormally()) { io_handler.SetIsDone(true); - m_stopped_for_crash = true; + m_result.SetResult(lldb::eCommandInterpreterResultInferiorCrash); } } @@ -2950,13 +2950,13 @@ return m_command_io_handler_sp; } -void CommandInterpreter::RunCommandInterpreter( +CommandInterpreterRunResult CommandInterpreter::RunCommandInterpreter( CommandInterpreterRunOptions &options) { // Always re-create the command interpreter when we run it in case any file // handles have changed. bool force_create = true; m_debugger.RunIOHandlerAsync(GetIOHandler(force_create, &options)); - m_stopped_for_crash = false; + m_result = CommandInterpreterRunResult(); if (options.GetAutoHandleEvents()) m_debugger.StartEventHandlerThread(); @@ -2969,6 +2969,8 @@ if (options.GetAutoHandleEvents()) m_debugger.StopEventHandlerThread(); } + + return m_result; } CommandObject *