From a1e84c5a03f379e7c6fabd7e0fa5db4264e61632 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Fri, 28 Mar 2025 07:01:39 -0700 Subject: [PATCH] Revert "Cherrypick commits to synchronize the debugger output and error stream" --- lldb/include/lldb/Core/Debugger.h | 38 +++-- lldb/include/lldb/Core/IOHandler.h | 38 +++-- lldb/include/lldb/Core/IOHandlerCursesGUI.h | 5 +- lldb/include/lldb/Core/StreamAsynchronousIO.h | 12 +- lldb/include/lldb/Host/Editline.h | 30 ++-- lldb/include/lldb/Host/File.h | 5 - lldb/include/lldb/Host/StreamFile.h | 52 ------- .../lldb/Interpreter/ScriptInterpreter.h | 19 +-- lldb/include/lldb/Target/ThreadPlanTracer.h | 2 +- lldb/include/lldb/Utility/AnsiTerminal.h | 25 ---- lldb/include/lldb/lldb-forward.h | 3 - lldb/source/API/SBDebugger.cpp | 28 ++-- lldb/source/Breakpoint/BreakpointOptions.cpp | 6 +- .../CommandObjectBreakpointCommand.cpp | 10 +- .../source/Commands/CommandObjectCommands.cpp | 69 ++++----- .../Commands/CommandObjectExpression.cpp | 25 ++-- lldb/source/Commands/CommandObjectGUI.cpp | 8 +- lldb/source/Commands/CommandObjectLog.cpp | 3 +- lldb/source/Commands/CommandObjectTarget.cpp | 35 ++--- lldb/source/Commands/CommandObjectType.cpp | 122 ++++++++-------- .../CommandObjectWatchpointCommand.cpp | 20 ++- lldb/source/Core/Debugger.cpp | 138 +++++++++--------- lldb/source/Core/DynamicLoader.cpp | 16 +- lldb/source/Core/IOHandler.cpp | 111 ++++++++------ lldb/source/Core/IOHandlerCursesGUI.cpp | 22 ++- lldb/source/Core/StreamAsynchronousIO.cpp | 12 +- lldb/source/Expression/REPL.cpp | 10 +- lldb/source/Host/common/Editline.cpp | 136 ++++++----------- .../source/Interpreter/CommandInterpreter.cpp | 30 ++-- lldb/source/Interpreter/ScriptInterpreter.cpp | 17 +-- .../DynamicLoaderDarwinKernel.cpp | 82 +++++------ .../DynamicLoaderFreeBSDKernel.cpp | 23 +-- .../TSan/InstrumentationRuntimeTSan.cpp | 11 +- .../UBSan/InstrumentationRuntimeUBSan.cpp | 2 + .../Utility/ReportRetriever.cpp | 4 +- .../AppleObjCTrampolineHandler.cpp | 4 +- .../Process/MacOSX-Kernel/ProcessKDP.cpp | 18 ++- .../Process/gdb-remote/ProcessGDBRemote.cpp | 3 +- .../Lua/ScriptInterpreterLua.cpp | 32 ++-- .../None/ScriptInterpreterNone.cpp | 4 +- .../Python/ScriptInterpreterPython.cpp | 39 +++-- lldb/source/Target/Process.cpp | 18 ++- lldb/source/Target/StopInfo.cpp | 8 +- lldb/source/Target/Target.cpp | 6 +- lldb/source/Target/ThreadPlanTracer.cpp | 39 +++-- lldb/test/API/terminal/TestEditline.py | 17 +-- lldb/unittests/Editline/EditlineTest.cpp | 13 +- lldb/unittests/Utility/AnsiTerminalTest.cpp | 15 -- 48 files changed, 599 insertions(+), 786 deletions(-) diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index c64fc9161e76e..899c0700e10fd 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -132,15 +132,20 @@ class Debugger : public std::enable_shared_from_this, void SetAsyncExecution(bool async); lldb::FileSP GetInputFileSP() { return m_input_file_sp; } + + lldb::StreamFileSP GetOutputStreamSP() { return m_output_stream_sp; } + + lldb::StreamFileSP GetErrorStreamSP() { return m_error_stream_sp; } + File &GetInputFile() { return *m_input_file_sp; } - lldb::FileSP GetOutputFileSP() { - return m_output_stream_sp->GetUnlockedFileSP(); - } + File &GetOutputFile() { return m_output_stream_sp->GetFile(); } - lldb::FileSP GetErrorFileSP() { - return m_error_stream_sp->GetUnlockedFileSP(); - } + File &GetErrorFile() { return m_error_stream_sp->GetFile(); } + + StreamFile &GetOutputStream() { return *m_output_stream_sp; } + + StreamFile &GetErrorStream() { return *m_error_stream_sp; } repro::DataRecorder *GetInputRecorder(); @@ -156,9 +161,9 @@ class Debugger : public std::enable_shared_from_this, void RestoreInputTerminalState(); - lldb::StreamUP GetAsyncOutputStream(); + lldb::StreamSP GetAsyncOutputStream(); - lldb::StreamUP GetAsyncErrorStream(); + lldb::StreamSP GetAsyncErrorStream(); CommandInterpreter &GetCommandInterpreter() { assert(m_command_interpreter_up.get()); @@ -201,8 +206,8 @@ class Debugger : public std::enable_shared_from_this, // If any of the streams are not set, set them to the in/out/err stream of // the top most input reader to ensure they at least have something void AdoptTopIOHandlerFilesIfInvalid(lldb::FileSP &in, - lldb::LockableStreamFileSP &out, - lldb::LockableStreamFileSP &err); + lldb::StreamFileSP &out, + lldb::StreamFileSP &err); /// Run the given IO handler and return immediately. void RunIOHandlerAsync(const lldb::IOHandlerSP &reader_sp, @@ -657,14 +662,6 @@ class Debugger : public std::enable_shared_from_this, void PrintProgress(const ProgressEventData &data); - /// Except for Debugger and IOHandler, GetOutputStreamSP and GetErrorStreamSP - /// should not be used directly. Use GetAsyncOutputStream and - /// GetAsyncErrorStream instead. - /// @{ - lldb::LockableStreamFileSP GetOutputStreamSP() { return m_output_stream_sp; } - lldb::LockableStreamFileSP GetErrorStreamSP() { return m_error_stream_sp; } - /// @} - void PushIOHandler(const lldb::IOHandlerSP &reader_sp, bool cancel_top_handler = true); @@ -705,9 +702,8 @@ class Debugger : public std::enable_shared_from_this, // these should never be NULL lldb::FileSP m_input_file_sp; - lldb::LockableStreamFileSP m_output_stream_sp; - lldb::LockableStreamFileSP m_error_stream_sp; - LockableStreamFile::Mutex m_output_mutex; + lldb::StreamFileSP m_output_stream_sp; + lldb::StreamFileSP m_error_stream_sp; /// Used for shadowing the input file when capturing a reproducer. repro::DataRecorder *m_input_recorder; diff --git a/lldb/include/lldb/Core/IOHandler.h b/lldb/include/lldb/Core/IOHandler.h index 127d73ae73d66..fef6c34903263 100644 --- a/lldb/include/lldb/Core/IOHandler.h +++ b/lldb/include/lldb/Core/IOHandler.h @@ -32,6 +32,11 @@ namespace lldb_private { class Debugger; } // namespace lldb_private +namespace curses { +class Application; +typedef std::unique_ptr ApplicationAP; +} // namespace curses + namespace lldb_private { class IOHandler { @@ -53,9 +58,8 @@ class IOHandler { IOHandler(Debugger &debugger, IOHandler::Type type); IOHandler(Debugger &debugger, IOHandler::Type type, - const lldb::FileSP &input_sp, - const lldb::LockableStreamFileSP &output_sp, - const lldb::LockableStreamFileSP &error_sp, uint32_t flags); + const lldb::FileSP &input_sp, const lldb::StreamFileSP &output_sp, + const lldb::StreamFileSP &error_sp, uint32_t flags); virtual ~IOHandler(); @@ -113,11 +117,17 @@ class IOHandler { int GetErrorFD(); + FILE *GetInputFILE(); + + FILE *GetOutputFILE(); + + FILE *GetErrorFILE(); + lldb::FileSP GetInputFileSP(); - lldb::LockableStreamFileSP GetOutputStreamFileSP(); + lldb::StreamFileSP GetOutputStreamFileSP(); - lldb::LockableStreamFileSP GetErrorStreamFileSP(); + lldb::StreamFileSP GetErrorStreamFileSP(); Debugger &GetDebugger() { return m_debugger; } @@ -150,11 +160,14 @@ class IOHandler { virtual void PrintAsync(const char *s, size_t len, bool is_stdout); + std::recursive_mutex &GetOutputMutex() { return m_output_mutex; } + protected: Debugger &m_debugger; lldb::FileSP m_input_sp; - lldb::LockableStreamFileSP m_output_sp; - lldb::LockableStreamFileSP m_error_sp; + lldb::StreamFileSP m_output_sp; + lldb::StreamFileSP m_error_sp; + std::recursive_mutex m_output_mutex; Predicate m_popped; Flags m_flags; Type m_type; @@ -322,8 +335,8 @@ class IOHandlerEditline : public IOHandler { IOHandlerEditline(Debugger &debugger, IOHandler::Type type, const lldb::FileSP &input_sp, - const lldb::LockableStreamFileSP &output_sp, - const lldb::LockableStreamFileSP &error_sp, uint32_t flags, + const lldb::StreamFileSP &output_sp, + const lldb::StreamFileSP &error_sp, uint32_t flags, const char *editline_name, // Used for saving history files llvm::StringRef prompt, llvm::StringRef continuation_prompt, bool multi_line, bool color, @@ -337,10 +350,9 @@ class IOHandlerEditline : public IOHandler { IOHandlerDelegate &) = delete; IOHandlerEditline(Debugger &, IOHandler::Type, const lldb::FileSP &, - const lldb::LockableStreamFileSP &, - const lldb::LockableStreamFileSP &, uint32_t, const char *, - const char *, const char *, bool, bool, uint32_t, - IOHandlerDelegate &) = delete; + const lldb::StreamFileSP &, const lldb::StreamFileSP &, + uint32_t, const char *, const char *, const char *, bool, + bool, uint32_t, IOHandlerDelegate &) = delete; ~IOHandlerEditline() override; diff --git a/lldb/include/lldb/Core/IOHandlerCursesGUI.h b/lldb/include/lldb/Core/IOHandlerCursesGUI.h index e9871e0532194..22ca735063ba1 100644 --- a/lldb/include/lldb/Core/IOHandlerCursesGUI.h +++ b/lldb/include/lldb/Core/IOHandlerCursesGUI.h @@ -12,9 +12,6 @@ #include "lldb/Core/IOHandler.h" namespace lldb_private { -namespace curses { -class Application; -} // namespace curses class IOHandlerCursesGUI : public IOHandler { public: @@ -37,7 +34,7 @@ class IOHandlerCursesGUI : public IOHandler { void TerminalSizeChanged() override; protected: - std::unique_ptr m_app_up; + curses::ApplicationAP m_app_ap; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Core/StreamAsynchronousIO.h b/lldb/include/lldb/Core/StreamAsynchronousIO.h index 7ae65757e2d73..b7adbc42096ce 100644 --- a/lldb/include/lldb/Core/StreamAsynchronousIO.h +++ b/lldb/include/lldb/Core/StreamAsynchronousIO.h @@ -18,17 +18,9 @@ namespace lldb_private { class Debugger; -/// A stream meant for asynchronously printing output. Output is buffered until -/// the stream is flushed or destroyed. Printing is handled by the currently -/// active IOHandler, or the debugger's output or error stream if there is none. class StreamAsynchronousIO : public Stream { public: - enum ForSTDOUT : bool { - STDOUT = true, - STDERR = false, - }; - - StreamAsynchronousIO(Debugger &debugger, ForSTDOUT for_stdout); + StreamAsynchronousIO(Debugger &debugger, bool for_stdout, bool colors); ~StreamAsynchronousIO() override; @@ -40,7 +32,7 @@ class StreamAsynchronousIO : public Stream { private: Debugger &m_debugger; std::string m_data; - ForSTDOUT m_for_stdout; + bool m_for_stdout; }; } // namespace lldb_private diff --git a/lldb/include/lldb/Host/Editline.h b/lldb/include/lldb/Host/Editline.h index 8964d37be8823..26deba38f8471 100644 --- a/lldb/include/lldb/Host/Editline.h +++ b/lldb/include/lldb/Host/Editline.h @@ -34,7 +34,6 @@ #include #include -#include "lldb/Host/StreamFile.h" #include "lldb/lldb-private.h" #if !defined(_WIN32) && !defined(__ANDROID__) @@ -152,9 +151,8 @@ using namespace line_editor; /// facility. Both single- and multi-line editing are supported. class Editline { public: - Editline(const char *editor_name, FILE *input_file, - lldb::LockableStreamFileSP output_stream_sp, - lldb::LockableStreamFileSP error_stream_sp, bool color); + Editline(const char *editor_name, FILE *input_file, FILE *output_file, + FILE *error_file, std::recursive_mutex &output_mutex); ~Editline(); @@ -214,23 +212,19 @@ class Editline { } void SetPromptAnsiPrefix(std::string prefix) { - if (m_color) - m_prompt_ansi_prefix = std::move(prefix); + m_prompt_ansi_prefix = std::move(prefix); } void SetPromptAnsiSuffix(std::string suffix) { - if (m_color) - m_prompt_ansi_suffix = std::move(suffix); + m_prompt_ansi_suffix = std::move(suffix); } void SetSuggestionAnsiPrefix(std::string prefix) { - if (m_color) - m_suggestion_ansi_prefix = std::move(prefix); + m_suggestion_ansi_prefix = std::move(prefix); } void SetSuggestionAnsiSuffix(std::string suffix) { - if (m_color) - m_suggestion_ansi_suffix = std::move(suffix); + m_suggestion_ansi_suffix = std::move(suffix); } /// Prompts for and reads a single line of user input. @@ -239,8 +233,7 @@ class Editline { /// Prompts for and reads a multi-line batch of user input. bool GetLines(int first_line_number, StringList &lines, bool &interrupted); - void PrintAsync(lldb::LockableStreamFileSP stream_sp, const char *s, - size_t len); + void PrintAsync(Stream *stream, const char *s, size_t len); /// Convert the current input lines into a UTF8 StringList StringList GetInputAsStringList(int line_count = UINT32_MAX); @@ -395,11 +388,8 @@ class Editline { volatile std::sig_atomic_t m_terminal_size_has_changed = 0; std::string m_editor_name; FILE *m_input_file; - lldb::LockableStreamFileSP m_output_stream_sp; - lldb::LockableStreamFileSP m_error_stream_sp; - - std::optional m_locked_output; - + FILE *m_output_file; + FILE *m_error_file; ConnectionFileDescriptor m_input_connection; IsInputCompleteCallbackType m_is_input_complete_callback; @@ -410,13 +400,13 @@ class Editline { CompleteCallbackType m_completion_callback; SuggestionCallbackType m_suggestion_callback; - bool m_color; std::string m_prompt_ansi_prefix; std::string m_prompt_ansi_suffix; std::string m_suggestion_ansi_prefix; std::string m_suggestion_ansi_suffix; std::size_t m_previous_autosuggestion_size = 0; + std::recursive_mutex &m_output_mutex; }; } diff --git a/lldb/include/lldb/Host/File.h b/lldb/include/lldb/Host/File.h index 9e2d0abe0b1af..5ce53c93b1b91 100644 --- a/lldb/include/lldb/Host/File.h +++ b/lldb/include/lldb/Host/File.h @@ -377,11 +377,6 @@ class File : public IOObject { class NativeFile : public File { public: - enum TransferOwnership : bool { - Owned = true, - Unowned = false, - }; - NativeFile() : m_descriptor(kInvalidDescriptor), m_stream(kInvalidStream) {} NativeFile(FILE *fh, bool transfer_ownership) diff --git a/lldb/include/lldb/Host/StreamFile.h b/lldb/include/lldb/Host/StreamFile.h index e37661a9938c0..2c96e13565a00 100644 --- a/lldb/include/lldb/Host/StreamFile.h +++ b/lldb/include/lldb/Host/StreamFile.h @@ -13,12 +13,9 @@ #include "lldb/Utility/Stream.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" -#include "lldb/lldb-forward.h" #include #include -#include -#include namespace lldb_private { @@ -55,55 +52,6 @@ class StreamFile : public Stream { const StreamFile &operator=(const StreamFile &) = delete; }; -class LockableStreamFile; -class LockedStreamFile : public StreamFile { -public: - ~LockedStreamFile() { Flush(); } - - LockedStreamFile(LockedStreamFile &&other) - : StreamFile(other.m_file_sp), m_lock(std::move(other.m_lock)) {} - -private: - LockedStreamFile(std::shared_ptr file, std::recursive_mutex &mutex) - : StreamFile(file), m_lock(mutex) {} - - friend class LockableStreamFile; - - std::unique_lock m_lock; -}; - -class LockableStreamFile { -public: - using Mutex = std::recursive_mutex; - - LockableStreamFile(std::shared_ptr stream_file_sp, Mutex &mutex) - : m_file_sp(stream_file_sp->GetFileSP()), m_mutex(mutex) {} - LockableStreamFile(StreamFile &stream_file, Mutex &mutex) - : m_file_sp(stream_file.GetFileSP()), m_mutex(mutex) {} - LockableStreamFile(FILE *fh, bool transfer_ownership, Mutex &mutex) - : m_file_sp(std::make_shared(fh, transfer_ownership)), - m_mutex(mutex) {} - LockableStreamFile(std::shared_ptr file_sp, Mutex &mutex) - : m_file_sp(file_sp), m_mutex(mutex) {} - - LockedStreamFile Lock() { return LockedStreamFile(m_file_sp, m_mutex); } - - /// Unsafe accessors to get the underlying File without a lock. Exists for - /// legacy reasons. - /// @{ - File &GetUnlockedFile() { return *m_file_sp; } - std::shared_ptr GetUnlockedFileSP() { return m_file_sp; } - /// @} - -protected: - std::shared_ptr m_file_sp; - Mutex &m_mutex; - -private: - LockableStreamFile(const LockableStreamFile &) = delete; - const LockableStreamFile &operator=(const LockableStreamFile &) = delete; -}; - } // namespace lldb_private #endif // LLDB_HOST_STREAMFILE_H diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index c6e01475621c0..7561585d9886a 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -115,12 +115,8 @@ class ScriptInterpreterIORedirect { ~ScriptInterpreterIORedirect(); lldb::FileSP GetInputFile() const { return m_input_file_sp; } - lldb::FileSP GetOutputFile() const { - return m_output_file_sp->GetUnlockedFileSP(); - } - lldb::FileSP GetErrorFile() const { - return m_error_file_sp->GetUnlockedFileSP(); - } + lldb::FileSP GetOutputFile() const { return m_output_file_sp->GetFileSP(); } + lldb::FileSP GetErrorFile() const { return m_error_file_sp->GetFileSP(); } /// Flush our output and error file handles. void Flush(); @@ -131,9 +127,8 @@ class ScriptInterpreterIORedirect { ScriptInterpreterIORedirect(Debugger &debugger, CommandReturnObject *result); lldb::FileSP m_input_file_sp; - lldb::LockableStreamFileSP m_output_file_sp; - lldb::LockableStreamFileSP m_error_file_sp; - LockableStreamFile::Mutex m_output_mutex; + lldb::StreamFileSP m_output_file_sp; + lldb::StreamFileSP m_error_file_sp; ThreadedCommunication m_communication; bool m_disconnect; }; @@ -500,7 +495,7 @@ class ScriptInterpreter : public PluginInterface { dest.clear(); return false; } - + virtual StructuredData::ObjectSP GetOptionsForCommandObject(StructuredData::GenericSP cmd_obj_sp) { return {}; @@ -510,9 +505,9 @@ class ScriptInterpreter : public PluginInterface { GetArgumentsForCommandObject(StructuredData::GenericSP cmd_obj_sp) { return {}; } - + virtual bool SetOptionValueForCommandObject( - StructuredData::GenericSP cmd_obj_sp, ExecutionContext *exe_ctx, + StructuredData::GenericSP cmd_obj_sp, ExecutionContext *exe_ctx, llvm::StringRef long_option, llvm::StringRef value) { return false; } diff --git a/lldb/include/lldb/Target/ThreadPlanTracer.h b/lldb/include/lldb/Target/ThreadPlanTracer.h index 7c45e213f94f1..a6fd2f031dc22 100644 --- a/lldb/include/lldb/Target/ThreadPlanTracer.h +++ b/lldb/include/lldb/Target/ThreadPlanTracer.h @@ -56,7 +56,7 @@ class ThreadPlanTracer { Process &m_process; lldb::tid_t m_tid; - lldb::StreamSP GetLogStreamSP(); + Stream *GetLogStream(); virtual void Log(); diff --git a/lldb/include/lldb/Utility/AnsiTerminal.h b/lldb/include/lldb/Utility/AnsiTerminal.h index 1939c49c7b859..67795971d2ca8 100644 --- a/lldb/include/lldb/Utility/AnsiTerminal.h +++ b/lldb/include/lldb/Utility/AnsiTerminal.h @@ -171,32 +171,7 @@ inline std::string FormatAnsiTerminalCodes(llvm::StringRef format, } return fmt; } - -inline std::string StripAnsiTerminalCodes(llvm::StringRef str) { - std::string stripped; - while (!str.empty()) { - llvm::StringRef left, right; - - std::tie(left, right) = str.split(ANSI_ESC_START); - stripped += left; - - // ANSI_ESC_START not found. - if (left == str && right.empty()) - break; - - size_t end = right.find_first_not_of("0123456789;"); - if (end < right.size() && (right[end] == 'm' || right[end] == 'G')) { - str = right.substr(end + 1); - } else { - // ANSI_ESC_END not found. - stripped += ANSI_ESC_START; - str = right; - } - } - return stripped; } - -} // namespace ansi } // namespace lldb_private #endif diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index a3550f3fe60ff..b37eea80aa60f 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -213,7 +213,6 @@ class StoppointCallbackContext; class Stream; class StreamFile; class StreamString; -class LockableStreamFile; class StringList; class StringTableReader; class StructuredDataImpl; @@ -428,9 +427,7 @@ typedef std::unique_ptr StackFrameRecognizerManagerUP; typedef std::shared_ptr StopInfoSP; typedef std::shared_ptr StreamSP; -typedef std::unique_ptr StreamUP; typedef std::shared_ptr StreamFileSP; -typedef std::shared_ptr LockableStreamFileSP; typedef std::shared_ptr StringTypeSummaryImplSP; typedef std::unique_ptr StructuredDataImplUP; diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index 8ca8b0f0bb361..cc9947cbd7256 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -507,31 +507,39 @@ SBFile SBDebugger::GetInputFile() { FILE *SBDebugger::GetOutputFileHandle() { LLDB_INSTRUMENT_VA(this); - if (m_opaque_sp) - return m_opaque_sp->GetOutputFileSP()->GetStream(); + if (m_opaque_sp) { + StreamFile &stream_file = m_opaque_sp->GetOutputStream(); + return stream_file.GetFile().GetStream(); + } return nullptr; } SBFile SBDebugger::GetOutputFile() { LLDB_INSTRUMENT_VA(this); - if (m_opaque_sp) - return SBFile(m_opaque_sp->GetOutputFileSP()); + if (m_opaque_sp) { + SBFile file(m_opaque_sp->GetOutputStream().GetFileSP()); + return file; + } return SBFile(); } FILE *SBDebugger::GetErrorFileHandle() { LLDB_INSTRUMENT_VA(this); - if (m_opaque_sp) - return m_opaque_sp->GetErrorFileSP()->GetStream(); + if (m_opaque_sp) { + StreamFile &stream_file = m_opaque_sp->GetErrorStream(); + return stream_file.GetFile().GetStream(); + } return nullptr; } SBFile SBDebugger::GetErrorFile() { LLDB_INSTRUMENT_VA(this); SBFile file; - if (m_opaque_sp) - return SBFile(m_opaque_sp->GetErrorFileSP()); + if (m_opaque_sp) { + SBFile file(m_opaque_sp->GetErrorStream().GetFileSP()); + return file; + } return SBFile(); } @@ -572,8 +580,8 @@ void SBDebugger::HandleCommand(const char *command) { sb_interpreter.HandleCommand(command, result, false); - result.PutError(m_opaque_sp->GetErrorFileSP()); - result.PutOutput(m_opaque_sp->GetOutputFileSP()); + result.PutError(m_opaque_sp->GetErrorStream().GetFileSP()); + result.PutOutput(m_opaque_sp->GetOutputStream().GetFileSP()); if (!m_opaque_sp->GetAsyncExecution()) { SBProcess process(GetCommandInterpreter().GetProcess()); diff --git a/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp index 242b5b30168c5..09abcf5e081d2 100644 --- a/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -620,8 +620,10 @@ bool BreakpointOptions::BreakpointOptionsCallbackFunction( // Rig up the results secondary output stream to the debugger's, so the // output will come out synchronously if the debugger is set up that way. - result.SetImmediateOutputStream(debugger.GetAsyncOutputStream()); - result.SetImmediateErrorStream(debugger.GetAsyncErrorStream()); + StreamSP output_stream(debugger.GetAsyncOutputStream()); + StreamSP error_stream(debugger.GetAsyncErrorStream()); + result.SetImmediateOutputStream(output_stream); + result.SetImmediateErrorStream(error_stream); CommandInterpreterRunOptions options; options.SetStopOnContinue(true); diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index 93303ac5e5db4..1f82ad8582685 100644 --- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -193,12 +193,10 @@ are no syntax errors may indicate that a function was declared but never called. Options *GetOptions() override { return &m_all_options; } void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - if (interactive) { - if (lldb::LockableStreamFileSP output_sp = - io_handler.GetOutputStreamFileSP()) { - LockedStreamFile locked_stream = output_sp->Lock(); - locked_stream.PutCString(g_reader_instructions); - } + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); + if (output_sp && interactive) { + output_sp->PutCString(g_reader_instructions); + output_sp->Flush(); } } diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp index 9510cf4d14467..f069b2feb5cb7 100644 --- a/lldb/source/Commands/CommandObjectCommands.cpp +++ b/lldb/source/Commands/CommandObjectCommands.cpp @@ -11,7 +11,6 @@ #include "CommandObjectRegexCommand.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/IOHandler.h" -#include "lldb/Host/StreamFile.h" #include "lldb/Interpreter/CommandHistory.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandOptionArgumentTable.h" @@ -793,15 +792,12 @@ a number follows 'f':" protected: void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - if (interactive) { - if (lldb::LockableStreamFileSP output_sp = - io_handler.GetOutputStreamFileSP()) { - LockedStreamFile locked_stream = output_sp->Lock(); - locked_stream.PutCString( - "Enter one or more sed substitution commands in " - "the form: 's///'.\nTerminate the " - "substitution list with an empty line.\n"); - } + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); + if (output_sp && interactive) { + output_sp->PutCString("Enter one or more sed substitution commands in " + "the form: 's///'.\nTerminate the " + "substitution list with an empty line.\n"); + output_sp->Flush(); } } @@ -815,9 +811,10 @@ a number follows 'f':" for (const std::string &line : lines) { Status error = AppendRegexSubstitution(line, check_only); if (error.Fail()) { - if (!GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) - GetDebugger().GetAsyncOutputStream()->Printf("error: %s\n", - error.AsCString()); + if (!GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) { + StreamSP out_stream = GetDebugger().GetAsyncOutputStream(); + out_stream->Printf("error: %s\n", error.AsCString()); + } } } } @@ -2380,18 +2377,16 @@ class CommandObjectCommandsScriptAdd : public CommandObjectParsed, }; void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - if (interactive) { - if (lldb::LockableStreamFileSP output_sp = - io_handler.GetOutputStreamFileSP()) { - LockedStreamFile locked_stream = output_sp->Lock(); - locked_stream.PutCString(g_python_command_instructions); - } + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); + if (output_sp && interactive) { + output_sp->PutCString(g_python_command_instructions); + output_sp->Flush(); } } void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override { - LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter(); if (interpreter) { @@ -2401,10 +2396,9 @@ class CommandObjectCommandsScriptAdd : public CommandObjectParsed, std::string funct_name_str; if (interpreter->GenerateScriptAliasFunction(lines, funct_name_str)) { if (funct_name_str.empty()) { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( - "error: unable to obtain a function name, didn't " - "add python command.\n"); + error_sp->Printf("error: unable to obtain a function name, didn't " + "add python command.\n"); + error_sp->Flush(); } else { // everything should be fine now, let's add this alias @@ -2415,36 +2409,33 @@ class CommandObjectCommandsScriptAdd : public CommandObjectParsed, Status error = m_interpreter.AddUserCommand( m_cmd_name, command_obj_sp, m_overwrite); if (error.Fail()) { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( - "error: unable to add selected command: '%s'", - error.AsCString()); + error_sp->Printf("error: unable to add selected command: '%s'", + error.AsCString()); + error_sp->Flush(); } } else { llvm::Error llvm_error = m_container->LoadUserSubcommand( m_cmd_name, command_obj_sp, m_overwrite); if (llvm_error) { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( - "error: unable to add selected command: '%s'", - llvm::toString(std::move(llvm_error)).c_str()); + error_sp->Printf("error: unable to add selected command: '%s'", + llvm::toString(std::move(llvm_error)).c_str()); + error_sp->Flush(); } } } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( + error_sp->Printf( "error: unable to create function, didn't add python command\n"); + error_sp->Flush(); } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( - "error: empty function, didn't add python command\n"); + error_sp->Printf("error: empty function, didn't add python command\n"); + error_sp->Flush(); } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( + error_sp->Printf( "error: script interpreter missing, didn't add python command\n"); + error_sp->Flush(); } io_handler.SetIsDone(true); diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index d2eaa4acbc568..69a4d6be382f5 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -12,7 +12,6 @@ #include "lldb/Expression/REPL.h" #include "lldb/Expression/UserExpression.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Host/StreamFile.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandOptionArgumentTable.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -23,7 +22,6 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/DiagnosticsRendering.h" #include "lldb/lldb-enumerations.h" -#include "lldb/lldb-forward.h" #include "lldb/lldb-private-enumerations.h" // BEGIN SWIFT @@ -528,17 +526,19 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, void CommandObjectExpression::IOHandlerInputComplete(IOHandler &io_handler, std::string &line) { io_handler.SetIsDone(true); - StreamSP output_stream = - GetCommandInterpreter().GetDebugger().GetAsyncOutputStream(); - StreamSP error_stream = - GetCommandInterpreter().GetDebugger().GetAsyncErrorStream(); + StreamFileSP output_sp = io_handler.GetOutputStreamFileSP(); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); CommandReturnObject return_obj( GetCommandInterpreter().GetDebugger().GetUseColor()); - EvaluateExpression(line.c_str(), *output_stream, *error_stream, return_obj); + EvaluateExpression(line.c_str(), *output_sp, *error_sp, return_obj); - output_stream->Flush(); - *error_stream << return_obj.GetErrorString(); + if (output_sp) + output_sp->Flush(); + if (error_sp) { + *error_sp << return_obj.GetErrorString(); + error_sp->Flush(); + } } bool CommandObjectExpression::IOHandlerIsInputComplete(IOHandler &io_handler, @@ -596,10 +596,11 @@ void CommandObjectExpression::GetMultilineExpression() { 1, // Show line numbers starting at 1 *this)); - if (LockableStreamFileSP output_sp = io_handler_sp->GetOutputStreamFileSP()) { - LockedStreamFile locked_stream = output_sp->Lock(); - locked_stream.PutCString( + StreamFileSP output_sp = io_handler_sp->GetOutputStreamFileSP(); + if (output_sp) { + output_sp->PutCString( "Enter expressions, then terminate with an empty line to evaluate:\n"); + output_sp->Flush(); } debugger.RunIOHandlerAsync(io_handler_sp); } diff --git a/lldb/source/Commands/CommandObjectGUI.cpp b/lldb/source/Commands/CommandObjectGUI.cpp index 8630171bae9d1..b56e49b073b03 100644 --- a/lldb/source/Commands/CommandObjectGUI.cpp +++ b/lldb/source/Commands/CommandObjectGUI.cpp @@ -28,10 +28,10 @@ void CommandObjectGUI::DoExecute(Args &args, CommandReturnObject &result) { #if LLDB_ENABLE_CURSES Debugger &debugger = GetDebugger(); - FileSP input_sp = debugger.GetInputFileSP(); - FileSP output_sp = debugger.GetOutputFileSP(); - if (input_sp->GetStream() && output_sp->GetStream() && - input_sp->GetIsRealTerminal() && input_sp->GetIsInteractive()) { + File &input = debugger.GetInputFile(); + File &output = debugger.GetOutputFile(); + if (input.GetStream() && output.GetStream() && input.GetIsRealTerminal() && + input.GetIsInteractive()) { IOHandlerSP io_handler_sp(new IOHandlerCursesGUI(debugger)); if (io_handler_sp) debugger.RunIOHandlerAsync(io_handler_sp); diff --git a/lldb/source/Commands/CommandObjectLog.cpp b/lldb/source/Commands/CommandObjectLog.cpp index 741b13fb56202..9eb68ddb73b6e 100644 --- a/lldb/source/Commands/CommandObjectLog.cpp +++ b/lldb/source/Commands/CommandObjectLog.cpp @@ -394,8 +394,7 @@ class CommandObjectLogDump : public CommandObjectParsed { (*file)->GetDescriptor(), /*shouldClose=*/true); } else { stream_up = std::make_unique( - GetDebugger().GetOutputFileSP()->GetDescriptor(), - /*shouldClose=*/false); + GetDebugger().GetOutputFile().GetDescriptor(), /*shouldClose=*/false); } const std::string channel = std::string(args[0].ref()); diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 38afadc87791d..c72419ffef3ff 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -57,7 +57,6 @@ #include "lldb/Utility/Timer.h" #include "lldb/ValueObject/ValueObjectVariable.h" #include "lldb/lldb-enumerations.h" -#include "lldb/lldb-forward.h" #include "lldb/lldb-private-enumerations.h" #include "clang/Frontend/CompilerInstance.h" @@ -4925,13 +4924,11 @@ Filter Options: protected: void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - if (interactive) { - if (lldb::LockableStreamFileSP output_sp = - io_handler.GetOutputStreamFileSP()) { - LockedStreamFile locked_stream = output_sp->Lock(); - locked_stream.PutCString( - "Enter your stop hook command(s). Type 'DONE' to end.\n"); - } + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); + if (output_sp && interactive) { + output_sp->PutCString( + "Enter your stop hook command(s). Type 'DONE' to end.\n"); + output_sp->Flush(); } } @@ -4939,12 +4936,12 @@ Filter Options: std::string &line) override { if (m_stop_hook_sp) { if (line.empty()) { - if (lldb::LockableStreamFileSP error_sp = - io_handler.GetErrorStreamFileSP()) { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("error: stop hook #%" PRIu64 - " aborted, no commands.\n", - m_stop_hook_sp->GetID()); + StreamFileSP error_sp(io_handler.GetErrorStreamFileSP()); + if (error_sp) { + error_sp->Printf("error: stop hook #%" PRIu64 + " aborted, no commands.\n", + m_stop_hook_sp->GetID()); + error_sp->Flush(); } Target *target = &GetTarget(); if (target) { @@ -4956,11 +4953,11 @@ Filter Options: static_cast(m_stop_hook_sp.get()); hook_ptr->SetActionFromString(line); - if (lldb::LockableStreamFileSP output_sp = - io_handler.GetOutputStreamFileSP()) { - LockedStreamFile locked_stream = output_sp->Lock(); - locked_stream.Printf("Stop hook #%" PRIu64 " added.\n", - m_stop_hook_sp->GetID()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); + if (output_sp) { + output_sp->Printf("Stop hook #%" PRIu64 " added.\n", + m_stop_hook_sp->GetID()); + output_sp->Flush(); } } m_stop_hook_sp.reset(); diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp index 923b3e7bc65b9..76e25f93c2c4c 100644 --- a/lldb/source/Commands/CommandObjectType.cpp +++ b/lldb/source/Commands/CommandObjectType.cpp @@ -14,7 +14,6 @@ #include "lldb/DataFormatters/FormatClasses.h" #include "lldb/Host/Config.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Host/StreamFile.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandOptionArgumentTable.h" @@ -33,7 +32,6 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/StringList.h" -#include "lldb/lldb-forward.h" #include "llvm/ADT/STLExtras.h" @@ -169,17 +167,16 @@ class CommandObjectTypeSummaryAdd : public CommandObjectParsed, "for\n" " internal_dict: an LLDB support object not to be used\"\"\"\n"; - if (interactive) { - if (LockableStreamFileSP output_sp = io_handler.GetOutputStreamFileSP()) { - LockedStreamFile locked_stream = output_sp->Lock(); - locked_stream.PutCString(g_summary_addreader_instructions); - } + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); + if (output_sp && interactive) { + output_sp->PutCString(g_summary_addreader_instructions); + output_sp->Flush(); } } void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override { - LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); #if LLDB_ENABLE_PYTHON ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter(); @@ -200,10 +197,9 @@ class CommandObjectTypeSummaryAdd : public CommandObjectParsed, if (interpreter->GenerateTypeScriptFunction(lines, funct_name_str)) { if (funct_name_str.empty()) { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( - "unable to obtain a valid function name from " - "the script interpreter.\n"); + error_sp->Printf("unable to obtain a valid function name from " + "the script interpreter.\n"); + error_sp->Flush(); } else { // now I have a valid function name, let's add this as script // for every type in the list @@ -220,8 +216,8 @@ class CommandObjectTypeSummaryAdd : public CommandObjectParsed, options->m_match_type, options->m_category, &error); if (error.Fail()) { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("error: %s", error.AsCString()); + error_sp->Printf("error: %s", error.AsCString()); + error_sp->Flush(); } } @@ -232,42 +228,41 @@ class CommandObjectTypeSummaryAdd : public CommandObjectParsed, CommandObjectTypeSummaryAdd::AddNamedSummary( options->m_name, script_format, &error); if (error.Fail()) { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("error: %s", error.AsCString()); + error_sp->Printf("error: %s", error.AsCString()); + error_sp->Flush(); } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("error: %s", error.AsCString()); + error_sp->Printf("error: %s", error.AsCString()); + error_sp->Flush(); } } else { if (error.AsCString()) { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("error: %s", error.AsCString()); + error_sp->Printf("error: %s", error.AsCString()); + error_sp->Flush(); } } } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("error: unable to generate a function.\n"); + error_sp->Printf("error: unable to generate a function.\n"); + error_sp->Flush(); } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("error: no script interpreter.\n"); + error_sp->Printf("error: no script interpreter.\n"); + error_sp->Flush(); } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("error: internal synchronization information " - "missing or invalid.\n"); + error_sp->Printf("error: internal synchronization information " + "missing or invalid.\n"); + error_sp->Flush(); } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( - "error: empty function, didn't add python command.\n"); + error_sp->Printf("error: empty function, didn't add python command.\n"); + error_sp->Flush(); } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( + error_sp->Printf( "error: script interpreter missing, didn't add python command.\n"); + error_sp->Flush(); } #endif io_handler.SetIsDone(true); @@ -409,17 +404,16 @@ class CommandObjectTypeSynthAdd : public CommandObjectParsed, } void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - if (interactive) { - if (LockableStreamFileSP output_sp = io_handler.GetOutputStreamFileSP()) { - LockedStreamFile locked_stream = output_sp->Lock(); - locked_stream.PutCString(g_synth_addreader_instructions); - } + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); + if (output_sp && interactive) { + output_sp->PutCString(g_synth_addreader_instructions); + output_sp->Flush(); } } void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override { - LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); #if LLDB_ENABLE_PYTHON ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter(); @@ -439,10 +433,9 @@ class CommandObjectTypeSynthAdd : public CommandObjectParsed, std::string class_name_str; if (interpreter->GenerateTypeSynthClass(lines, class_name_str)) { if (class_name_str.empty()) { - - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( + error_sp->Printf( "error: unable to obtain a proper name for the class.\n"); + error_sp->Flush(); } else { // everything should be fine now, let's add the synth provider // class @@ -466,39 +459,37 @@ class CommandObjectTypeSynthAdd : public CommandObjectParsed, if (AddSynth(ConstString(type_name), synth_provider, options->m_match_type, options->m_category, &error)) { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("error: %s\n", error.AsCString()); + error_sp->Printf("error: %s\n", error.AsCString()); + error_sp->Flush(); break; } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("error: invalid type name.\n"); + error_sp->Printf("error: invalid type name.\n"); + error_sp->Flush(); break; } } } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("error: unable to generate a class.\n"); + error_sp->Printf("error: unable to generate a class.\n"); + error_sp->Flush(); } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("error: no script interpreter.\n"); + error_sp->Printf("error: no script interpreter.\n"); + error_sp->Flush(); } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( - "error: internal synchronization data missing.\n"); + error_sp->Printf("error: internal synchronization data missing.\n"); + error_sp->Flush(); } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( - "error: empty function, didn't add python command.\n"); + error_sp->Printf("error: empty function, didn't add python command.\n"); + error_sp->Flush(); } } else { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf( + error_sp->Printf( "error: script interpreter missing, didn't add python command.\n"); + error_sp->Flush(); } #endif @@ -961,8 +952,8 @@ class CommandObjectTypeFormatterClear : public CommandObjectParsed { class CommandObjectTypeFormatDelete : public CommandObjectTypeFormatterDelete { public: CommandObjectTypeFormatDelete(CommandInterpreter &interpreter) - : CommandObjectTypeFormatterDelete(interpreter, - eFormatCategoryItemFormat) {} + : CommandObjectTypeFormatterDelete( + interpreter, eFormatCategoryItemFormat) {} ~CommandObjectTypeFormatDelete() override = default; }; @@ -1612,8 +1603,8 @@ bool CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name, class CommandObjectTypeSummaryDelete : public CommandObjectTypeFormatterDelete { public: CommandObjectTypeSummaryDelete(CommandInterpreter &interpreter) - : CommandObjectTypeFormatterDelete(interpreter, - eFormatCategoryItemSummary) {} + : CommandObjectTypeFormatterDelete( + interpreter, eFormatCategoryItemSummary) {} ~CommandObjectTypeSummaryDelete() override = default; @@ -2079,8 +2070,8 @@ class CommandObjectTypeSynthList class CommandObjectTypeFilterDelete : public CommandObjectTypeFormatterDelete { public: CommandObjectTypeFilterDelete(CommandInterpreter &interpreter) - : CommandObjectTypeFormatterDelete(interpreter, - eFormatCategoryItemFilter) {} + : CommandObjectTypeFormatterDelete( + interpreter, eFormatCategoryItemFilter) {} ~CommandObjectTypeFilterDelete() override = default; }; @@ -2090,12 +2081,13 @@ class CommandObjectTypeFilterDelete : public CommandObjectTypeFormatterDelete { class CommandObjectTypeSynthDelete : public CommandObjectTypeFormatterDelete { public: CommandObjectTypeSynthDelete(CommandInterpreter &interpreter) - : CommandObjectTypeFormatterDelete(interpreter, - eFormatCategoryItemSynth) {} + : CommandObjectTypeFormatterDelete( + interpreter, eFormatCategoryItemSynth) {} ~CommandObjectTypeSynthDelete() override = default; }; + // CommandObjectTypeFilterClear class CommandObjectTypeFilterClear : public CommandObjectTypeFormatterClear { diff --git a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp index e7dc77e313275..b4dd6daa5b63e 100644 --- a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp @@ -14,13 +14,11 @@ #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/IOHandler.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Host/StreamFile.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandOptionArgumentTable.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Target/Target.h" -#include "lldb/lldb-forward.h" using namespace lldb; using namespace lldb_private; @@ -172,13 +170,11 @@ are no syntax errors may indicate that a function was declared but never called. Options *GetOptions() override { return &m_options; } void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - if (interactive) { - if (lldb::LockableStreamFileSP output_sp = - io_handler.GetOutputStreamFileSP()) { - LockedStreamFile locked_stream = output_sp->Lock(); - locked_stream.PutCString( - "Enter your debugger command(s). Type 'DONE' to end.\n"); - } + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); + if (output_sp && interactive) { + output_sp->PutCString( + "Enter your debugger command(s). Type 'DONE' to end.\n"); + output_sp->Flush(); } } @@ -252,8 +248,10 @@ are no syntax errors may indicate that a function was declared but never called. // Rig up the results secondary output stream to the debugger's, so the // output will come out synchronously if the debugger is set up that // way. - result.SetImmediateOutputStream(debugger.GetAsyncOutputStream()); - result.SetImmediateErrorStream(debugger.GetAsyncErrorStream()); + StreamSP output_stream(debugger.GetAsyncOutputStream()); + StreamSP error_stream(debugger.GetAsyncErrorStream()); + result.SetImmediateOutputStream(output_stream); + result.SetImmediateErrorStream(error_stream); CommandInterpreterRunOptions options; options.SetStopOnContinue(true); diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index e4edd94ce9413..11db7363f8334 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -257,11 +257,12 @@ Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, std::list errors; StreamString feedback_stream; if (!target_sp->LoadScriptingResources(errors, feedback_stream)) { - lldb::StreamUP s = GetAsyncErrorStream(); - for (auto &error : errors) - s->Printf("%s\n", error.AsCString()); + Stream &s = GetErrorStream(); + for (auto &error : errors) { + s.Printf("%s\n", error.AsCString()); + } if (feedback_stream.GetSize()) - s->PutCString(feedback_stream.GetString()); + s.PutCString(feedback_stream.GetString()); } } } @@ -873,11 +874,9 @@ llvm::StringRef Debugger::GetStaticBroadcasterClass() { Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) : UserID(g_unique_id++), Properties(std::make_shared()), - m_input_file_sp(std::make_shared(stdin, NativeFile::Unowned)), - m_output_stream_sp(std::make_shared( - stdout, NativeFile::Unowned, m_output_mutex)), - m_error_stream_sp(std::make_shared( - stderr, NativeFile::Unowned, m_output_mutex)), + m_input_file_sp(std::make_shared(stdin, false)), + m_output_stream_sp(std::make_shared(stdout, false)), + m_error_stream_sp(std::make_shared(stderr, false)), m_input_recorder(nullptr), m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()), m_terminal_state(), m_target_list(*this), m_platform_list(), @@ -949,7 +948,7 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) if (term && !strcmp(term, "dumb")) SetUseColor(false); // Turn off use-color if we don't write to a terminal with color support. - if (!GetOutputFileSP()->GetIsTerminalWithColors()) + if (!GetOutputFile().GetIsTerminalWithColors()) SetUseColor(false); if (Diagnostics::Enabled()) { @@ -1085,14 +1084,12 @@ void Debugger::SetInputFile(FileSP file_sp) { void Debugger::SetOutputFile(FileSP file_sp) { assert(file_sp && file_sp->IsValid()); - m_output_stream_sp = - std::make_shared(file_sp, m_output_mutex); + m_output_stream_sp = std::make_shared(file_sp); } void Debugger::SetErrorFile(FileSP file_sp) { assert(file_sp && file_sp->IsValid()); - m_error_stream_sp = - std::make_shared(file_sp, m_output_mutex); + m_error_stream_sp = std::make_shared(file_sp); } void Debugger::SaveInputTerminalState() { @@ -1202,10 +1199,9 @@ bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type, void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) { bool printed = m_io_handler_stack.PrintAsync(s, len, is_stdout); if (!printed) { - LockableStreamFileSP stream_sp = + lldb::StreamFileSP stream = is_stdout ? m_output_stream_sp : m_error_stream_sp; - LockedStreamFile locked_stream = stream_sp->Lock(); - locked_stream.Write(s, len); + stream->Write(s, len); } } @@ -1230,9 +1226,8 @@ void Debugger::RunIOHandlerAsync(const IOHandlerSP &reader_sp, PushIOHandler(reader_sp, cancel_top_handler); } -void Debugger::AdoptTopIOHandlerFilesIfInvalid(FileSP &in, - LockableStreamFileSP &out, - LockableStreamFileSP &err) { +void Debugger::AdoptTopIOHandlerFilesIfInvalid(FileSP &in, StreamFileSP &out, + StreamFileSP &err) { // Before an IOHandler runs, it must have in/out/err streams. This function // is called when one ore more of the streams are nullptr. We use the top // input reader's in/out/err streams, or fall back to the debugger file @@ -1248,29 +1243,27 @@ void Debugger::AdoptTopIOHandlerFilesIfInvalid(FileSP &in, in = GetInputFileSP(); // If there is nothing, use stdin if (!in) - in = std::make_shared(stdin, NativeFile::Unowned); + in = std::make_shared(stdin, false); } // If no STDOUT has been set, then set it appropriately - if (!out || !out->GetUnlockedFile().IsValid()) { + if (!out || !out->GetFile().IsValid()) { if (top_reader_sp) out = top_reader_sp->GetOutputStreamFileSP(); else out = GetOutputStreamSP(); // If there is nothing, use stdout if (!out) - out = std::make_shared(stdout, NativeFile::Unowned, - m_output_mutex); + out = std::make_shared(stdout, false); } // If no STDERR has been set, then set it appropriately - if (!err || !err->GetUnlockedFile().IsValid()) { + if (!err || !err->GetFile().IsValid()) { if (top_reader_sp) err = top_reader_sp->GetErrorStreamFileSP(); else err = GetErrorStreamSP(); // If there is nothing, use stderr if (!err) - err = std::make_shared(stderr, NativeFile::Unowned, - m_output_mutex); + err = std::make_shared(stderr, false); } } @@ -1367,14 +1360,12 @@ bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) { return true; } -StreamUP Debugger::GetAsyncOutputStream() { - return std::make_unique(*this, - StreamAsynchronousIO::STDOUT); +StreamSP Debugger::GetAsyncOutputStream() { + return std::make_shared(*this, true, GetUseColor()); } -StreamUP Debugger::GetAsyncErrorStream() { - return std::make_unique(*this, - StreamAsynchronousIO::STDERR); +StreamSP Debugger::GetAsyncErrorStream() { + return std::make_shared(*this, false, GetUseColor()); } void Debugger::RequestInterrupt() { @@ -1616,7 +1607,8 @@ static void PrivateReportDiagnostic(Debugger &debugger, Severity severity, // diagnostic directly to the debugger's error stream. DiagnosticEventData event_data(severity, std::move(message), debugger_specific); - event_data.Dump(debugger.GetAsyncErrorStream().get()); + StreamSP stream = debugger.GetAsyncErrorStream(); + event_data.Dump(stream.get()); return; } EventSP event_sp = std::make_shared( @@ -1726,7 +1718,7 @@ bool Debugger::EnableLog(llvm::StringRef channel, LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; } else if (log_file.empty()) { log_handler_sp = - CreateLogHandler(log_handler_kind, GetOutputFileSP()->GetDescriptor(), + CreateLogHandler(log_handler_kind, GetOutputFile().GetDescriptor(), /*should_close=*/false, buffer_size); } else { auto pos = m_stream_handlers.find(log_file); @@ -1812,11 +1804,12 @@ void Debugger::HandleBreakpointEvent(const EventSP &event_sp) { if (num_new_locations > 0) { BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp); - if (StreamUP output_up = GetAsyncOutputStream()) { - output_up->Printf("%d location%s added to breakpoint %d\n", + StreamSP output_sp(GetAsyncOutputStream()); + if (output_sp) { + output_sp->Printf("%d location%s added to breakpoint %d\n", num_new_locations, num_new_locations == 1 ? "" : "s", breakpoint->GetID()); - output_up->Flush(); + output_sp->Flush(); } } } @@ -1860,8 +1853,8 @@ void Debugger::HandleProcessEvent(const EventSP &event_sp) { ? EventDataStructuredData::GetProcessFromEvent(event_sp.get()) : Process::ProcessEventData::GetProcessFromEvent(event_sp.get()); - StreamUP output_stream_up = GetAsyncOutputStream(); - StreamUP error_stream_up = GetAsyncErrorStream(); + StreamSP output_stream_sp = GetAsyncOutputStream(); + StreamSP error_stream_sp = GetAsyncErrorStream(); const bool gui_enabled = IsForwardingEvents(); if (!gui_enabled) { @@ -1889,7 +1882,7 @@ void Debugger::HandleProcessEvent(const EventSP &event_sp) { if (got_state_changed && !state_is_stopped) { // This is a public stop which we are going to announce to the user, so // we should force the most relevant frame selection here. - Process::HandleProcessStateChangedEvent(event_sp, output_stream_up.get(), + Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(), SelectMostRelevantFrame, pop_process_io_handler, // BEGIN SWIFT @@ -1909,29 +1902,31 @@ void Debugger::HandleProcessEvent(const EventSP &event_sp) { if (plugin_sp) { auto structured_data_sp = EventDataStructuredData::GetObjectFromEvent(event_sp.get()); - StreamString content_stream; - Status error = - plugin_sp->GetDescription(structured_data_sp, content_stream); - if (error.Success()) { - if (!content_stream.GetString().empty()) { - // Add newline. - content_stream.PutChar('\n'); - content_stream.Flush(); - - // Print it. - output_stream_up->PutCString(content_stream.GetString()); + if (output_stream_sp) { + StreamString content_stream; + Status error = + plugin_sp->GetDescription(structured_data_sp, content_stream); + if (error.Success()) { + if (!content_stream.GetString().empty()) { + // Add newline. + content_stream.PutChar('\n'); + content_stream.Flush(); + + // Print it. + output_stream_sp->PutCString(content_stream.GetString()); + } + } else { + error_stream_sp->Format("Failed to print structured " + "data with plugin {0}: {1}", + plugin_sp->GetPluginName(), error); } - } else { - error_stream_up->Format("Failed to print structured " - "data with plugin {0}: {1}", - plugin_sp->GetPluginName(), error); } } } // Now display any stopped state changes after any STDIO if (got_state_changed && state_is_stopped) { - Process::HandleProcessStateChangedEvent(event_sp, output_stream_up.get(), + Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(), SelectMostRelevantFrame, pop_process_io_handler, // BEGIN SWIFT @@ -1940,8 +1935,8 @@ void Debugger::HandleProcessEvent(const EventSP &event_sp) { ); } - output_stream_up->Flush(); - error_stream_up->Flush(); + output_stream_sp->Flush(); + error_stream_sp->Flush(); if (pop_process_io_handler) // BEGIN SWIFT @@ -2043,18 +2038,22 @@ lldb::thread_result_t Debugger::DefaultEventHandler() { const char *data = static_cast( EventDataBytes::GetBytesFromEvent(event_sp.get())); if (data && data[0]) { - StreamUP error_up = GetAsyncErrorStream(); - error_up->PutCString(data); - error_up->Flush(); + StreamSP error_sp(GetAsyncErrorStream()); + if (error_sp) { + error_sp->PutCString(data); + error_sp->Flush(); + } } } else if (event_type & CommandInterpreter:: eBroadcastBitAsynchronousOutputData) { const char *data = static_cast( EventDataBytes::GetBytesFromEvent(event_sp.get())); if (data && data[0]) { - StreamUP output_up = GetAsyncOutputStream(); - output_up->PutCString(data); - output_up->Flush(); + StreamSP output_sp(GetAsyncOutputStream()); + if (output_sp) { + output_sp->PutCString(data); + output_sp->Flush(); + } } } } else if (broadcaster == &m_broadcaster) { @@ -2165,11 +2164,11 @@ void Debugger::HandleProgressEvent(const lldb::EventSP &event_sp) { // Determine whether the current output file is an interactive terminal with // color support. We assume that if we support ANSI escape codes we support // vt100 escape codes. - FileSP file_sp = GetOutputFileSP(); - if (!file_sp->GetIsInteractive() || !file_sp->GetIsTerminalWithColors()) + File &file = GetOutputFile(); + if (!file.GetIsInteractive() || !file.GetIsTerminalWithColors()) return; - StreamUP output = GetAsyncOutputStream(); + StreamSP output = GetAsyncOutputStream(); // Print over previous line, if any. output->Printf("\r"); @@ -2219,7 +2218,8 @@ void Debugger::HandleDiagnosticEvent(const lldb::EventSP &event_sp) { if (!data) return; - data->Dump(GetAsyncErrorStream().get()); + StreamSP stream = GetAsyncErrorStream(); + data->Dump(stream.get()); } bool Debugger::HasIOHandlerThread() const { diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp index b9728625447a5..7758a87403b5a 100644 --- a/lldb/source/Core/DynamicLoader.cpp +++ b/lldb/source/Core/DynamicLoader.cpp @@ -255,7 +255,7 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress( module_sp = std::make_shared(module_spec); } else if (force_symbol_search && error.AsCString("") && error.AsCString("")[0] != '\0') { - *target.GetDebugger().GetAsyncErrorStream() << error.AsCString(); + target.GetDebugger().GetErrorStream() << error.AsCString(); } } @@ -320,19 +320,19 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress( } } else { if (force_symbol_search) { - lldb::StreamUP s = target.GetDebugger().GetAsyncErrorStream(); - s->Printf("Unable to find file"); + Stream &s = target.GetDebugger().GetErrorStream(); + s.Printf("Unable to find file"); if (!name.empty()) - s->Printf(" %s", name.str().c_str()); + s.Printf(" %s", name.str().c_str()); if (uuid.IsValid()) - s->Printf(" with UUID %s", uuid.GetAsString().c_str()); + s.Printf(" with UUID %s", uuid.GetAsString().c_str()); if (value != LLDB_INVALID_ADDRESS) { if (value_is_offset) - s->Printf(" with slide 0x%" PRIx64, value); + s.Printf(" with slide 0x%" PRIx64, value); else - s->Printf(" at address 0x%" PRIx64, value); + s.Printf(" at address 0x%" PRIx64, value); } - s->Printf("\n"); + s.Printf("\n"); } LLDB_LOGF(log, "Unable to find binary %s with UUID %s and load it at " diff --git a/lldb/source/Core/IOHandler.cpp b/lldb/source/Core/IOHandler.cpp index 1ee755b4ca793..bf8c3887ccbfb 100644 --- a/lldb/source/Core/IOHandler.cpp +++ b/lldb/source/Core/IOHandler.cpp @@ -54,17 +54,17 @@ using llvm::StringRef; IOHandler::IOHandler(Debugger &debugger, IOHandler::Type type) : IOHandler(debugger, type, - FileSP(), // Adopt STDIN from top input reader - LockableStreamFileSP(), // Adopt STDOUT from top input reader - LockableStreamFileSP(), // Adopt STDERR from top input reader - 0 // Flags + FileSP(), // Adopt STDIN from top input reader + StreamFileSP(), // Adopt STDOUT from top input reader + StreamFileSP(), // Adopt STDERR from top input reader + 0 // Flags ) {} IOHandler::IOHandler(Debugger &debugger, IOHandler::Type type, const lldb::FileSP &input_sp, - const lldb::LockableStreamFileSP &output_sp, - const lldb::LockableStreamFileSP &error_sp, uint32_t flags) + const lldb::StreamFileSP &output_sp, + const lldb::StreamFileSP &error_sp, uint32_t flags) : m_debugger(debugger), m_input_sp(input_sp), m_output_sp(output_sp), m_error_sp(error_sp), m_popped(false), m_flags(flags), m_type(type), m_user_data(nullptr), m_done(false), m_active(false) { @@ -81,18 +81,30 @@ int IOHandler::GetInputFD() { } int IOHandler::GetOutputFD() { - return (m_output_sp ? m_output_sp->GetUnlockedFile().GetDescriptor() : -1); + return (m_output_sp ? m_output_sp->GetFile().GetDescriptor() : -1); } int IOHandler::GetErrorFD() { - return (m_error_sp ? m_error_sp->GetUnlockedFile().GetDescriptor() : -1); + return (m_error_sp ? m_error_sp->GetFile().GetDescriptor() : -1); +} + +FILE *IOHandler::GetInputFILE() { + return (m_input_sp ? m_input_sp->GetStream() : nullptr); +} + +FILE *IOHandler::GetOutputFILE() { + return (m_output_sp ? m_output_sp->GetFile().GetStream() : nullptr); +} + +FILE *IOHandler::GetErrorFILE() { + return (m_error_sp ? m_error_sp->GetFile().GetStream() : nullptr); } FileSP IOHandler::GetInputFileSP() { return m_input_sp; } -LockableStreamFileSP IOHandler::GetOutputStreamFileSP() { return m_output_sp; } +StreamFileSP IOHandler::GetOutputStreamFileSP() { return m_output_sp; } -LockableStreamFileSP IOHandler::GetErrorStreamFileSP() { return m_error_sp; } +StreamFileSP IOHandler::GetErrorStreamFileSP() { return m_error_sp; } bool IOHandler::GetIsInteractive() { return GetInputFileSP() ? GetInputFileSP()->GetIsInteractive() : false; @@ -107,9 +119,10 @@ void IOHandler::SetPopped(bool b) { m_popped.SetValue(b, eBroadcastOnChange); } void IOHandler::WaitForPop() { m_popped.WaitForValueEqualTo(true); } void IOHandler::PrintAsync(const char *s, size_t len, bool is_stdout) { - lldb::LockableStreamFileSP stream_sp = is_stdout ? m_output_sp : m_error_sp; - LockedStreamFile locked_Stream = stream_sp->Lock(); - locked_Stream.Write(s, len); + std::lock_guard guard(m_output_mutex); + lldb::StreamFileSP stream = is_stdout ? m_output_sp : m_error_sp; + stream->Write(s, len); + stream->Flush(); } bool IOHandlerStack::PrintAsync(const char *s, size_t len, bool is_stdout) { @@ -215,20 +228,19 @@ IOHandlerEditline::IOHandlerEditline( llvm::StringRef prompt, llvm::StringRef continuation_prompt, bool multi_line, bool color, uint32_t line_number_start, IOHandlerDelegate &delegate) - : IOHandlerEditline( - debugger, type, - FileSP(), // Inherit input from top input reader - LockableStreamFileSP(), // Inherit output from top input reader - LockableStreamFileSP(), // Inherit error from top input reader - 0, // Flags - editline_name, // Used for saving history files - prompt, continuation_prompt, multi_line, color, line_number_start, - delegate) {} + : IOHandlerEditline(debugger, type, + FileSP(), // Inherit input from top input reader + StreamFileSP(), // Inherit output from top input reader + StreamFileSP(), // Inherit error from top input reader + 0, // Flags + editline_name, // Used for saving history files + prompt, continuation_prompt, multi_line, color, + line_number_start, delegate) {} IOHandlerEditline::IOHandlerEditline( Debugger &debugger, IOHandler::Type type, const lldb::FileSP &input_sp, - const lldb::LockableStreamFileSP &output_sp, - const lldb::LockableStreamFileSP &error_sp, uint32_t flags, + const lldb::StreamFileSP &output_sp, const lldb::StreamFileSP &error_sp, + uint32_t flags, const char *editline_name, // Used for saving history files llvm::StringRef prompt, llvm::StringRef continuation_prompt, bool multi_line, bool color, uint32_t line_number_start, @@ -244,12 +256,15 @@ IOHandlerEditline::IOHandlerEditline( SetPrompt(prompt); #if LLDB_ENABLE_LIBEDIT - const bool use_editline = m_input_sp && m_output_sp && m_error_sp && - m_input_sp->GetIsRealTerminal(); + bool use_editline = false; + + use_editline = GetInputFILE() && GetOutputFILE() && GetErrorFILE() && + m_input_sp && m_input_sp->GetIsRealTerminal(); + if (use_editline) { - m_editline_up = std::make_unique( - editline_name, m_input_sp ? m_input_sp->GetStream() : nullptr, - m_output_sp, m_error_sp, m_color); + m_editline_up = std::make_unique(editline_name, GetInputFILE(), + GetOutputFILE(), GetErrorFILE(), + GetOutputMutex()); m_editline_up->SetIsInputCompleteCallback( [this](Editline *editline, StringList &lines) { return this->IsInputCompleteCallback(editline, lines); @@ -263,10 +278,12 @@ IOHandlerEditline::IOHandlerEditline( m_editline_up->SetSuggestionCallback([this](llvm::StringRef line) { return this->SuggestionCallback(line); }); - m_editline_up->SetSuggestionAnsiPrefix(ansi::FormatAnsiTerminalCodes( - debugger.GetAutosuggestionAnsiPrefix())); - m_editline_up->SetSuggestionAnsiSuffix(ansi::FormatAnsiTerminalCodes( - debugger.GetAutosuggestionAnsiSuffix())); + if (m_color) { + m_editline_up->SetSuggestionAnsiPrefix(ansi::FormatAnsiTerminalCodes( + debugger.GetAutosuggestionAnsiPrefix())); + m_editline_up->SetSuggestionAnsiSuffix(ansi::FormatAnsiTerminalCodes( + debugger.GetAutosuggestionAnsiSuffix())); + } } // See if the delegate supports fixing indentation const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters(); @@ -351,8 +368,8 @@ bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) { if (prompt && prompt[0]) { if (m_output_sp) { - LockedStreamFile locked_stream = m_output_sp->Lock(); - locked_stream.Printf("%s", prompt); + m_output_sp->Printf("%s", prompt); + m_output_sp->Flush(); } } } @@ -365,7 +382,7 @@ bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) { return false; } - FILE *in = m_input_sp ? m_input_sp->GetStream() : nullptr; + FILE *in = GetInputFILE(); char buffer[256]; if (!got_line && !in && m_input_sp) { @@ -461,10 +478,12 @@ bool IOHandlerEditline::SetPrompt(llvm::StringRef prompt) { #if LLDB_ENABLE_LIBEDIT if (m_editline_up) { m_editline_up->SetPrompt(m_prompt.empty() ? nullptr : m_prompt.c_str()); - m_editline_up->SetPromptAnsiPrefix( - ansi::FormatAnsiTerminalCodes(m_debugger.GetPromptAnsiPrefix())); - m_editline_up->SetPromptAnsiSuffix( - ansi::FormatAnsiTerminalCodes(m_debugger.GetPromptAnsiSuffix())); + if (m_color) { + m_editline_up->SetPromptAnsiPrefix( + ansi::FormatAnsiTerminalCodes(m_debugger.GetPromptAnsiPrefix())); + m_editline_up->SetPromptAnsiSuffix( + ansi::FormatAnsiTerminalCodes(m_debugger.GetPromptAnsiSuffix())); + } } #endif return true; @@ -530,10 +549,9 @@ bool IOHandlerEditline::GetLines(StringList &lines, bool &interrupted) { std::string line; if (m_base_line_number > 0 && GetIsInteractive()) { if (m_output_sp) { - LockedStreamFile locked_stream = m_output_sp->Lock(); - locked_stream.Printf("%u%s", - m_base_line_number + (uint32_t)lines.GetSize(), - GetPrompt() == nullptr ? " " : ""); + m_output_sp->Printf("%u%s", + m_base_line_number + (uint32_t)lines.GetSize(), + GetPrompt() == nullptr ? " " : ""); } } @@ -619,8 +637,9 @@ void IOHandlerEditline::GotEOF() { void IOHandlerEditline::PrintAsync(const char *s, size_t len, bool is_stdout) { #if LLDB_ENABLE_LIBEDIT if (m_editline_up) { - lldb::LockableStreamFileSP stream_sp = is_stdout ? m_output_sp : m_error_sp; - m_editline_up->PrintAsync(stream_sp, s, len); + std::lock_guard guard(m_output_mutex); + lldb::StreamFileSP stream = is_stdout ? m_output_sp : m_error_sp; + m_editline_up->PrintAsync(stream.get(), s, len); } else #endif { diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp b/lldb/source/Core/IOHandlerCursesGUI.cpp index e63611c7b05c4..c3bbe91290c36 100644 --- a/lldb/source/Core/IOHandlerCursesGUI.cpp +++ b/lldb/source/Core/IOHandlerCursesGUI.cpp @@ -94,7 +94,6 @@ using llvm::StringRef; #define KEY_SHIFT_TAB (KEY_MAX + 1) #define KEY_ALT_ENTER (KEY_MAX + 2) -namespace lldb_private { namespace curses { class Menu; class MenuDelegate; @@ -4480,9 +4479,8 @@ class Application { }; } // namespace curses -} // namespace lldb_private -using namespace lldb_private::curses; +using namespace curses; struct Row { ValueObjectUpdater value; @@ -7573,14 +7571,12 @@ IOHandlerCursesGUI::IOHandlerCursesGUI(Debugger &debugger) void IOHandlerCursesGUI::Activate() { IOHandler::Activate(); - if (!m_app_up) { - m_app_up = std::make_unique( - m_input_sp ? m_input_sp->GetStream() : nullptr, - m_output_sp ? m_input_sp->GetStream() : nullptr); + if (!m_app_ap) { + m_app_ap = std::make_unique(GetInputFILE(), GetOutputFILE()); // This is both a window and a menu delegate std::shared_ptr app_delegate_sp( - new ApplicationDelegate(*m_app_up, m_debugger)); + new ApplicationDelegate(*m_app_ap, m_debugger)); MenuDelegateSP app_menu_delegate_sp = std::static_pointer_cast(app_delegate_sp); @@ -7654,8 +7650,8 @@ void IOHandlerCursesGUI::Activate() { help_menu_sp->AddSubmenu(MenuSP(new Menu( "GUI Help", nullptr, 'g', ApplicationDelegate::eMenuID_HelpGUIHelp))); - m_app_up->Initialize(); - WindowSP &main_window_sp = m_app_up->GetMainWindow(); + m_app_ap->Initialize(); + WindowSP &main_window_sp = m_app_ap->GetMainWindow(); MenuSP menubar_sp(new Menu(Menu::Type::Bar)); menubar_sp->AddSubmenu(lldb_menu_sp); @@ -7736,10 +7732,10 @@ void IOHandlerCursesGUI::Activate() { } } -void IOHandlerCursesGUI::Deactivate() { m_app_up->Terminate(); } +void IOHandlerCursesGUI::Deactivate() { m_app_ap->Terminate(); } void IOHandlerCursesGUI::Run() { - m_app_up->Run(m_debugger); + m_app_ap->Run(m_debugger); SetIsDone(true); } @@ -7754,7 +7750,7 @@ bool IOHandlerCursesGUI::Interrupt() { void IOHandlerCursesGUI::GotEOF() {} void IOHandlerCursesGUI::TerminalSizeChanged() { - m_app_up->TerminalSizeChanged(); + m_app_ap->TerminalSizeChanged(); } #endif // LLDB_ENABLE_CURSES diff --git a/lldb/source/Core/StreamAsynchronousIO.cpp b/lldb/source/Core/StreamAsynchronousIO.cpp index dbd56a69675b4..c2c64b61ab726 100644 --- a/lldb/source/Core/StreamAsynchronousIO.cpp +++ b/lldb/source/Core/StreamAsynchronousIO.cpp @@ -14,20 +14,20 @@ using namespace lldb; using namespace lldb_private; -StreamAsynchronousIO::StreamAsynchronousIO( - Debugger &debugger, StreamAsynchronousIO::ForSTDOUT for_stdout) - : Stream(0, 4, eByteOrderBig, debugger.GetUseColor()), m_debugger(debugger), - m_data(), m_for_stdout(for_stdout) {} +StreamAsynchronousIO::StreamAsynchronousIO(Debugger &debugger, bool for_stdout, + bool colors) + : Stream(0, 4, eByteOrderBig, colors), m_debugger(debugger), m_data(), + m_for_stdout(for_stdout) {} StreamAsynchronousIO::~StreamAsynchronousIO() { - // Flush when we destroy to make sure we display the data. + // Flush when we destroy to make sure we display the data Flush(); } void StreamAsynchronousIO::Flush() { if (!m_data.empty()) { m_debugger.PrintAsync(m_data.data(), m_data.size(), m_for_stdout); - m_data.clear(); + m_data = std::string(); } } diff --git a/lldb/source/Expression/REPL.cpp b/lldb/source/Expression/REPL.cpp index b43c7e0f8c46e..fed07ddf16102 100644 --- a/lldb/source/Expression/REPL.cpp +++ b/lldb/source/Expression/REPL.cpp @@ -103,8 +103,8 @@ void REPL::IOHandlerActivated(IOHandler &io_handler, bool interactive) { lldb::ProcessSP process_sp = m_target.GetProcessSP(); if (process_sp && process_sp->IsAlive()) return; - LockedStreamFile locked_stream = io_handler.GetErrorStreamFileSP()->Lock(); - locked_stream.Printf("REPL requires a running target process.\n"); + lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP()); + error_sp->Printf("REPL requires a running target process.\n"); io_handler.SetIsDone(true); } @@ -219,10 +219,8 @@ static bool ReadCode(const std::string &path, std::string &code, } void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { - lldb::StreamFileSP output_sp = std::make_shared( - io_handler.GetOutputStreamFileSP()->GetUnlockedFileSP()); - lldb::StreamFileSP error_sp = std::make_shared( - io_handler.GetErrorStreamFileSP()->GetUnlockedFileSP()); + lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); + lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP()); bool extra_line = false; bool did_quit = false; diff --git a/lldb/source/Host/common/Editline.cpp b/lldb/source/Host/common/Editline.cpp index 5f7a8b0190a1d..6e35b15d69651 100644 --- a/lldb/source/Host/common/Editline.cpp +++ b/lldb/source/Host/common/Editline.cpp @@ -14,8 +14,6 @@ #include "lldb/Host/Editline.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" -#include "lldb/Host/StreamFile.h" -#include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBAssert.h" @@ -24,7 +22,6 @@ #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringList.h" #include "lldb/Utility/Timeout.h" -#include "lldb/lldb-forward.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/FileSystem.h" @@ -79,19 +76,6 @@ using namespace lldb_private::line_editor; #endif // #if LLDB_EDITLINE_USE_WCHAR -template class ScopedOptional { -public: - template - ScopedOptional(std::optional &optional, Args &&...args) - : m_optional(optional) { - m_optional.emplace(std::forward(args)...); - } - ~ScopedOptional() { m_optional.reset(); } - -private: - std::optional &m_optional; -}; - bool IsOnlySpaces(const EditLineStringType &content) { for (wchar_t ch : content) { if (ch != EditLineCharType(' ')) @@ -101,8 +85,7 @@ bool IsOnlySpaces(const EditLineStringType &content) { } static size_t ColumnWidth(llvm::StringRef str) { - std::string stripped = ansi::StripAnsiTerminalCodes(str); - return llvm::sys::locale::columnWidth(stripped); + return llvm::sys::locale::columnWidth(str); } static int GetOperation(HistoryOperation op) { @@ -404,13 +387,11 @@ void Editline::MoveCursor(CursorLocation from, CursorLocation to) { (int)((info->cursor - info->buffer) + GetPromptWidth()); int editline_cursor_row = editline_cursor_position / m_terminal_width; - LockedStreamFile locked_stream = m_output_stream_sp->Lock(); - // Determine relative starting and ending lines int fromLine = GetLineIndexForLocation(from, editline_cursor_row); int toLine = GetLineIndexForLocation(to, editline_cursor_row); if (toLine != fromLine) { - fprintf(locked_stream.GetFile().GetStream(), + fprintf(m_output_file, (toLine > fromLine) ? ANSI_DOWN_N_ROWS : ANSI_UP_N_ROWS, std::abs(toLine - fromLine)); } @@ -426,23 +407,21 @@ void Editline::MoveCursor(CursorLocation from, CursorLocation to) { 80) + 1; } - fprintf(locked_stream.GetFile().GetStream(), ANSI_SET_COLUMN_N, toColumn); + fprintf(m_output_file, ANSI_SET_COLUMN_N, toColumn); } void Editline::DisplayInput(int firstIndex) { - LockedStreamFile locked_stream = m_output_stream_sp->Lock(); - fprintf(locked_stream.GetFile().GetStream(), - ANSI_SET_COLUMN_N ANSI_CLEAR_BELOW, 1); + fprintf(m_output_file, ANSI_SET_COLUMN_N ANSI_CLEAR_BELOW, 1); int line_count = (int)m_input_lines.size(); for (int index = firstIndex; index < line_count; index++) { - fprintf(locked_stream.GetFile().GetStream(), + fprintf(m_output_file, "%s" "%s" "%s" EditLineStringFormatSpec " ", m_prompt_ansi_prefix.c_str(), PromptForIndex(index).c_str(), m_prompt_ansi_suffix.c_str(), m_input_lines[index].c_str()); if (index < line_count - 1) - fprintf(locked_stream.GetFile().GetStream(), "\n"); + fprintf(m_output_file, "\n"); } } @@ -554,10 +533,8 @@ int Editline::GetCharacter(EditLineGetCharType *c) { // Paint a ANSI formatted version of the desired prompt over the version // libedit draws. (will only be requested if colors are supported) if (m_needs_prompt_repaint) { - ScopedOptional scope(m_locked_output, - m_output_stream_sp->Lock()); MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt); - fprintf(m_locked_output->GetFile().GetStream(), + fprintf(m_output_file, "%s" "%s" "%s", @@ -595,10 +572,10 @@ int Editline::GetCharacter(EditLineGetCharType *c) { // indefinitely. This gives a chance for someone to interrupt us. After // Read returns, immediately lock the mutex again and check if we were // interrupted. - m_locked_output.reset(); + m_output_mutex.unlock(); int read_count = m_input_connection.Read(&ch, 1, std::nullopt, status, nullptr); - m_locked_output.emplace(m_output_stream_sp->Lock()); + m_output_mutex.lock(); if (m_editor_status == EditorStatus::Interrupted) { while (read_count > 0 && status == lldb::eConnectionStatusSuccess) read_count = @@ -633,7 +610,7 @@ int Editline::GetCharacter(EditLineGetCharType *c) { } const char *Editline::Prompt() { - if (m_color) + if (!m_prompt_ansi_prefix.empty() || !m_prompt_ansi_suffix.empty()) m_needs_prompt_repaint = true; return m_current_prompt.c_str(); } @@ -721,14 +698,12 @@ unsigned char Editline::EndOrAddLineCommand(int ch) { } } MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockEnd); - LockedStreamFile locked_stream = m_output_stream_sp->Lock(); - fprintf(locked_stream.GetFile().GetStream(), "\n"); + fprintf(m_output_file, "\n"); m_editor_status = EditorStatus::Complete; return CC_NEWLINE; } unsigned char Editline::DeleteNextCharCommand(int ch) { - LockedStreamFile locked_stream = m_output_stream_sp->Lock(); LineInfoW *info = const_cast(el_wline(m_editline)); // Just delete the next character normally if possible @@ -742,7 +717,7 @@ unsigned char Editline::DeleteNextCharCommand(int ch) { // line is empty, in which case it is treated as EOF if (m_current_line_index == m_input_lines.size() - 1) { if (ch == 4 && info->buffer == info->lastchar) { - fprintf(locked_stream.GetFile().GetStream(), "^D\n"); + fprintf(m_output_file, "^D\n"); m_editor_status = EditorStatus::EndOfInput; return CC_EOF; } @@ -790,8 +765,7 @@ unsigned char Editline::DeletePreviousCharCommand(int ch) { priorLine + m_input_lines[m_current_line_index]; // Repaint from the new line down - LockedStreamFile locked_stream = m_output_stream_sp->Lock(); - fprintf(locked_stream.GetFile().GetStream(), ANSI_UP_N_ROWS ANSI_SET_COLUMN_N, + fprintf(m_output_file, ANSI_UP_N_ROWS ANSI_SET_COLUMN_N, CountRowsForLine(priorLine), 1); DisplayInput(m_current_line_index); @@ -809,19 +783,17 @@ unsigned char Editline::PreviousLineCommand(int ch) { return RecallHistory(HistoryOperation::Older); } - LockedStreamFile locked_stream = m_output_stream_sp->Lock(); - // Start from a known location MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt); // Treat moving up from a blank last line as a deletion of that line if (m_current_line_index == m_input_lines.size() - 1 && IsOnlySpaces()) { m_input_lines.erase(m_input_lines.begin() + m_current_line_index); - fprintf(locked_stream.GetFile().GetStream(), ANSI_CLEAR_BELOW); + fprintf(m_output_file, ANSI_CLEAR_BELOW); } SetCurrentLine(m_current_line_index - 1); - fprintf(locked_stream.GetFile().GetStream(), ANSI_UP_N_ROWS ANSI_SET_COLUMN_N, + fprintf(m_output_file, ANSI_UP_N_ROWS ANSI_SET_COLUMN_N, CountRowsForLine(m_input_lines[m_current_line_index]), 1); return CC_NEWLINE; } @@ -855,11 +827,9 @@ unsigned char Editline::NextLineCommand(int ch) { const LineInfoW *info = el_wline(m_editline); int cursor_position = (int)((info->cursor - info->buffer) + GetPromptWidth()); int cursor_row = cursor_position / m_terminal_width; - - LockedStreamFile locked_stream = m_output_stream_sp->Lock(); for (int line_count = 0; line_count < m_current_line_rows - cursor_row; line_count++) { - fprintf(locked_stream.GetFile().GetStream(), "\n"); + fprintf(m_output_file, "\n"); } return CC_NEWLINE; } @@ -1059,9 +1029,7 @@ void Editline::DisplayCompletions( Editline &editline, llvm::ArrayRef results) { assert(!results.empty()); - LockedStreamFile locked_stream = editline.m_output_stream_sp->Lock(); - - fprintf(locked_stream.GetFile().GetStream(), + fprintf(editline.m_output_file, "\n" ANSI_CLEAR_BELOW "Available completions:\n"); /// Account for the current line, the line showing "Available completions" @@ -1079,15 +1047,15 @@ void Editline::DisplayCompletions( size_t cur_pos = 0; while (cur_pos < results.size()) { - cur_pos += PrintCompletion( - locked_stream.GetFile().GetStream(), results.slice(cur_pos), max_len, - editline.GetTerminalWidth(), - all ? std::nullopt : std::optional(page_size)); + cur_pos += + PrintCompletion(editline.m_output_file, results.slice(cur_pos), max_len, + editline.GetTerminalWidth(), + all ? std::nullopt : std::optional(page_size)); if (cur_pos >= results.size()) break; - fprintf(locked_stream.GetFile().GetStream(), "More (Y/n/a): "); + fprintf(editline.m_output_file, "More (Y/n/a): "); // The type for the output and the type for the parameter are different, // to allow interoperability with older versions of libedit. The container // for the reply must be as wide as what our implementation is using, @@ -1099,11 +1067,11 @@ void Editline::DisplayCompletions( // Check for a ^C or other interruption. if (editline.m_editor_status == EditorStatus::Interrupted) { editline.m_editor_status = EditorStatus::Editing; - fprintf(locked_stream.GetFile().GetStream(), "^C\n"); + fprintf(editline.m_output_file, "^C\n"); break; } - fprintf(locked_stream.GetFile().GetStream(), "\n"); + fprintf(editline.m_output_file, "\n"); if (got_char == -1 || reply == 'n') break; if (reply == 'a') @@ -1212,18 +1180,17 @@ unsigned char Editline::TypedCharacter(int ch) { line_info->lastchar - line_info->buffer); if (std::optional to_add = m_suggestion_callback(line)) { - LockedStreamFile locked_stream = m_output_stream_sp->Lock(); std::string to_add_color = m_suggestion_ansi_prefix + to_add.value() + m_suggestion_ansi_suffix; - fputs(typed.c_str(), locked_stream.GetFile().GetStream()); - fputs(to_add_color.c_str(), locked_stream.GetFile().GetStream()); + fputs(typed.c_str(), m_output_file); + fputs(to_add_color.c_str(), m_output_file); size_t new_autosuggestion_size = line.size() + to_add->length(); // Print spaces to hide any remains of a previous longer autosuggestion. if (new_autosuggestion_size < m_previous_autosuggestion_size) { size_t spaces_to_print = m_previous_autosuggestion_size - new_autosuggestion_size; std::string spaces = std::string(spaces_to_print, ' '); - fputs(spaces.c_str(), locked_stream.GetFile().GetStream()); + fputs(spaces.c_str(), m_output_file); } m_previous_autosuggestion_size = new_autosuggestion_size; @@ -1232,7 +1199,7 @@ unsigned char Editline::TypedCharacter(int ch) { int editline_cursor_row = editline_cursor_position / m_terminal_width; int toColumn = editline_cursor_position - (editline_cursor_row * m_terminal_width); - fprintf(locked_stream.GetFile().GetStream(), ANSI_SET_COLUMN_N, toColumn); + fprintf(m_output_file, ANSI_SET_COLUMN_N, toColumn); return CC_REFRESH; } @@ -1267,17 +1234,13 @@ void Editline::ConfigureEditor(bool multiline) { el_end(m_editline); } - LockedStreamFile locked_output_stream = m_output_stream_sp->Lock(); - LockedStreamFile locked_error_stream = m_output_stream_sp->Lock(); - m_editline = el_init(m_editor_name.c_str(), m_input_file, - locked_output_stream.GetFile().GetStream(), - locked_error_stream.GetFile().GetStream()); + m_editline = + el_init(m_editor_name.c_str(), m_input_file, m_output_file, m_error_file); ApplyTerminalSizeChange(); if (m_history_sp && m_history_sp->IsValid()) { if (!m_history_sp->Load()) { - fputs("Could not load history file\n.", - locked_output_stream.GetFile().GetStream()); + fputs("Could not load history file\n.", m_output_file); } el_wset(m_editline, EL_HIST, history, m_history_sp->GetHistoryPtr()); } @@ -1508,12 +1471,12 @@ Editline *Editline::InstanceFor(EditLine *editline) { } Editline::Editline(const char *editline_name, FILE *input_file, - lldb::LockableStreamFileSP output_stream_sp, - lldb::LockableStreamFileSP error_stream_sp, bool color) + FILE *output_file, FILE *error_file, + std::recursive_mutex &output_mutex) : m_editor_status(EditorStatus::Complete), m_input_file(input_file), - m_output_stream_sp(output_stream_sp), m_error_stream_sp(error_stream_sp), - m_input_connection(fileno(input_file), false), m_color(color) { - assert(output_stream_sp && error_stream_sp); + m_output_file(output_file), m_error_file(error_file), + m_input_connection(fileno(input_file), false), + m_output_mutex(output_mutex) { // Get a shared history instance m_editor_name = (editline_name == nullptr) ? "lldb-tmp" : editline_name; m_history_sp = EditlineHistory::GetHistory(m_editor_name); @@ -1587,9 +1550,9 @@ uint32_t Editline::GetCurrentLine() { return m_current_line_index; } bool Editline::Interrupt() { bool result = true; - LockedStreamFile locked_stream = m_output_stream_sp->Lock(); + std::lock_guard guard(m_output_mutex); if (m_editor_status == EditorStatus::Editing) { - fprintf(locked_stream.GetFile().GetStream(), "^C\n"); + fprintf(m_output_file, "^C\n"); result = m_input_connection.InterruptRead(); } m_editor_status = EditorStatus::Interrupted; @@ -1598,10 +1561,10 @@ bool Editline::Interrupt() { bool Editline::Cancel() { bool result = true; - LockedStreamFile locked_stream = m_output_stream_sp->Lock(); + std::lock_guard guard(m_output_mutex); if (m_editor_status == EditorStatus::Editing) { MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart); - fprintf(locked_stream.GetFile().GetStream(), ANSI_CLEAR_BELOW); + fprintf(m_output_file, ANSI_CLEAR_BELOW); result = m_input_connection.InterruptRead(); } m_editor_status = EditorStatus::Interrupted; @@ -1613,8 +1576,7 @@ bool Editline::GetLine(std::string &line, bool &interrupted) { m_input_lines = std::vector(); m_input_lines.insert(m_input_lines.begin(), EditLineConstString("")); - ScopedOptional scope(m_locked_output, - m_output_stream_sp->Lock()); + std::lock_guard guard(m_output_mutex); lldbassert(m_editor_status != EditorStatus::Editing); if (m_editor_status == EditorStatus::Interrupted) { @@ -1634,7 +1596,7 @@ bool Editline::GetLine(std::string &line, bool &interrupted) { interrupted = m_editor_status == EditorStatus::Interrupted; if (!interrupted) { if (input == nullptr) { - fprintf(m_locked_output->GetFile().GetStream(), "\n"); + fprintf(m_output_file, "\n"); m_editor_status = EditorStatus::EndOfInput; } else { m_history_sp->Enter(input); @@ -1659,9 +1621,7 @@ bool Editline::GetLines(int first_line_number, StringList &lines, m_input_lines = std::vector(); m_input_lines.insert(m_input_lines.begin(), EditLineConstString("")); - ScopedOptional scope(m_locked_output, - m_output_stream_sp->Lock()); - + std::lock_guard guard(m_output_mutex); // Begin the line editing loop DisplayInput(); SetCurrentLine(0); @@ -1690,15 +1650,15 @@ bool Editline::GetLines(int first_line_number, StringList &lines, return m_editor_status != EditorStatus::EndOfInput; } -void Editline::PrintAsync(lldb::LockableStreamFileSP stream_sp, const char *s, - size_t len) { - LockedStreamFile locked_stream = m_output_stream_sp->Lock(); +void Editline::PrintAsync(Stream *stream, const char *s, size_t len) { + std::lock_guard guard(m_output_mutex); if (m_editor_status == EditorStatus::Editing) { SaveEditedLine(); MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart); - fprintf(locked_stream.GetFile().GetStream(), ANSI_CLEAR_BELOW); + fprintf(m_output_file, ANSI_CLEAR_BELOW); } - locked_stream.Write(s, len); + stream->Write(s, len); + stream->Flush(); if (m_editor_status == EditorStatus::Editing) { DisplayInput(); MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor); diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index aaeff9c97fd0a..d7fe97077cb34 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -58,7 +58,6 @@ #include "lldb/Utility/Timer.h" #include "lldb/Host/Config.h" -#include "lldb/lldb-forward.h" #if LLDB_ENABLE_LIBEDIT #include "lldb/Host/Editline.h" #endif @@ -2850,13 +2849,13 @@ void CommandInterpreter::HandleCommandsFromFile(FileSpec &cmd_file, } if (flags & eHandleCommandFlagPrintResult) { - debugger.GetOutputFileSP()->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 // have nested "command source" commands - lldb::LockableStreamFileSP empty_stream_sp; + lldb::StreamFileSP empty_stream_sp; m_command_source_flags.push_back(flags); IOHandlerSP io_handler_sp(new IOHandlerEditline( debugger, IOHandler::Type::CommandInterpreter, input_file_sp, @@ -3113,26 +3112,25 @@ void CommandInterpreter::PrintCommandOutput(IOHandler &io_handler, llvm::StringRef str, bool is_stdout) { - lldb::LockableStreamFileSP stream = is_stdout - ? io_handler.GetOutputStreamFileSP() - : io_handler.GetErrorStreamFileSP(); + lldb::StreamFileSP stream = is_stdout ? io_handler.GetOutputStreamFileSP() + : io_handler.GetErrorStreamFileSP(); // Split the output into lines and poll for interrupt requests bool had_output = !str.empty(); while (!str.empty()) { llvm::StringRef line; std::tie(line, str) = str.split('\n'); { - LockedStreamFile stream_file = stream->Lock(); - stream_file.Write(line.data(), line.size()); - stream_file.Write("\n", 1); + std::lock_guard guard(io_handler.GetOutputMutex()); + stream->Write(line.data(), line.size()); + stream->Write("\n", 1); } } - LockedStreamFile stream_file = stream->Lock(); + std::lock_guard guard(io_handler.GetOutputMutex()); if (had_output && INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping command output")) - stream_file.Printf("\n... Interrupted.\n"); - stream_file.Flush(); + stream->Printf("\n... Interrupted.\n"); + stream->Flush(); } bool CommandInterpreter::EchoCommandNonInteractive( @@ -3174,9 +3172,9 @@ 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())) { - LockedStreamFile locked_stream = - io_handler.GetOutputStreamFileSP()->Lock(); - locked_stream.Printf("%s%s\n", io_handler.GetPrompt(), line.c_str()); + std::lock_guard guard(io_handler.GetOutputMutex()); + io_handler.GetOutputStreamFileSP()->Printf( + "%s%s\n", io_handler.GetPrompt(), line.c_str()); } } diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp index 1c0c97d876a9f..8b55221da6e76 100644 --- a/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -200,8 +200,7 @@ ScriptInterpreterIORedirect::Create(bool enable_io, Debugger &debugger, ScriptInterpreterIORedirect::ScriptInterpreterIORedirect( std::unique_ptr input, std::unique_ptr output) : m_input_file_sp(std::move(input)), - m_output_file_sp(std::make_shared(std::move(output), - m_output_mutex)), + m_output_file_sp(std::make_shared(std::move(output))), m_error_file_sp(m_output_file_sp), m_communication("lldb.ScriptInterpreterIORedirect.comm"), m_disconnect(false) {} @@ -235,15 +234,13 @@ ScriptInterpreterIORedirect::ScriptInterpreterIORedirect( m_disconnect = true; FILE *outfile_handle = fdopen(pipe.ReleaseWriteFileDescriptor(), "w"); - m_output_file_sp = std::make_shared( - std::make_shared(outfile_handle, NativeFile::Owned), - m_output_mutex); + m_output_file_sp = std::make_shared(outfile_handle, true); m_error_file_sp = m_output_file_sp; if (outfile_handle) ::setbuf(outfile_handle, nullptr); - result->SetImmediateOutputFile(debugger.GetOutputFileSP()); - result->SetImmediateErrorFile(debugger.GetErrorFileSP()); + result->SetImmediateOutputFile(debugger.GetOutputStream().GetFileSP()); + result->SetImmediateErrorFile(debugger.GetErrorStream().GetFileSP()); } } @@ -254,9 +251,9 @@ ScriptInterpreterIORedirect::ScriptInterpreterIORedirect( void ScriptInterpreterIORedirect::Flush() { if (m_output_file_sp) - m_output_file_sp->Lock().Flush(); + m_output_file_sp->Flush(); if (m_error_file_sp) - m_error_file_sp->Lock().Flush(); + m_error_file_sp->Flush(); } ScriptInterpreterIORedirect::~ScriptInterpreterIORedirect() { @@ -270,7 +267,7 @@ ScriptInterpreterIORedirect::~ScriptInterpreterIORedirect() { // Close the write end of the pipe since we are done with our one line // script. This should cause the read thread that output_comm is using to // exit. - m_output_file_sp->GetUnlockedFile().Close(); + m_output_file_sp->GetFile().Close(); // The close above should cause this thread to exit when it gets to the end // of file, so let it get all its data. m_communication.JoinReadThread(); diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp index 97f69786e7a76..ab013e79047ea 100644 --- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp +++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp @@ -736,9 +736,9 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule( } if (IsKernel() && m_uuid.IsValid()) { - lldb::StreamUP s = target.GetDebugger().GetAsyncOutputStream(); - s->Printf("Kernel UUID: %s\n", m_uuid.GetAsString().c_str()); - s->Printf("Load Address: 0x%" PRIx64 "\n", m_load_address); + Stream &s = target.GetDebugger().GetOutputStream(); + s.Printf("Kernel UUID: %s\n", m_uuid.GetAsString().c_str()); + s.Printf("Load Address: 0x%" PRIx64 "\n", m_load_address); // Start of a kernel debug session, we have the UUID of the kernel. // Go through the target's list of modules and if there are any kernel @@ -828,12 +828,12 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule( } if (IsKernel() && !m_module_sp) { - lldb::StreamUP s = target.GetDebugger().GetAsyncErrorStream(); - s->Printf("WARNING: Unable to locate kernel binary on the debugger " - "system.\n"); + Stream &s = target.GetDebugger().GetErrorStream(); + s.Printf("WARNING: Unable to locate kernel binary on the debugger " + "system.\n"); if (kernel_search_error.Fail() && kernel_search_error.AsCString("") && kernel_search_error.AsCString("")[0] != '\0') { - *s << kernel_search_error.AsCString(); + s << kernel_search_error.AsCString(); } } } @@ -972,19 +972,22 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule( bool is_loaded = IsLoaded(); if (is_loaded && m_module_sp && IsKernel()) { - lldb::StreamUP s = target.GetDebugger().GetAsyncOutputStream(); + Stream &s = target.GetDebugger().GetOutputStream(); ObjectFile *kernel_object_file = m_module_sp->GetObjectFile(); if (kernel_object_file) { addr_t file_address = kernel_object_file->GetBaseAddress().GetFileAddress(); if (m_load_address != LLDB_INVALID_ADDRESS && file_address != LLDB_INVALID_ADDRESS) { - s->Printf("Kernel slid 0x%" PRIx64 " in memory.\n", - m_load_address - file_address); + s.Printf("Kernel slid 0x%" PRIx64 " in memory.\n", + m_load_address - file_address); } } - s->Printf("Loaded kernel file %s\n", - m_module_sp->GetFileSpec().GetPath().c_str()); + { + s.Printf("Loaded kernel file %s\n", + m_module_sp->GetFileSpec().GetPath().c_str()); + } + s.Flush(); } // Notify the target about the module being added; @@ -1190,11 +1193,10 @@ bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() { lldb::offset_t offset = 0; m_kext_summary_header.version = data.GetU32(&offset); if (m_kext_summary_header.version > 128) { - lldb::StreamSP s = - m_process->GetTarget().GetDebugger().GetAsyncOutputStream(); - s->Printf("WARNING: Unable to read kext summary header, got " - "improbable version number %u\n", - m_kext_summary_header.version); + Stream &s = m_process->GetTarget().GetDebugger().GetOutputStream(); + s.Printf("WARNING: Unable to read kext summary header, got " + "improbable version number %u\n", + m_kext_summary_header.version); // If we get an improbably large version number, we're probably // getting bad memory. m_kext_summary_header_addr.Clear(); @@ -1205,11 +1207,11 @@ bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() { if (m_kext_summary_header.entry_size > 4096) { // If we get an improbably large entry_size, we're probably // getting bad memory. - lldb::StreamSP s = - m_process->GetTarget().GetDebugger().GetAsyncOutputStream(); - s->Printf("WARNING: Unable to read kext summary header, got " - "improbable entry_size %u\n", - m_kext_summary_header.entry_size); + Stream &s = + m_process->GetTarget().GetDebugger().GetOutputStream(); + s.Printf("WARNING: Unable to read kext summary header, got " + "improbable entry_size %u\n", + m_kext_summary_header.entry_size); m_kext_summary_header_addr.Clear(); return false; } @@ -1223,11 +1225,10 @@ bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() { if (m_kext_summary_header.entry_count > 10000) { // If we get an improbably large number of kexts, we're probably // getting bad memory. - lldb::StreamSP s = - m_process->GetTarget().GetDebugger().GetAsyncOutputStream(); - s->Printf("WARNING: Unable to read kext summary header, got " - "improbable number of kexts %u\n", - m_kext_summary_header.entry_count); + Stream &s = m_process->GetTarget().GetDebugger().GetOutputStream(); + s.Printf("WARNING: Unable to read kext summary header, got " + "improbable number of kexts %u\n", + m_kext_summary_header.entry_count); m_kext_summary_header_addr.Clear(); return false; } @@ -1328,19 +1329,17 @@ bool DynamicLoaderDarwinKernel::ParseKextSummaries( number_of_old_kexts_being_removed == 0) return true; - lldb::StreamSP s = - m_process->GetTarget().GetDebugger().GetAsyncOutputStream(); + Stream &s = m_process->GetTarget().GetDebugger().GetOutputStream(); if (load_kexts) { if (number_of_new_kexts_being_added > 0 && number_of_old_kexts_being_removed > 0) { - s->Printf("Loading %d kext modules and unloading %d kext modules ", - number_of_new_kexts_being_added, - number_of_old_kexts_being_removed); + s.Printf("Loading %d kext modules and unloading %d kext modules ", + number_of_new_kexts_being_added, + number_of_old_kexts_being_removed); } else if (number_of_new_kexts_being_added > 0) { - s->Printf("Loading %d kext modules ", number_of_new_kexts_being_added); + s.Printf("Loading %d kext modules ", number_of_new_kexts_being_added); } else if (number_of_old_kexts_being_removed > 0) { - s->Printf("Unloading %d kext modules ", - number_of_old_kexts_being_removed); + s.Printf("Unloading %d kext modules ", number_of_old_kexts_being_removed); } } @@ -1404,7 +1403,7 @@ bool DynamicLoaderDarwinKernel::ParseKextSummaries( if (image_info.GetModule()) { unloaded_module_list.AppendIfNeeded(image_info.GetModule()); } - s->Printf("."); + s.Printf("."); image_info.Clear(); // should pull it out of the KextImageInfos vector but that would // mutate the list and invalidate the to_be_removed bool vector; @@ -1416,11 +1415,11 @@ bool DynamicLoaderDarwinKernel::ParseKextSummaries( } if (load_kexts) { - s->Printf(" done.\n"); + s.Printf(" done.\n"); if (kexts_failed_to_load.size() > 0 && number_of_new_kexts_being_added > 0) { - s->Printf("Failed to load %d of %d kexts:\n", - (int)kexts_failed_to_load.size(), - number_of_new_kexts_being_added); + s.Printf("Failed to load %d of %d kexts:\n", + (int)kexts_failed_to_load.size(), + number_of_new_kexts_being_added); // print a sorted list of kexts which failed to load unsigned longest_name = 0; std::sort(kexts_failed_to_load.begin(), kexts_failed_to_load.end()); @@ -1432,9 +1431,10 @@ bool DynamicLoaderDarwinKernel::ParseKextSummaries( std::string uuid; if (ku.second.IsValid()) uuid = ku.second.GetAsString(); - s->Printf(" %-*s %s\n", longest_name, ku.first.c_str(), uuid.c_str()); + s.Printf(" %-*s %s\n", longest_name, ku.first.c_str(), uuid.c_str()); } } + s.Flush(); } return true; diff --git a/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp b/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp index 40c871c3f393b..7c678faaae7fd 100644 --- a/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp +++ b/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp @@ -327,9 +327,9 @@ bool DynamicLoaderFreeBSDKernel::KModImageInfo::LoadImageUsingMemoryModule( Target &target = process->GetTarget(); if (IsKernel() && m_uuid.IsValid()) { - lldb::StreamUP s = target.GetDebugger().GetAsyncOutputStream(); - s->Printf("Kernel UUID: %s\n", m_uuid.GetAsString().c_str()); - s->Printf("Load Address: 0x%" PRIx64 "\n", m_load_address); + Stream &s = target.GetDebugger().GetOutputStream(); + s.Printf("Kernel UUID: %s\n", m_uuid.GetAsString().c_str()); + s.Printf("Load Address: 0x%" PRIx64 "\n", m_load_address); } // Test if the module is loaded into the taget, @@ -355,9 +355,9 @@ bool DynamicLoaderFreeBSDKernel::KModImageInfo::LoadImageUsingMemoryModule( if (!m_module_sp) m_module_sp = target.GetOrCreateModule(module_spec, true); if (IsKernel() && !m_module_sp) { - target.GetDebugger().GetAsyncOutputStream()->Printf( - "WARNING: Unable to locate kernel binary on the debugger " - "system.\n"); + Stream &s = target.GetDebugger().GetOutputStream(); + s.Printf("WARNING: Unable to locate kernel binary on the debugger " + "system.\n"); } } @@ -464,19 +464,20 @@ bool DynamicLoaderFreeBSDKernel::KModImageInfo::LoadImageUsingMemoryModule( } if (IsLoaded() && m_module_sp && IsKernel()) { - lldb::StreamUP s = target.GetDebugger().GetAsyncOutputStream(); + Stream &s = target.GetDebugger().GetOutputStream(); ObjectFile *kernel_object_file = m_module_sp->GetObjectFile(); if (kernel_object_file) { addr_t file_address = kernel_object_file->GetBaseAddress().GetFileAddress(); if (m_load_address != LLDB_INVALID_ADDRESS && file_address != LLDB_INVALID_ADDRESS) { - s->Printf("Kernel slide 0x%" PRIx64 " in memory.\n", - m_load_address - file_address); - s->Printf("Loaded kernel file %s\n", - m_module_sp->GetFileSpec().GetPath().c_str()); + s.Printf("Kernel slide 0x%" PRIx64 " in memory.\n", + m_load_address - file_address); + s.Printf("Loaded kernel file %s\n", + m_module_sp->GetFileSpec().GetPath().c_str()); } } + s.Flush(); } return IsLoaded(); diff --git a/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp b/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp index f034d6e2dd3ab..72ece72aa6f98 100644 --- a/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp +++ b/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp @@ -895,14 +895,13 @@ bool InstrumentationRuntimeTSan::NotifyBreakpointHit( CreateStopReasonWithInstrumentationData( *thread_sp, stop_reason_description, report)); - lldb::StreamSP s = - process_sp->GetTarget().GetDebugger().GetAsyncOutputStream(); - s->Printf("ThreadSanitizer report breakpoint hit. Use 'thread " - "info -s' to get extended information about the " - "report.\n"); + StreamFile &s = process_sp->GetTarget().GetDebugger().GetOutputStream(); + s.Printf("ThreadSanitizer report breakpoint hit. Use 'thread " + "info -s' to get extended information about the " + "report.\n"); return true; // Return true to stop the target - } + } else return false; // Let target run } diff --git a/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp b/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp index c2db3540a797b..8c2700cf21de9 100644 --- a/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp +++ b/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp @@ -116,6 +116,8 @@ StructuredData::ObjectSP InstrumentationRuntimeUBSan::RetrieveReportData( if (!frame_sp) return StructuredData::ObjectSP(); + StreamFileSP Stream = target.GetDebugger().GetOutputStreamSP(); + EvaluateExpressionOptions options; options.SetUnwindOnError(true); options.SetTryAllThreads(true); diff --git a/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp b/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp index 3cd4630728a6f..00761327a694b 100644 --- a/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp +++ b/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp @@ -217,8 +217,8 @@ bool ReportRetriever::NotifyBreakpointHit(ProcessSP process_sp, InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData( *thread_sp, description, report)); - if (StreamSP stream_sp = - process_sp->GetTarget().GetDebugger().GetAsyncOutputStream()) + if (StreamFileSP stream_sp = StreamFileSP( + process_sp->GetTarget().GetDebugger().GetOutputStreamSP())) stream_sp->Printf("AddressSanitizer report breakpoint hit. Use 'thread " "info -s' to get extended information about the " "report.\n"); diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp index 7774eb843c62d..2b8adeae10d14 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp @@ -622,14 +622,14 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler( // step through any method dispatches. Warn to that effect and get out of // here. if (process_sp->CanJIT()) { - process_sp->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf( + process_sp->GetTarget().GetDebugger().GetErrorStream().Printf( "Could not find implementation lookup function \"%s\"" " step in through ObjC method dispatch will not work.\n", get_impl_name.AsCString()); } return; } - + // We will either set the implementation to the _stret or non_stret version, // so either way it's safe to start filling the m_lookup_..._code here. m_lookup_implementation_function_code.assign( diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp index 406e1d45dc39a..9b2907c680996 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -321,10 +321,20 @@ Status ProcessKDP::DoConnectRemote(llvm::StringRef remote_url) { SetID(1); GetThreadList(); SetPrivateState(eStateStopped); - const char *cstr; - if ((cstr = m_comm.GetKernelVersion()) != NULL) - target.GetDebugger().GetAsyncOutputStream()->Printf("Version: %s\n", - cstr); + StreamSP async_strm_sp(target.GetDebugger().GetAsyncOutputStream()); + if (async_strm_sp) { + const char *cstr; + if ((cstr = m_comm.GetKernelVersion()) != NULL) { + async_strm_sp->Printf("Version: %s\n", cstr); + async_strm_sp->Flush(); + } + // if ((cstr = m_comm.GetImagePath ()) != NULL) + // { + // async_strm_sp->Printf ("Image Path: + // %s\n", cstr); + // async_strm_sp->Flush(); + // } + } } else { return Status::FromErrorString("KDP_REATTACH failed"); } diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index ba0384be51c70..49a3935d47f18 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -5468,7 +5468,8 @@ class CommandObjectProcessGDBRemoteSpeedTest : public CommandObjectParsed { if (process) { StreamSP output_stream_sp = result.GetImmediateOutputStream(); if (!output_stream_sp) - output_stream_sp = m_interpreter.GetDebugger().GetAsyncOutputStream(); + output_stream_sp = + StreamSP(m_interpreter.GetDebugger().GetAsyncOutputStream()); result.SetImmediateOutputStream(output_stream_sp); const uint32_t num_packets = diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp index d4df74ad98b6a..ea74a500518e3 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp @@ -17,7 +17,6 @@ #include "lldb/Utility/Stream.h" #include "lldb/Utility/StringList.h" #include "lldb/Utility/Timer.h" -#include "lldb/lldb-forward.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/FormatAdapters.h" #include @@ -46,8 +45,8 @@ class IOHandlerLuaInterpreter : public IOHandlerDelegate, m_script_interpreter(script_interpreter), m_active_io_handler(active_io_handler) { llvm::cantFail(m_script_interpreter.GetLua().ChangeIO( - debugger.GetOutputFileSP()->GetStream(), - debugger.GetErrorFileSP()->GetStream())); + debugger.GetOutputFile().GetStream(), + debugger.GetErrorFile().GetStream())); llvm::cantFail(m_script_interpreter.EnterSession(debugger.GetID())); } @@ -77,13 +76,8 @@ class IOHandlerLuaInterpreter : public IOHandlerDelegate, } if (instructions == nullptr) return; - if (interactive) { - if (lldb::LockableStreamFileSP output_sp = - io_handler.GetOutputStreamFileSP()) { - LockedStreamFile locked_stream = output_sp->Lock(); - locked_stream << instructions; - } - } + if (interactive) + *io_handler.GetOutputStreamFileSP() << instructions; } bool IOHandlerIsInputComplete(IOHandler &io_handler, @@ -118,11 +112,8 @@ class IOHandlerLuaInterpreter : public IOHandlerDelegate, for (BreakpointOptions &bp_options : *bp_options_vec) { Status error = m_script_interpreter.SetBreakpointCommandCallback( bp_options, data.c_str(), /*is_callback=*/false); - if (error.Fail()) { - LockedStreamFile locked_stream = - io_handler.GetErrorStreamFileSP()->Lock(); - locked_stream << error.AsCString() << '\n'; - } + if (error.Fail()) + *io_handler.GetErrorStreamFileSP() << error.AsCString() << '\n'; } io_handler.SetIsDone(true); } break; @@ -139,11 +130,8 @@ class IOHandlerLuaInterpreter : public IOHandlerDelegate, io_handler.SetIsDone(true); return; } - if (llvm::Error error = m_script_interpreter.GetLua().Run(data)) { - LockedStreamFile locked_stream = - io_handler.GetErrorStreamFileSP()->Lock(); - locked_stream << toString(std::move(error)); - } + if (llvm::Error error = m_script_interpreter.GetLua().Run(data)) + *io_handler.GetErrorStreamFileSP() << toString(std::move(error)); break; } } @@ -301,7 +289,7 @@ bool ScriptInterpreterLua::BreakpointCallbackFunction( llvm::Expected BoolOrErr = lua.CallBreakpointCallback( baton, stop_frame_sp, bp_loc_sp, bp_option_data->m_extra_args_sp); if (llvm::Error E = BoolOrErr.takeError()) { - *debugger.GetAsyncErrorStream() << toString(std::move(E)); + debugger.GetErrorStream() << toString(std::move(E)); return true; } @@ -328,7 +316,7 @@ bool ScriptInterpreterLua::WatchpointCallbackFunction( llvm::Expected BoolOrErr = lua.CallWatchpointCallback(baton, stop_frame_sp, wp_sp); if (llvm::Error E = BoolOrErr.takeError()) { - *debugger.GetAsyncErrorStream() << toString(std::move(E)); + debugger.GetErrorStream() << toString(std::move(E)); return true; } diff --git a/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp index d0c3df05e6320..7aeee6e403954 100644 --- a/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp @@ -33,12 +33,12 @@ static const char *no_interpreter_err_msg = bool ScriptInterpreterNone::ExecuteOneLine(llvm::StringRef command, CommandReturnObject *, const ExecuteScriptOptions &) { - m_debugger.GetAsyncErrorStream()->PutCString(no_interpreter_err_msg); + m_debugger.GetErrorStream().PutCString(no_interpreter_err_msg); return false; } void ScriptInterpreterNone::ExecuteInterpreterLoop() { - m_debugger.GetAsyncErrorStream()->PutCString(no_interpreter_err_msg); + m_debugger.GetErrorStream().PutCString(no_interpreter_err_msg); } void ScriptInterpreterNone::Initialize() { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index d6e8f4df68327..88c90262c9b86 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -7,10 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/Config.h" -#include "lldb/Host/StreamFile.h" #include "lldb/lldb-enumerations.h" -#include "lldb/lldb-forward.h" -#include #if LLDB_ENABLE_PYTHON @@ -508,11 +505,11 @@ def function (frame, bp_loc, internal_dict): break; } - if (instructions && interactive) { - if (LockableStreamFileSP stream_sp = io_handler.GetOutputStreamFileSP()) { - LockedStreamFile locked_stream = stream_sp->Lock(); - locked_stream.PutCString(instructions); - locked_stream.Flush(); + if (instructions) { + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); + if (output_sp && interactive) { + output_sp->PutCString(instructions); + output_sp->Flush(); } } } @@ -546,9 +543,10 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler, bp_options.SetCallback( ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp); } else if (!batch_mode) { - if (LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP()) { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("Warning: No command attached to breakpoint.\n"); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); + if (error_sp) { + error_sp->Printf("Warning: No command attached to breakpoint.\n"); + error_sp->Flush(); } } } @@ -568,9 +566,10 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler, wp_options->SetCallback( ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp); } else if (!batch_mode) { - if (LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP()) { - LockedStreamFile locked_stream = error_sp->Lock(); - locked_stream.Printf("Warning: No command attached to breakpoint.\n"); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); + if (error_sp) { + error_sp->Printf("Warning: No command attached to breakpoint.\n"); + error_sp->Flush(); } } m_active_io_handler = eIOHandlerNone; @@ -697,7 +696,7 @@ bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags, PythonDictionary &sys_module_dict = GetSysModuleDictionary(); if (sys_module_dict.IsValid()) { lldb::FileSP top_in_sp; - lldb::LockableStreamFileSP top_out_sp, top_err_sp; + lldb::StreamFileSP top_out_sp, top_err_sp; if (!in_sp || !out_sp || !err_sp || !*in_sp || !*out_sp || !*err_sp) m_debugger.AdoptTopIOHandlerFilesIfInvalid(top_in_sp, top_out_sp, top_err_sp); @@ -713,14 +712,12 @@ bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags, if (!SetStdHandle(out_sp, "stdout", m_saved_stdout, "w")) { if (top_out_sp) - SetStdHandle(top_out_sp->GetUnlockedFileSP(), "stdout", m_saved_stdout, - "w"); + SetStdHandle(top_out_sp->GetFileSP(), "stdout", m_saved_stdout, "w"); } if (!SetStdHandle(err_sp, "stderr", m_saved_stderr, "w")) { if (top_err_sp) - SetStdHandle(top_err_sp->GetUnlockedFileSP(), "stderr", m_saved_stderr, - "w"); + SetStdHandle(top_err_sp->GetFileSP(), "stderr", m_saved_stderr, "w"); } } @@ -1979,10 +1976,10 @@ bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction( llvm::handleAllErrors( maybe_ret_val.takeError(), [&](PythonException &E) { - *debugger.GetAsyncErrorStream() << E.ReadBacktrace(); + debugger.GetErrorStream() << E.ReadBacktrace(); }, [&](const llvm::ErrorInfoBase &E) { - *debugger.GetAsyncErrorStream() << E.message(); + debugger.GetErrorStream() << E.message(); }); } else { diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 2942d2babd2fe..1633d873b10b5 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -1810,7 +1810,7 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &constituent, Address symbol_address = symbol->GetAddress(); load_addr = ResolveIndirectFunction(&symbol_address, error); if (!error.Success() && show_error) { - GetTarget().GetDebugger().GetAsyncErrorStream()->Printf( + GetTarget().GetDebugger().GetErrorStream().Printf( "warning: failed to resolve indirect function at 0x%" PRIx64 " for breakpoint %i.%i: %s\n", symbol->GetLoadAddress(&GetTarget()), @@ -1849,7 +1849,7 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &constituent, } else { if (show_error || use_hardware) { // Report error for setting breakpoint... - GetTarget().GetDebugger().GetAsyncErrorStream()->Printf( + GetTarget().GetDebugger().GetErrorStream().Printf( "warning: failed to set breakpoint site at 0x%" PRIx64 " for breakpoint %i.%i: %s\n", load_addr, constituent->GetBreakpoint().GetID(), @@ -2888,9 +2888,10 @@ Status Process::LaunchPrivate(ProcessLaunchInfo &launch_info, StateType &state, // Now that we know the process type, update its signal responses from the // ones stored in the Target: - if (m_unix_signals_sp) - GetTarget().UpdateSignalsFromDummy( - m_unix_signals_sp, GetTarget().GetDebugger().GetAsyncErrorStream()); + if (m_unix_signals_sp) { + StreamSP warning_strm = GetTarget().GetDebugger().GetAsyncErrorStream(); + GetTarget().UpdateSignalsFromDummy(m_unix_signals_sp, warning_strm); + } DynamicLoader *dyld = GetDynamicLoader(); if (dyld) @@ -3275,9 +3276,10 @@ void Process::CompleteAttach() { } // Now that we know the process type, update its signal responses from the // ones stored in the Target: - if (m_unix_signals_sp) - GetTarget().UpdateSignalsFromDummy( - m_unix_signals_sp, GetTarget().GetDebugger().GetAsyncErrorStream()); + if (m_unix_signals_sp) { + StreamSP warning_strm = GetTarget().GetDebugger().GetAsyncErrorStream(); + GetTarget().UpdateSignalsFromDummy(m_unix_signals_sp, warning_strm); + } // We have completed the attach, now it is time to find the dynamic loader // plug-in diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp index bd086550f4d82..d12d1c8bced3e 100644 --- a/lldb/source/Target/StopInfo.cpp +++ b/lldb/source/Target/StopInfo.cpp @@ -1016,9 +1016,11 @@ class StopInfoWatchpoint : public StopInfo { wp_sp->CaptureWatchedValue(exe_ctx); Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger(); - StreamUP output_up = debugger.GetAsyncOutputStream(); - if (wp_sp->DumpSnapshots(output_up.get())) - output_up->EOL(); + StreamSP output_sp = debugger.GetAsyncOutputStream(); + if (wp_sp->DumpSnapshots(output_sp.get())) { + output_sp->EOL(); + output_sp->Flush(); + } } } else { diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 6d4a2ec68ba11..a596e1176ce7f 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1475,15 +1475,15 @@ static void LoadScriptingResourceForModule(const ModuleSP &module_sp, if (module_sp && !module_sp->LoadScriptingResourceInTarget(target, error, feedback_stream)) { if (error.AsCString()) - target->GetDebugger().GetAsyncErrorStream()->Printf( + target->GetDebugger().GetErrorStream().Printf( "unable to load scripting data for module %s - error reported was " "%s\n", module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(), error.AsCString()); } if (feedback_stream.GetSize()) - target->GetDebugger().GetAsyncErrorStream()->Printf( - "%s\n", feedback_stream.GetData()); + target->GetDebugger().GetErrorStream().Printf("%s\n", + feedback_stream.GetData()); } void Target::ClearModules(bool delete_locations) { diff --git a/lldb/source/Target/ThreadPlanTracer.cpp b/lldb/source/Target/ThreadPlanTracer.cpp index 9f661b3c59478..ff9f49c6d4bb6 100644 --- a/lldb/source/Target/ThreadPlanTracer.cpp +++ b/lldb/source/Target/ThreadPlanTracer.cpp @@ -27,7 +27,6 @@ #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/State.h" -#include "lldb/lldb-forward.h" using namespace lldb; using namespace lldb_private; @@ -42,13 +41,13 @@ ThreadPlanTracer::ThreadPlanTracer(Thread &thread) : m_process(*thread.GetProcess().get()), m_tid(thread.GetID()), m_enabled(false), m_stream_sp(), m_thread(nullptr) {} -StreamSP ThreadPlanTracer::GetLogStreamSP() { +Stream *ThreadPlanTracer::GetLogStream() { if (m_stream_sp) - return m_stream_sp; + return m_stream_sp.get(); else { TargetSP target_sp(GetThread().CalculateTarget()); if (target_sp) - return target_sp->GetDebugger().GetAsyncOutputStream(); + return &(target_sp->GetDebugger().GetOutputStream()); } return nullptr; } @@ -66,11 +65,12 @@ void ThreadPlanTracer::Log() { bool show_frame_index = false; bool show_fullpaths = false; - if (StreamSP stream_sp = GetLogStreamSP()) { - GetThread().GetStackFrameAtIndex(0)->Dump(stream_sp.get(), show_frame_index, + Stream *stream = GetLogStream(); + if (stream) { + GetThread().GetStackFrameAtIndex(0)->Dump(stream, show_frame_index, show_fullpaths); - stream_sp->Printf("\n"); - stream_sp->Flush(); + stream->Printf("\n"); + stream->Flush(); } } @@ -129,9 +129,9 @@ void ThreadPlanAssemblyTracer::TracingStarted() { void ThreadPlanAssemblyTracer::TracingEnded() { m_register_values.clear(); } void ThreadPlanAssemblyTracer::Log() { - StreamSP stream_sp = GetLogStreamSP(); + Stream *stream = GetLogStream(); - if (!stream_sp) + if (!stream) return; RegisterContext *reg_ctx = GetThread().GetRegisterContext().get(); @@ -143,10 +143,9 @@ void ThreadPlanAssemblyTracer::Log() { addr_valid = m_process.GetTarget().GetSectionLoadList().ResolveLoadAddress( pc, pc_addr); - pc_addr.Dump(stream_sp.get(), &GetThread(), - Address::DumpStyleResolvedDescription, + pc_addr.Dump(stream, &GetThread(), Address::DumpStyleResolvedDescription, Address::DumpStyleModuleWithFileAddress); - stream_sp->PutCString(" "); + stream->PutCString(" "); Disassembler *disassembler = GetDisassembler(); if (disassembler) { @@ -177,7 +176,7 @@ void ThreadPlanAssemblyTracer::Log() { instruction_list.GetInstructionAtIndex(0).get(); const FormatEntity::Entry *disassemble_format = m_process.GetTarget().GetDebugger().GetDisassemblyFormat(); - instruction->Dump(stream_sp.get(), max_opcode_byte_size, show_address, + instruction->Dump(stream, max_opcode_byte_size, show_address, show_bytes, show_control_flow_kind, nullptr, nullptr, nullptr, disassemble_format, 0); } @@ -200,12 +199,12 @@ void ThreadPlanAssemblyTracer::Log() { if (abi->GetArgumentValues(GetThread(), value_list)) { for (int arg_index = 0; arg_index < num_args; ++arg_index) { - stream_sp->Printf( + stream->Printf( "\n\targ[%d]=%llx", arg_index, value_list.GetValueAtIndex(arg_index)->GetScalar().ULongLong()); if (arg_index + 1 < num_args) - stream_sp->PutCString(", "); + stream->PutCString(", "); } } } @@ -224,14 +223,14 @@ void ThreadPlanAssemblyTracer::Log() { if (m_register_values[reg_num].GetType() == RegisterValue::eTypeInvalid || reg_value != m_register_values[reg_num]) { if (reg_value.GetType() != RegisterValue::eTypeInvalid) { - stream_sp->PutCString("\n\t"); - DumpRegisterValue(reg_value, *stream_sp, *reg_info, true, false, + stream->PutCString("\n\t"); + DumpRegisterValue(reg_value, *stream, *reg_info, true, false, eFormatDefault); } } m_register_values[reg_num] = reg_value; } } - stream_sp->EOL(); - stream_sp->Flush(); + stream->EOL(); + stream->Flush(); } diff --git a/lldb/test/API/terminal/TestEditline.py b/lldb/test/API/terminal/TestEditline.py index ddaa441d5f7c1..aa7d827e59944 100644 --- a/lldb/test/API/terminal/TestEditline.py +++ b/lldb/test/API/terminal/TestEditline.py @@ -2,6 +2,7 @@ Test that the lldb editline handling is configured correctly. """ + import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * @@ -68,22 +69,6 @@ def test_prompt_color(self): # Column: 1....6.8 self.child.expect(re.escape("\x1b[31m(lldb) \x1b[0m\x1b[8G")) - @skipIfAsan - @skipIfEditlineSupportMissing - def test_prompt_format_color(self): - """Test that we can change the prompt color with a format string.""" - self.launch(use_colors=True) - # Clear the prefix and suffix setting to simplify the output. - self.expect('settings set prompt-ansi-prefix ""') - self.expect('settings set prompt-ansi-suffix ""') - self.expect('settings set prompt "${ansi.fg.red}(lldb) ${ansi.normal}"') - self.child.send("foo") - # Make sure this change is reflected immediately. Check that the color - # is set (31) and the cursor position (8) is correct. - # Prompt: (lldb) _ - # Column: 1....6.8 - self.child.expect(re.escape("\x1b[31m(lldb) \x1b[0m\x1b[8Gfoo")) - @skipIfAsan @skipIfEditlineSupportMissing def test_prompt_no_color(self): diff --git a/lldb/unittests/Editline/EditlineTest.cpp b/lldb/unittests/Editline/EditlineTest.cpp index 6c5a0c907a33e..333ad77a0a16f 100644 --- a/lldb/unittests/Editline/EditlineTest.cpp +++ b/lldb/unittests/Editline/EditlineTest.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/Config.h" -#include "lldb/Host/File.h" #if LLDB_ENABLE_LIBEDIT @@ -26,7 +25,6 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/Pipe.h" #include "lldb/Host/PseudoTerminal.h" -#include "lldb/Host/StreamFile.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StringList.h" @@ -117,17 +115,10 @@ EditlineAdapter::EditlineAdapter() if (*_el_secondary_file == nullptr) return; - lldb::LockableStreamFileSP output_stream_sp = - std::make_shared(*_el_secondary_file, - NativeFile::Unowned, output_mutex); - lldb::LockableStreamFileSP error_stream_sp = - std::make_shared(*_el_secondary_file, - NativeFile::Unowned, output_mutex); - // Create an Editline instance. _editline_sp.reset(new lldb_private::Editline( - "gtest editor", *_el_secondary_file, output_stream_sp, error_stream_sp, - /*color=*/false)); + "gtest editor", *_el_secondary_file, *_el_secondary_file, + *_el_secondary_file, output_mutex)); _editline_sp->SetPrompt("> "); // Hookup our input complete callback. diff --git a/lldb/unittests/Utility/AnsiTerminalTest.cpp b/lldb/unittests/Utility/AnsiTerminalTest.cpp index 1ba9565c3f6af..a6dbfd6106142 100644 --- a/lldb/unittests/Utility/AnsiTerminalTest.cpp +++ b/lldb/unittests/Utility/AnsiTerminalTest.cpp @@ -16,21 +16,16 @@ TEST(AnsiTerminal, Empty) { EXPECT_EQ("", ansi::FormatAnsiTerminalCodes("")); } TEST(AnsiTerminal, WhiteSpace) { EXPECT_EQ(" ", ansi::FormatAnsiTerminalCodes(" ")); - EXPECT_EQ(" ", ansi::StripAnsiTerminalCodes(" ")); } TEST(AnsiTerminal, AtEnd) { EXPECT_EQ("abc\x1B[30m", ansi::FormatAnsiTerminalCodes("abc${ansi.fg.black}")); - - EXPECT_EQ("abc", ansi::StripAnsiTerminalCodes("abc\x1B[30m")); } TEST(AnsiTerminal, AtStart) { EXPECT_EQ("\x1B[30mabc", ansi::FormatAnsiTerminalCodes("${ansi.fg.black}abc")); - - EXPECT_EQ("abc", ansi::StripAnsiTerminalCodes("\x1B[30mabc")); } TEST(AnsiTerminal, KnownPrefix) { @@ -50,20 +45,10 @@ TEST(AnsiTerminal, Incomplete) { TEST(AnsiTerminal, Twice) { EXPECT_EQ("\x1B[30m\x1B[31mabc", ansi::FormatAnsiTerminalCodes("${ansi.fg.black}${ansi.fg.red}abc")); - - EXPECT_EQ("abc", ansi::StripAnsiTerminalCodes("\x1B[30m\x1B[31mabc")); } TEST(AnsiTerminal, Basic) { EXPECT_EQ( "abc\x1B[31mabc\x1B[0mabc", ansi::FormatAnsiTerminalCodes("abc${ansi.fg.red}abc${ansi.normal}abc")); - - EXPECT_EQ("abcabcabc", - ansi::StripAnsiTerminalCodes("abc\x1B[31mabc\x1B[0mabc")); -} - -TEST(AnsiTerminal, InvalidEscapeCode) { - EXPECT_EQ("abc\x1B[31kabcabc", - ansi::StripAnsiTerminalCodes("abc\x1B[31kabc\x1B[0mabc")); }