diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -17,6 +17,7 @@ #include "lldb/Core/FormatEntity.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/SourceManager.h" +#include "lldb/Core/StreamFile.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/Terminal.h" @@ -113,11 +114,21 @@ void SetAsyncExecution(bool async); - lldb::StreamFileSP GetInputFile() { return m_input_file_sp; } + lldb::FileSP GetInputFileSP() { return m_input_file_sp; } - lldb::StreamFileSP GetOutputFile() { return m_output_file_sp; } + lldb::StreamFileSP GetOutputStreamSP() { return m_output_stream_sp; } - lldb::StreamFileSP GetErrorFile() { return m_error_file_sp; } + lldb::StreamFileSP GetErrorStreamSP() { return m_error_stream_sp; } + + lldb_private::File &GetInputFile() { return *m_input_file_sp; } + + lldb_private::File &GetOutputFile() { return m_output_stream_sp->GetFile(); } + + lldb_private::File &GetErrorFile() { return m_error_stream_sp->GetFile(); } + + lldb_private::StreamFile &GetOutputStream() { return *m_output_stream_sp; } + + lldb_private::StreamFile &GetErrorStream() { return *m_error_stream_sp; } repro::DataRecorder *GetInputRecorder(); @@ -174,7 +185,7 @@ // 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::StreamFileSP &in, + void AdoptTopIOHandlerFilesIfInvalid(lldb::FileSP &in, lldb::StreamFileSP &out, lldb::StreamFileSP &err); @@ -356,9 +367,10 @@ void InstanceInitialize(); - lldb::StreamFileSP m_input_file_sp; - lldb::StreamFileSP m_output_file_sp; - lldb::StreamFileSP m_error_file_sp; + // these should never be NULL + lldb::FileSP m_input_file_sp; + 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 --- a/lldb/include/lldb/Core/IOHandler.h +++ b/lldb/include/lldb/Core/IOHandler.h @@ -58,8 +58,7 @@ IOHandler(Debugger &debugger, IOHandler::Type type); IOHandler(Debugger &debugger, IOHandler::Type type, - const lldb::StreamFileSP &input_sp, - const lldb::StreamFileSP &output_sp, + const lldb::FileSP &input_sp, const lldb::StreamFileSP &output_sp, const lldb::StreamFileSP &error_sp, uint32_t flags, repro::DataRecorder *data_recorder); @@ -123,11 +122,11 @@ FILE *GetErrorFILE(); - lldb::StreamFileSP &GetInputStreamFile(); + lldb::FileSP &GetInputFileSP(); - lldb::StreamFileSP &GetOutputStreamFile(); + lldb::StreamFileSP &GetOutputStreamFileSP(); - lldb::StreamFileSP &GetErrorStreamFile(); + lldb::StreamFileSP &GetErrorStreamFileSP(); Debugger &GetDebugger() { return m_debugger; } @@ -165,7 +164,7 @@ protected: Debugger &m_debugger; - lldb::StreamFileSP m_input_sp; + lldb::FileSP m_input_sp; lldb::StreamFileSP m_output_sp; lldb::StreamFileSP m_error_sp; repro::DataRecorder *m_data_recorder; @@ -333,7 +332,7 @@ repro::DataRecorder *data_recorder); IOHandlerEditline(Debugger &debugger, IOHandler::Type type, - const lldb::StreamFileSP &input_sp, + const lldb::FileSP &input_sp, const lldb::StreamFileSP &output_sp, const lldb::StreamFileSP &error_sp, uint32_t flags, const char *editline_name, // Used for saving history files @@ -349,7 +348,7 @@ const char *, bool, bool, uint32_t, IOHandlerDelegate &) = delete; - IOHandlerEditline(Debugger &, IOHandler::Type, const lldb::StreamFileSP &, + IOHandlerEditline(Debugger &, IOHandler::Type, const lldb::FileSP &, const lldb::StreamFileSP &, const lldb::StreamFileSP &, uint32_t, const char *, const char *, const char *, bool, bool, uint32_t, IOHandlerDelegate &) = delete; diff --git a/lldb/include/lldb/Core/StreamFile.h b/lldb/include/lldb/Core/StreamFile.h --- a/lldb/include/lldb/Core/StreamFile.h +++ b/lldb/include/lldb/Core/StreamFile.h @@ -35,18 +35,29 @@ StreamFile(FILE *fh, bool transfer_ownership); + StreamFile(std::shared_ptr file) : StreamFile() { SetFile(file); } + ~StreamFile() override; - File &GetFile() { return m_file; } + File &GetFile() { return *m_file_sp; } + + const File &GetFile() const { return *m_file_sp; } + + std::shared_ptr GetFileSP() { return m_file_sp; } - const File &GetFile() const { return m_file; } + void SetFile(std::shared_ptr file) { + if (file) + m_file_sp = file; + else + m_file_sp = std::make_shared(); + } void Flush() override; protected: // Classes that inherit from StreamFile can see and modify these - File m_file; + std::shared_ptr m_file_sp; // never NULL size_t WriteImpl(const void *s, size_t length) override; private: diff --git a/lldb/include/lldb/Host/File.h b/lldb/include/lldb/Host/File.h --- a/lldb/include/lldb/Host/File.h +++ b/lldb/include/lldb/Host/File.h @@ -125,12 +125,8 @@ WaitableHandle GetWaitableHandle() override; - void SetDescriptor(int fd, uint32_t options, bool transfer_ownership); - FILE *GetStream(); - void SetStream(FILE *fh, bool transfer_ownership); - /// Read bytes from a file from the current file position. /// /// NOTE: This function is NOT thread safe. Use the read function diff --git a/lldb/include/lldb/Host/FileSystem.h b/lldb/include/lldb/Host/FileSystem.h --- a/lldb/include/lldb/Host/FileSystem.h +++ b/lldb/include/lldb/Host/FileSystem.h @@ -63,7 +63,9 @@ /// Wraps ::open in a platform-independent way. int Open(const char *path, int flags, int mode); - Status Open(File &File, const FileSpec &file_spec, uint32_t options, + // file will be set to null if there's an error. + Status Open(std::shared_ptr &file, const FileSpec &file_spec, + uint32_t options, uint32_t permissions = lldb::eFilePermissionsFileDefault, bool should_close_fd = true); diff --git a/lldb/scripts/Python/python-typemaps.swig b/lldb/scripts/Python/python-typemaps.swig --- a/lldb/scripts/Python/python-typemaps.swig +++ b/lldb/scripts/Python/python-typemaps.swig @@ -395,13 +395,13 @@ else { PythonFile py_file(PyRefType::Borrowed, $input); - File file; + lldb::FileSP file; if (!py_file.GetUnderlyingFile(file)) return nullptr; - $1 = file.GetStream(); + $1 = file->GetStream(); if ($1) - file.Clear(); + file->Clear(); } } diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -329,9 +329,8 @@ LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetInputFileHandle); if (m_opaque_sp) { - StreamFileSP stream_file_sp(m_opaque_sp->GetInputFile()); - if (stream_file_sp) - return LLDB_RECORD_RESULT(stream_file_sp->GetFile().GetStream()); + File &file_sp = m_opaque_sp->GetInputFile(); + return LLDB_RECORD_RESULT(file_sp.GetStream()); } return nullptr; } @@ -340,9 +339,8 @@ LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetOutputFileHandle); if (m_opaque_sp) { - StreamFileSP stream_file_sp(m_opaque_sp->GetOutputFile()); - if (stream_file_sp) - return LLDB_RECORD_RESULT(stream_file_sp->GetFile().GetStream()); + StreamFile &stream_file = m_opaque_sp->GetOutputStream(); + return LLDB_RECORD_RESULT(stream_file.GetFile().GetStream()); } return nullptr; } @@ -351,9 +349,8 @@ LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetErrorFileHandle); if (m_opaque_sp) { - StreamFileSP stream_file_sp(m_opaque_sp->GetErrorFile()); - if (stream_file_sp) - return LLDB_RECORD_RESULT(stream_file_sp->GetFile().GetStream()); + StreamFile &stream_file = m_opaque_sp->GetErrorStream(); + return LLDB_RECORD_RESULT(stream_file.GetFile().GetStream()); } return nullptr; } diff --git a/lldb/source/API/SBStream.cpp b/lldb/source/API/SBStream.cpp --- a/lldb/source/API/SBStream.cpp +++ b/lldb/source/API/SBStream.cpp @@ -89,8 +89,9 @@ else open_options |= File::eOpenOptionTruncate; - FileSystem::Instance().Open(stream_file->GetFile(), FileSpec(path), - open_options); + FileSP file; + FileSystem::Instance().Open(file, FileSpec(path), open_options); + stream_file->SetFile(file); m_opaque_up.reset(stream_file); if (m_opaque_up) { diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp --- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -221,7 +221,7 @@ Options *GetOptions() override { return &m_options; } void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + 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 --- a/lldb/source/Commands/CommandObjectCommands.cpp +++ b/lldb/source/Commands/CommandObjectCommands.cpp @@ -945,7 +945,7 @@ protected: void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + 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 " @@ -1585,7 +1585,7 @@ }; void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp && interactive) { output_sp->PutCString(g_python_command_instructions); output_sp->Flush(); @@ -1594,7 +1594,7 @@ void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override { - StreamFileSP error_sp = io_handler.GetErrorStreamFile(); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter(); if (interpreter) { diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -498,8 +498,8 @@ // StreamSP output_stream = // io_handler.GetDebugger().GetAsyncOutputStream(); // StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream(); - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); - StreamFileSP error_sp(io_handler.GetErrorStreamFile()); + StreamFileSP output_sp = io_handler.GetOutputStreamFileSP(); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); EvaluateExpression(line.c_str(), output_sp.get(), error_sp.get()); if (output_sp) @@ -537,7 +537,7 @@ 1, // Show line numbers starting at 1 *this, nullptr)); - StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile()); + StreamFileSP output_sp = io_handler_sp->GetOutputStreamFileSP(); if (output_sp) { output_sp->PutCString( "Enter expressions, then terminate with an empty line to evaluate:\n"); diff --git a/lldb/source/Commands/CommandObjectGUI.cpp b/lldb/source/Commands/CommandObjectGUI.cpp --- a/lldb/source/Commands/CommandObjectGUI.cpp +++ b/lldb/source/Commands/CommandObjectGUI.cpp @@ -28,9 +28,9 @@ if (args.GetArgumentCount() == 0) { Debugger &debugger = GetDebugger(); - lldb::StreamFileSP input_sp = debugger.GetInputFile(); - if (input_sp && input_sp->GetFile().GetIsRealTerminal() && - input_sp->GetFile().GetIsInteractive()) { + File &input = debugger.GetInputFile(); + if (input.GetIsRealTerminal() && + input.GetIsInteractive()) { IOHandlerSP io_handler_sp(new IOHandlerCursesGUI(debugger)); if (io_handler_sp) debugger.PushIOHandler(io_handler_sp); diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp --- a/lldb/source/Commands/CommandObjectMemory.cpp +++ b/lldb/source/Commands/CommandObjectMemory.cpp @@ -779,8 +779,11 @@ if (append) open_options |= File::eOpenOptionAppend; - Status error = FileSystem::Instance().Open(outfile_stream.GetFile(), - outfile_spec, open_options); + FileSP file; + Status error = + FileSystem::Instance().Open(file, outfile_spec, open_options); + outfile_stream.SetFile(file); + if (error.Success()) { if (m_memory_options.m_output_as_binary) { const size_t bytes_written = diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -4555,7 +4555,7 @@ protected: void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp && interactive) { output_sp->PutCString( "Enter your stop hook command(s). Type 'DONE' to end.\n"); @@ -4567,7 +4567,7 @@ std::string &line) override { if (m_stop_hook_sp) { if (line.empty()) { - StreamFileSP error_sp(io_handler.GetErrorStreamFile()); + StreamFileSP error_sp(io_handler.GetErrorStreamFileSP()); if (error_sp) { error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", @@ -4579,7 +4579,7 @@ target->RemoveStopHookByID(m_stop_hook_sp->GetID()); } else { m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line); - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp) { output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID()); diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp --- a/lldb/source/Commands/CommandObjectType.cpp +++ b/lldb/source/Commands/CommandObjectType.cpp @@ -151,7 +151,7 @@ "for\n" " internal_dict: an LLDB support object not to be used\"\"\"\n"; - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp && interactive) { output_sp->PutCString(g_summary_addreader_instructions); output_sp->Flush(); @@ -160,7 +160,7 @@ void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override { - StreamFileSP error_sp = io_handler.GetErrorStreamFile(); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); #ifndef LLDB_DISABLE_PYTHON ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter(); @@ -383,7 +383,7 @@ } void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp && interactive) { output_sp->PutCString(g_synth_addreader_instructions); output_sp->Flush(); @@ -392,7 +392,7 @@ void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override { - StreamFileSP error_sp = io_handler.GetErrorStreamFile(); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); #ifndef LLDB_DISABLE_PYTHON ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter(); diff --git a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp --- a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp @@ -207,7 +207,7 @@ Options *GetOptions() override { return &m_options; } void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp && interactive) { output_sp->PutCString( "Enter your debugger command(s). Type 'DONE' to end.\n"); diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -297,14 +297,12 @@ std::list errors; StreamString feedback_stream; if (!target_sp->LoadScriptingResources(errors, &feedback_stream)) { - StreamFileSP stream_sp(GetErrorFile()); - if (stream_sp) { - for (auto error : errors) { - stream_sp->Printf("%s\n", error.AsCString()); - } - if (feedback_stream.GetSize()) - stream_sp->PutCString(feedback_stream.GetString()); + Stream &s = GetErrorStream(); + for (auto error : errors) { + s.Printf("%s\n", error.AsCString()); } + if (feedback_stream.GetSize()) + s.PutCString(feedback_stream.GetString()); } } } @@ -700,9 +698,9 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) : UserID(g_unique_id++), Properties(std::make_shared()), - m_input_file_sp(std::make_shared(stdin, false)), - m_output_file_sp(std::make_shared(stdout, false)), - m_error_file_sp(std::make_shared(stderr, false)), + 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(), @@ -757,7 +755,7 @@ if (term && !strcmp(term, "dumb")) SetUseColor(false); // Turn off use-color if we don't write to a terminal with color support. - if (!m_output_file_sp->GetFile().GetIsTerminalWithColors()) + if (!GetOutputFile().GetIsTerminalWithColors()) SetUseColor(false); #if defined(_WIN32) && defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) @@ -798,8 +796,7 @@ // Close the input file _before_ we close the input read communications // class as it does NOT own the input file, our m_input_file does. m_terminal_state.Clear(); - if (m_input_file_sp) - m_input_file_sp->GetFile().Close(); + GetInputFile().Close(); m_command_interpreter_up->Clear(); }); @@ -827,14 +824,10 @@ void Debugger::SetInputFileHandle(FILE *fh, bool tranfer_ownership, repro::DataRecorder *recorder) { m_input_recorder = recorder; - if (m_input_file_sp) - m_input_file_sp->GetFile().SetStream(fh, tranfer_ownership); - else - m_input_file_sp = std::make_shared(fh, tranfer_ownership); - File &in_file = m_input_file_sp->GetFile(); - if (!in_file.IsValid()) - in_file.SetStream(stdin, true); + m_input_file_sp = std::make_shared(fh, tranfer_ownership); + if (!m_input_file_sp->IsValid()) + m_input_file_sp = std::make_shared(stdin, false); // Save away the terminal state if that is relevant, so that we can restore // it in RestoreInputState. @@ -842,14 +835,10 @@ } void Debugger::SetOutputFileHandle(FILE *fh, bool tranfer_ownership) { - if (m_output_file_sp) - m_output_file_sp->GetFile().SetStream(fh, tranfer_ownership); - else - m_output_file_sp = std::make_shared(fh, tranfer_ownership); - File &out_file = m_output_file_sp->GetFile(); - if (!out_file.IsValid()) - out_file.SetStream(stdout, false); + GetOutputStream().SetFile(std::make_shared(fh, tranfer_ownership)); + if (!GetOutputFile()) + GetOutputStream().SetFile(std::make_shared(stdout, false)); // Do not create the ScriptInterpreter just for setting the output file // handle as the constructor will know how to do the right thing on its own. @@ -859,22 +848,15 @@ } void Debugger::SetErrorFileHandle(FILE *fh, bool tranfer_ownership) { - if (m_error_file_sp) - m_error_file_sp->GetFile().SetStream(fh, tranfer_ownership); - else - m_error_file_sp = std::make_shared(fh, tranfer_ownership); - - File &err_file = m_error_file_sp->GetFile(); - if (!err_file.IsValid()) - err_file.SetStream(stderr, false); + GetErrorStream().SetFile(std::make_shared(fh, tranfer_ownership)); + if (!GetErrorFile()) + GetErrorStream().SetFile(std::make_shared(stderr, false)); } void Debugger::SaveInputTerminalState() { - if (m_input_file_sp) { - File &in_file = m_input_file_sp->GetFile(); - if (in_file.GetDescriptor() != File::kInvalidDescriptor) - m_terminal_state.Save(in_file.GetDescriptor(), true); - } + int fd = GetInputFile().GetDescriptor(); + if (fd != File::kInvalidDescriptor) + m_terminal_state.Save(fd, true); } void Debugger::RestoreInputTerminalState() { m_terminal_state.Restore(); } @@ -955,8 +937,9 @@ } void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) { - lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile(); - m_input_reader_stack.PrintAsync(stream.get(), s, len); + lldb_private::StreamFile &stream = + is_stdout ? GetOutputStream() : GetErrorStream(); + m_input_reader_stack.PrintAsync(&stream, s, len); } ConstString Debugger::GetTopIOHandlerControlSequence(char ch) { @@ -993,8 +976,7 @@ } } -void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in, - StreamFileSP &out, +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 @@ -1006,20 +988,20 @@ // If no STDIN has been set, then set it appropriately if (!in) { if (top_reader_sp) - in = top_reader_sp->GetInputStreamFile(); + in = top_reader_sp->GetInputFileSP(); else - in = GetInputFile(); + in = GetInputFileSP(); // If there is nothing, use stdin if (!in) - in = std::make_shared(stdin, false); + in = std::make_shared(stdin, false); } // If no STDOUT has been set, then set it appropriately if (!out) { if (top_reader_sp) - out = top_reader_sp->GetOutputStreamFile(); + out = top_reader_sp->GetOutputStreamFileSP(); else - out = GetOutputFile(); + out = GetOutputStreamSP(); // If there is nothing, use stdout if (!out) @@ -1028,13 +1010,13 @@ // If no STDERR has been set, then set it appropriately if (!err) { if (top_reader_sp) - err = top_reader_sp->GetErrorStreamFile(); + err = top_reader_sp->GetErrorStreamFileSP(); else - err = GetErrorFile(); + err = GetErrorStreamSP(); // If there is nothing, use stderr if (!err) - err = std::make_shared(stdout, false); + err = std::make_shared(stderr, false); } } @@ -1202,7 +1184,7 @@ LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; } else if (log_file.empty()) { log_stream_sp = std::make_shared( - GetOutputFile()->GetFile().GetDescriptor(), !should_close, unbuffered); + GetOutputFile().GetDescriptor(), !should_close, unbuffered); } else { auto pos = m_log_streams.find(log_file); if (pos != m_log_streams.end()) @@ -1597,8 +1579,7 @@ void Debugger::StopIOHandlerThread() { if (m_io_handler_thread.IsJoinable()) { - if (m_input_file_sp) - m_input_file_sp->GetFile().Close(); + GetInputFile().Close(); m_io_handler_thread.Join(nullptr); } } diff --git a/lldb/source/Core/IOHandler.cpp b/lldb/source/Core/IOHandler.cpp --- a/lldb/source/Core/IOHandler.cpp +++ b/lldb/source/Core/IOHandler.cpp @@ -73,7 +73,7 @@ IOHandler::IOHandler(Debugger &debugger, IOHandler::Type type) : IOHandler(debugger, type, - StreamFileSP(), // Adopt STDIN from top input reader + FileSP(), // Adopt STDIN from top input reader StreamFileSP(), // Adopt STDOUT from top input reader StreamFileSP(), // Adopt STDERR from top input reader 0, // Flags @@ -81,7 +81,7 @@ ) {} IOHandler::IOHandler(Debugger &debugger, IOHandler::Type type, - const lldb::StreamFileSP &input_sp, + const lldb::FileSP &input_sp, const lldb::StreamFileSP &output_sp, const lldb::StreamFileSP &error_sp, uint32_t flags, repro::DataRecorder *data_recorder) @@ -98,7 +98,7 @@ IOHandler::~IOHandler() = default; int IOHandler::GetInputFD() { - return (m_input_sp ? m_input_sp->GetFile().GetDescriptor() : -1); + return (m_input_sp ? m_input_sp->GetDescriptor() : -1); } int IOHandler::GetOutputFD() { @@ -110,7 +110,7 @@ } FILE *IOHandler::GetInputFILE() { - return (m_input_sp ? m_input_sp->GetFile().GetStream() : nullptr); + return (m_input_sp ? m_input_sp->GetStream() : nullptr); } FILE *IOHandler::GetOutputFILE() { @@ -121,18 +121,18 @@ return (m_error_sp ? m_error_sp->GetFile().GetStream() : nullptr); } -StreamFileSP &IOHandler::GetInputStreamFile() { return m_input_sp; } +FileSP &IOHandler::GetInputFileSP() { return m_input_sp; } -StreamFileSP &IOHandler::GetOutputStreamFile() { return m_output_sp; } +StreamFileSP &IOHandler::GetOutputStreamFileSP() { return m_output_sp; } -StreamFileSP &IOHandler::GetErrorStreamFile() { return m_error_sp; } +StreamFileSP &IOHandler::GetErrorStreamFileSP() { return m_error_sp; } bool IOHandler::GetIsInteractive() { - return GetInputStreamFile()->GetFile().GetIsInteractive(); + return GetInputFileSP() ? GetInputFileSP()->GetIsInteractive() : false; } bool IOHandler::GetIsRealTerminal() { - return GetInputStreamFile()->GetFile().GetIsRealTerminal(); + return GetInputFileSP() ? GetInputFileSP()->GetIsRealTerminal() : false; } void IOHandler::SetPopped(bool b) { m_popped.SetValue(b, eBroadcastOnChange); } @@ -235,7 +235,7 @@ bool multi_line, bool color_prompts, uint32_t line_number_start, IOHandlerDelegate &delegate, repro::DataRecorder *data_recorder) : IOHandlerEditline(debugger, type, - StreamFileSP(), // Inherit input from top input reader + FileSP(), // Inherit input from top input reader StreamFileSP(), // Inherit output from top input reader StreamFileSP(), // Inherit error from top input reader 0, // Flags @@ -244,9 +244,9 @@ line_number_start, delegate, data_recorder) {} IOHandlerEditline::IOHandlerEditline( - Debugger &debugger, IOHandler::Type type, - const lldb::StreamFileSP &input_sp, const lldb::StreamFileSP &output_sp, - const lldb::StreamFileSP &error_sp, uint32_t flags, + Debugger &debugger, IOHandler::Type type, const lldb::FileSP &input_sp, + 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_prompts, uint32_t line_number_start, @@ -266,7 +266,7 @@ #ifndef LLDB_DISABLE_LIBEDIT bool use_editline = false; - use_editline = m_input_sp->GetFile().GetIsRealTerminal(); + use_editline = m_input_sp && m_input_sp->GetIsRealTerminal(); if (use_editline) { m_editline_up.reset(new Editline(editline_name, GetInputFILE(), @@ -596,7 +596,7 @@ IOHandler::PrintAsync(stream, s, len); #ifdef _MSC_VER if (prompt) - IOHandler::PrintAsync(GetOutputStreamFile().get(), prompt, + IOHandler::PrintAsync(GetOutputStreamFileSP().get(), prompt, strlen(prompt)); #endif } diff --git a/lldb/source/Core/StreamFile.cpp b/lldb/source/Core/StreamFile.cpp --- a/lldb/source/Core/StreamFile.cpp +++ b/lldb/source/Core/StreamFile.cpp @@ -15,35 +15,43 @@ using namespace lldb_private; // StreamFile constructor -StreamFile::StreamFile() : Stream(), m_file() {} +StreamFile::StreamFile() : Stream() { m_file_sp = std::make_shared(); } StreamFile::StreamFile(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) - : Stream(flags, addr_size, byte_order), m_file() {} + : Stream(flags, addr_size, byte_order) { + m_file_sp = std::make_shared(); +} -StreamFile::StreamFile(int fd, bool transfer_ownership) - : Stream(), m_file(fd, File::eOpenOptionWrite, transfer_ownership) {} +StreamFile::StreamFile(int fd, bool transfer_ownership) : Stream() { + m_file_sp = + std::make_shared(fd, File::eOpenOptionWrite, transfer_ownership); +} -StreamFile::StreamFile(FILE *fh, bool transfer_ownership) - : Stream(), m_file(fh, transfer_ownership) {} +StreamFile::StreamFile(FILE *fh, bool transfer_ownership) : Stream() { + m_file_sp = std::make_shared(fh, transfer_ownership); +} -StreamFile::StreamFile(const char *path) : Stream(), m_file() { - FileSystem::Instance().Open(m_file, FileSpec(path), +StreamFile::StreamFile(const char *path) : Stream() { + FileSystem::Instance().Open(m_file_sp, FileSpec(path), File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec); + if (!m_file_sp) + m_file_sp = std::make_shared(); } StreamFile::StreamFile(const char *path, uint32_t options, uint32_t permissions) - : Stream(), m_file() { - - FileSystem::Instance().Open(m_file, FileSpec(path), options, permissions); + : Stream() { + FileSystem::Instance().Open(m_file_sp, FileSpec(path), options, permissions); + if (!m_file_sp) + m_file_sp = std::make_shared(); } StreamFile::~StreamFile() {} -void StreamFile::Flush() { m_file.Flush(); } +void StreamFile::Flush() { m_file_sp->Flush(); } size_t StreamFile::WriteImpl(const void *s, size_t length) { - m_file.Write(s, length); + m_file_sp->Write(s, length); return length; } diff --git a/lldb/source/Expression/REPL.cpp b/lldb/source/Expression/REPL.cpp --- a/lldb/source/Expression/REPL.cpp +++ b/lldb/source/Expression/REPL.cpp @@ -96,7 +96,7 @@ lldb::ProcessSP process_sp = m_target.GetProcessSP(); if (process_sp && process_sp->IsAlive()) return; - lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFile()); + lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP()); error_sp->Printf("REPL requires a running target process.\n"); io_handler.SetIsDone(true); } @@ -180,8 +180,8 @@ } void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { - lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFile()); - lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFile()); + lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); + lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP()); bool extra_line = false; bool did_quit = false; @@ -398,17 +398,19 @@ // Update our code on disk if (!m_repl_source_path.empty()) { - lldb_private::File file; + std::shared_ptr file; FileSystem::Instance().Open(file, FileSpec(m_repl_source_path), File::eOpenOptionWrite | File::eOpenOptionTruncate | File::eOpenOptionCanCreate, lldb::eFilePermissionsFileDefault); - std::string code(m_code.CopyList()); - code.append(1, '\n'); - size_t bytes_written = code.size(); - file.Write(code.c_str(), bytes_written); - file.Close(); + if (file) { + std::string code(m_code.CopyList()); + code.append(1, '\n'); + size_t bytes_written = code.size(); + file->Write(code.c_str(), bytes_written); + file->Close(); + } // Now set the default file and line to the REPL source file m_target.GetSourceManager().SetDefaultFileAndLine( diff --git a/lldb/source/Host/common/File.cpp b/lldb/source/Host/common/File.cpp --- a/lldb/source/Host/common/File.cpp +++ b/lldb/source/Host/common/File.cpp @@ -93,14 +93,6 @@ IOObject::WaitableHandle File::GetWaitableHandle() { return GetDescriptor(); } -void File::SetDescriptor(int fd, uint32_t options, bool transfer_ownership) { - if (IsValid()) - Close(); - m_descriptor = fd; - m_should_close_fd = transfer_ownership; - m_options = options; -} - FILE *File::GetStream() { if (!StreamIsValid()) { if (DescriptorIsValid()) { @@ -133,13 +125,6 @@ return m_stream; } -void File::SetStream(FILE *fh, bool transfer_ownership) { - if (IsValid()) - Close(); - m_stream = fh; - m_own_stream = transfer_ownership; -} - uint32_t File::GetPermissions(Status &error) const { int fd = GetDescriptor(); if (fd != kInvalidDescriptor) { diff --git a/lldb/source/Host/common/FileCache.cpp b/lldb/source/Host/common/FileCache.cpp --- a/lldb/source/Host/common/FileCache.cpp +++ b/lldb/source/Host/common/FileCache.cpp @@ -29,9 +29,9 @@ error.SetErrorString("empty path"); return UINT64_MAX; } - FileSP file_sp(new File()); - error = FileSystem::Instance().Open(*file_sp, file_spec, flags, mode); - if (!file_sp->IsValid()) + FileSP file_sp; + error = FileSystem::Instance().Open(file_sp, file_spec, flags, mode); + if (!file_sp) return UINT64_MAX; lldb::user_id_t fd = file_sp->GetDescriptor(); m_cache[fd] = file_sp; diff --git a/lldb/source/Host/common/FileSystem.cpp b/lldb/source/Host/common/FileSystem.cpp --- a/lldb/source/Host/common/FileSystem.cpp +++ b/lldb/source/Host/common/FileSystem.cpp @@ -415,13 +415,13 @@ return mode; } -Status FileSystem::Open(File &File, const FileSpec &file_spec, uint32_t options, - uint32_t permissions, bool should_close_fd) { +Status FileSystem::Open(FileSP &filesp, const FileSpec &file_spec, + uint32_t options, uint32_t permissions, + bool should_close_fd) { if (m_collector) m_collector->addFile(file_spec.GetPath()); - if (File.IsValid()) - File.Close(); + filesp.reset(); const int open_flags = GetOpenFlags(options); const mode_t open_mode = @@ -436,11 +436,13 @@ Status error; if (!File::DescriptorIsValid(descriptor)) { - File.SetDescriptor(-1, options, false); + errno = EINVAL; error.SetErrorToErrno(); } else { - File.SetDescriptor(descriptor, options, should_close_fd); + filesp = std::make_shared(descriptor, options, should_close_fd); } + if (filesp && !filesp->IsValid()) + filesp.reset(); return error; } diff --git a/lldb/source/Host/windows/Host.cpp b/lldb/source/Host/windows/Host.cpp --- a/lldb/source/Host/windows/Host.cpp +++ b/lldb/source/Host/windows/Host.cpp @@ -34,9 +34,12 @@ bool GetTripleForProcess(const FileSpec &executable, llvm::Triple &triple) { // Open the PE File as a binary file, and parse just enough information to // determine the machine type. - File imageBinary; - FileSystem::Instance().Open(imageBinary, executable, File::eOpenOptionRead, + FileSP imageBinarySP; + FileSystem::Instance().Open(imageBinarySP, executable, File::eOpenOptionRead, lldb::eFilePermissionsUserRead); + if (!imageBinarySP) + return false; + File &imageBinary = *imageBinarySP; imageBinary.SeekFromStart(0x3c); int32_t peOffset = 0; uint32_t peHead = 0; diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -2315,12 +2315,11 @@ return; } - StreamFileSP input_file_sp(new StreamFile()); std::string cmd_file_path = cmd_file.GetPath(); - Status error = FileSystem::Instance().Open(input_file_sp->GetFile(), cmd_file, + FileSP input_file_sp; + Status error = FileSystem::Instance().Open(input_file_sp, cmd_file, File::eOpenOptionRead); - - if (error.Fail()) { + if (!input_file_sp || error.Fail()) { result.AppendErrorWithFormat( "error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(), error.AsCString()); @@ -2412,8 +2411,8 @@ } if (flags & eHandleCommandFlagPrintResult) { - debugger.GetOutputFile()->Printf("Executing commands in '%s'.\n", - cmd_file_path.c_str()); + debugger.GetOutputFile().Printf("Executing commands in '%s'.\n", + cmd_file_path.c_str()); } // Used for inheriting the right settings when "command source" might @@ -2713,8 +2712,8 @@ // from a file) we need to echo the command out so we don't just see the // command output and no command... if (EchoCommandNonInteractive(line, io_handler.GetFlags())) - io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(), - line.c_str()); + io_handler.GetOutputStreamFileSP()->Printf( + "%s%s\n", io_handler.GetPrompt(), line.c_str()); } StartHandlingCommand(); @@ -2731,13 +2730,13 @@ if (!result.GetImmediateOutputStream()) { llvm::StringRef output = result.GetOutputData(); - PrintCommandOutput(*io_handler.GetOutputStreamFile(), output); + PrintCommandOutput(*io_handler.GetOutputStreamFileSP(), output); } // Now emit the command error text from the command we just executed if (!result.GetImmediateErrorStream()) { llvm::StringRef error = result.GetErrorData(); - PrintCommandOutput(*io_handler.GetErrorStreamFile(), error); + PrintCommandOutput(*io_handler.GetErrorStreamFileSP(), error); } } @@ -2904,8 +2903,8 @@ m_command_io_handler_sp = std::make_shared( m_debugger, IOHandler::Type::CommandInterpreter, - m_debugger.GetInputFile(), m_debugger.GetOutputFile(), - m_debugger.GetErrorFile(), flags, "lldb", m_debugger.GetPrompt(), + m_debugger.GetInputFileSP(), m_debugger.GetOutputStreamSP(), + m_debugger.GetErrorStreamSP(), flags, "lldb", m_debugger.GetPrompt(), llvm::StringRef(), // Continuation prompt false, // Don't enable multiple line input, just single line commands m_debugger.GetUseColor(), diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp --- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp +++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp @@ -773,12 +773,9 @@ } if (IsKernel() && m_uuid.IsValid()) { - Stream *s = target.GetDebugger().GetOutputFile().get(); - if (s) { - 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); } if (!m_module_sp) { @@ -839,11 +836,9 @@ } if (IsKernel() && !m_module_sp) { - Stream *s = target.GetDebugger().GetOutputFile().get(); - if (s) { - s->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"); } } @@ -932,25 +927,24 @@ bool is_loaded = IsLoaded(); if (is_loaded && m_module_sp && IsKernel()) { - Stream *s = target.GetDebugger().GetOutputFile().get(); - if (s) { - 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); - } + 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("Loaded kernel file %s\n", - m_module_sp->GetFileSpec().GetPath().c_str()); - } - s->Flush(); } + { + s.Printf("Loaded kernel file %s\n", + m_module_sp->GetFileSpec().GetPath().c_str()); + } + s.Flush(); } + return is_loaded; } @@ -1109,11 +1103,10 @@ lldb::offset_t offset = 0; m_kext_summary_header.version = data.GetU32(&offset); if (m_kext_summary_header.version > 128) { - Stream *s = - m_process->GetTarget().GetDebugger().GetOutputFile().get(); - 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(); @@ -1124,11 +1117,11 @@ if (m_kext_summary_header.entry_size > 4096) { // If we get an improbably large entry_size, we're probably // getting bad memory. - Stream *s = - m_process->GetTarget().GetDebugger().GetOutputFile().get(); - 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; } @@ -1142,11 +1135,10 @@ if (m_kext_summary_header.entry_count > 10000) { // If we get an improbably large number of kexts, we're probably // getting bad memory. - Stream *s = - m_process->GetTarget().GetDebugger().GetOutputFile().get(); - 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; } @@ -1247,18 +1239,17 @@ number_of_old_kexts_being_removed == 0) return true; - Stream *s = m_process->GetTarget().GetDebugger().GetOutputFile().get(); - if (s && load_kexts) { + 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); } } @@ -1304,11 +1295,11 @@ m_process->GetStopID() == image_info.GetProcessStopId()) loaded_module_list.AppendIfNeeded(image_info.GetModule()); - if (s && load_kexts) { + if (load_kexts) { if (kext_successfully_added) - s->Printf("."); + s.Printf("."); else - s->Printf("-"); + s.Printf("-"); } if (log) @@ -1330,8 +1321,7 @@ if (image_info.GetModule()) { unloaded_module_list.AppendIfNeeded(image_info.GetModule()); } - if (s) - 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; @@ -1342,12 +1332,12 @@ } } - if (s && load_kexts) { - s->Printf(" done.\n"); + if (load_kexts) { + 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()); @@ -1359,10 +1349,10 @@ 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(); + s.Flush(); } return true; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -1228,12 +1228,10 @@ type_system_helper->DeclMap(); // result can be NULL if (decl_map) { - Stream *error_stream = nullptr; Target *target = exe_ctx.GetTargetPtr(); - error_stream = target->GetDebugger().GetErrorFile().get(); - + auto &error_stream = target->GetDebugger().GetErrorStream(); IRForTarget ir_for_target(decl_map, m_expr.NeedsVariableResolution(), - *execution_unit_sp, *error_stream, + *execution_unit_sp, error_stream, function_name.AsCString()); bool ir_can_run = diff --git a/lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp b/lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp --- a/lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp +++ b/lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp @@ -264,7 +264,7 @@ *thread_sp, description, report)); StreamFileSP stream_sp( - process_sp->GetTarget().GetDebugger().GetOutputFile()); + process_sp->GetTarget().GetDebugger().GetOutputStreamSP()); if (stream_sp) { stream_sp->Printf("AddressSanitizer report breakpoint hit. Use 'thread " "info -s' to get extended information about the " diff --git a/lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp b/lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp --- a/lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp +++ b/lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp @@ -863,13 +863,11 @@ CreateStopReasonWithInstrumentationData( *thread_sp, stop_reason_description, report)); - StreamFileSP stream_sp( - process_sp->GetTarget().GetDebugger().GetOutputFile()); - if (stream_sp) { - stream_sp->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/UBSanRuntime.cpp b/lldb/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp --- a/lldb/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp +++ b/lldb/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp @@ -124,7 +124,7 @@ if (!frame_sp) return StructuredData::ObjectSP(); - StreamFileSP Stream(target.GetDebugger().GetOutputFile()); + StreamFileSP Stream = target.GetDebugger().GetOutputStreamSP(); EvaluateExpressionOptions options; options.SetUnwindOnError(true); diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp @@ -704,7 +704,7 @@ // step through any method dispatches. Warn to that effect and get out of // here. if (process_sp->CanJIT()) { - process_sp->GetTarget().GetDebugger().GetErrorFile()->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()); diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp --- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp @@ -2651,7 +2651,7 @@ // Check we can create writable file FileSpec file_spec(path); FileSystem::Instance().Resolve(file_spec); - File file; + FileSP file; FileSystem::Instance().Open(file, file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | @@ -2690,7 +2690,7 @@ LLDB_LOGF(log, "%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__, (uint64_t)num_bytes); - Status err = file.Write(&head, num_bytes); + Status err = file->Write(&head, num_bytes); if (!err.Success()) { strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path); strm.EOL(); @@ -2715,7 +2715,7 @@ LLDB_LOGF(log, "%s - writing element headers, 0x%" PRIx64 " bytes.", __FUNCTION__, (uint64_t)num_bytes); - err = file.Write(element_header_buffer.get(), num_bytes); + err = file->Write(element_header_buffer.get(), num_bytes); if (!err.Success()) { strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path); strm.EOL(); @@ -2727,7 +2727,7 @@ LLDB_LOGF(log, "%s - writing 0x%" PRIx64 " bytes", __FUNCTION__, (uint64_t)num_bytes); - err = file.Write(buffer.get(), num_bytes); + err = file->Write(buffer.get(), num_bytes); if (!err.Success()) { strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path); strm.EOL(); @@ -4585,9 +4585,11 @@ if (outfile_spec) { // Open output file std::string path = outfile_spec.GetPath(); - auto error = FileSystem::Instance().Open( - outfile_stream.GetFile(), outfile_spec, - File::eOpenOptionWrite | File::eOpenOptionCanCreate); + FileSP file; + auto error = FileSystem::Instance().Open(file, outfile_spec, + File::eOpenOptionWrite | + File::eOpenOptionCanCreate); + outfile_stream.SetFile(file); if (error.Success()) { output_strm = &outfile_stream; result.GetOutputStream().Printf("Results written to '%s'", diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -6271,22 +6271,22 @@ buffer.PutHex32(segment.flags); } - File core_file; + FileSP core_file; std::string core_file_path(outfile.GetPath()); error = FileSystem::Instance().Open(core_file, outfile, File::eOpenOptionWrite | File::eOpenOptionTruncate | File::eOpenOptionCanCreate); - if (error.Success()) { + if (error.Success() && core_file) { // Read 1 page at a time uint8_t bytes[0x1000]; // Write the mach header and load commands out to the core file size_t bytes_written = buffer.GetString().size(); - error = core_file.Write(buffer.GetString().data(), bytes_written); + error = core_file->Write(buffer.GetString().data(), bytes_written); if (error.Success()) { // Now write the file data for all memory segments in the process for (const auto &segment : segment_load_commands) { - if (core_file.SeekFromStart(segment.fileoff) == -1) { + if (core_file->SeekFromStart(segment.fileoff) == -1) { error.SetErrorStringWithFormat( "unable to seek to offset 0x%" PRIx64 " in '%s'", segment.fileoff, core_file_path.c_str()); @@ -6311,7 +6311,7 @@ if (bytes_read == bytes_to_read) { size_t bytes_written = bytes_read; - error = core_file.Write(bytes, bytes_written); + error = core_file->Write(bytes, bytes_written); bytes_left -= bytes_read; addr += bytes_read; } else { @@ -6319,7 +6319,7 @@ // be zero filled memset(bytes, 0, bytes_to_read); size_t bytes_written = bytes_to_read; - error = core_file.Write(bytes, bytes_written); + error = core_file->Write(bytes, bytes_written); bytes_left -= bytes_to_read; addr += bytes_to_read; } diff --git a/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm b/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm --- a/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm +++ b/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm @@ -382,7 +382,7 @@ static Status HandleFileAction(ProcessLaunchInfo &launch_info, NSMutableDictionary *options, NSString *key, - const int fd, File &file) { + const int fd, lldb::FileSP &file) { Status error; const FileAction *file_action = launch_info.GetFileActionForFD(fd); if (file_action) { @@ -434,7 +434,7 @@ file_options |= File::eOpenOptionRead; if ((oflag & O_RDWR) || (oflag & O_RDONLY)) file_options |= File::eOpenOptionWrite; - file.SetDescriptor(created_fd, file_options, true); + file = std::make_shared(created_fd, file_options, true); [options setValue:[NSNumber numberWithInteger:created_fd] forKey:key]; return error; // Success } else { @@ -494,9 +494,9 @@ [options setObject:env_dict forKey:kSimDeviceSpawnEnvironment]; Status error; - File stdin_file; - File stdout_file; - File stderr_file; + lldb::FileSP stdin_file; + lldb::FileSP stdout_file; + lldb::FileSP stderr_file; error = HandleFileAction(launch_info, options, kSimDeviceSpawnStdin, STDIN_FILENO, stdin_file); diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -512,14 +512,15 @@ mode_t mode = packet.GetHexMaxU32(false, 0600); FileSpec path_spec(path); FileSystem::Instance().Resolve(path_spec); - File file; + FileSP file; // Do not close fd. Status error = FileSystem::Instance().Open(file, path_spec, flags, mode, false); const int save_errno = error.GetError(); StreamString response; response.PutChar('F'); - response.Printf("%i", file.GetDescriptor()); + response.Printf("%i", file ? file->GetDescriptor() + : File::kInvalidDescriptor); if (save_errno) response.Printf(",%i", save_errno); return SendPacketNoLock(response.GetString()); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -99,12 +99,14 @@ // namespace. This allows you to attach with a debugger and call this function // and get the packet history dumped to a file. void DumpProcessGDBRemotePacketHistory(void *p, const char *path) { - StreamFile strm; - Status error = FileSystem::Instance().Open(strm.GetFile(), FileSpec(path), + FileSP file; + Status error = FileSystem::Instance().Open(file, FileSpec(path), File::eOpenOptionWrite | File::eOpenOptionCanCreate); - if (error.Success()) - ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(strm); + if (file) { + StreamFile stream(file); + ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(stream); + } } } // namespace lldb diff --git a/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp --- a/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp @@ -28,13 +28,13 @@ bool ScriptInterpreterNone::ExecuteOneLine(llvm::StringRef command, CommandReturnObject *, const ExecuteScriptOptions &) { - m_debugger.GetErrorFile()->PutCString( + m_debugger.GetErrorStream().PutCString( "error: there is no embedded script interpreter in this mode.\n"); return false; } void ScriptInterpreterNone::ExecuteInterpreterLoop() { - m_debugger.GetErrorFile()->PutCString( + m_debugger.GetErrorStream().PutCString( "error: there is no embedded script interpreter in this mode.\n"); } diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -469,7 +469,7 @@ static uint32_t GetOptionsFromMode(llvm::StringRef mode); - bool GetUnderlyingFile(File &file) const; + bool GetUnderlyingFile(lldb::FileSP &file) const; }; } // namespace lldb_private diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -950,9 +950,12 @@ PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); } PythonFile::PythonFile(const char *path, const char *mode) { - lldb_private::File file; + lldb::FileSP file; FileSystem::Instance().Open(file, FileSpec(path), GetOptionsFromMode(mode)); - Reset(file, mode); + if (file) + Reset(*file, mode); + else + Reset(); } PythonFile::PythonFile(PyRefType type, PyObject *o) { Reset(type, o); } @@ -1036,17 +1039,20 @@ .Default(0); } -bool PythonFile::GetUnderlyingFile(File &file) const { +bool PythonFile::GetUnderlyingFile(FileSP &file) const { if (!IsValid()) return false; - file.Close(); + if (file) + file->Close(); + // We don't own the file descriptor returned by this function, make sure the // File object knows about that. PythonString py_mode = GetAttributeValue("mode").AsType(); auto options = PythonFile::GetOptionsFromMode(py_mode.GetString()); - file.SetDescriptor(PyObject_AsFileDescriptor(m_py_obj), options, false); - return file.IsValid(); + file = std::make_shared(PyObject_AsFileDescriptor(m_py_obj), options, + false); + return file->IsValid(); } #endif diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -535,7 +535,7 @@ } if (instructions) { - StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp && interactive) { output_sp->PutCString(instructions); output_sp->Flush(); @@ -571,7 +571,7 @@ bp_options->SetCallback( ScriptInterpreterPythonImpl::BreakpointCallbackFunction, baton_sp); } else if (!batch_mode) { - StreamFileSP error_sp = io_handler.GetErrorStreamFile(); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); if (error_sp) { error_sp->Printf("Warning: No command attached to breakpoint.\n"); error_sp->Flush(); @@ -593,7 +593,7 @@ wp_options->SetCallback( ScriptInterpreterPythonImpl::WatchpointCallbackFunction, baton_sp); } else if (!batch_mode) { - StreamFileSP error_sp = io_handler.GetErrorStreamFile(); + StreamFileSP error_sp = io_handler.GetErrorStreamFileSP(); if (error_sp) { error_sp->Printf("Warning: No command attached to breakpoint.\n"); error_sp->Flush(); @@ -724,7 +724,7 @@ File out_file(out, false); File err_file(err, false); - lldb::StreamFileSP in_sp; + lldb::FileSP in_sp; lldb::StreamFileSP out_sp; lldb::StreamFileSP err_sp; if (!in_file.IsValid() || !out_file.IsValid() || !err_file.IsValid()) @@ -735,7 +735,7 @@ } else { if (!SetStdHandle(in_file, "stdin", m_saved_stdin, "r")) { if (in_sp) - SetStdHandle(in_sp->GetFile(), "stdin", m_saved_stdin, "r"); + SetStdHandle(*in_sp, "stdin", m_saved_stdin, "r"); } } @@ -854,7 +854,7 @@ // directly down to Python. Debugger &debugger = m_debugger; - StreamFileSP input_file_sp; + FileSP input_file_sp; StreamFileSP output_file_sp; StreamFileSP error_file_sp; Communication output_comm( @@ -862,7 +862,7 @@ bool join_read_thread = false; if (options.GetEnableIO()) { if (result) { - input_file_sp = debugger.GetInputFile(); + input_file_sp = debugger.GetInputFileSP(); // Set output to a temporary file so we can forward the results on to // the result object @@ -893,9 +893,8 @@ ::setbuf(outfile_handle, nullptr); result->SetImmediateOutputFile( - debugger.GetOutputFile()->GetFile().GetStream()); - result->SetImmediateErrorFile( - debugger.GetErrorFile()->GetFile().GetStream()); + debugger.GetOutputFile().GetStream()); + result->SetImmediateErrorFile(debugger.GetErrorFile().GetStream()); } } } @@ -903,20 +902,17 @@ debugger.AdoptTopIOHandlerFilesIfInvalid(input_file_sp, output_file_sp, error_file_sp); } else { - input_file_sp = std::make_shared(); - FileSystem::Instance().Open(input_file_sp->GetFile(), - FileSpec(FileSystem::DEV_NULL), + + FileSystem::Instance().Open(input_file_sp, FileSpec(FileSystem::DEV_NULL), File::eOpenOptionRead); - output_file_sp = std::make_shared(); - FileSystem::Instance().Open(output_file_sp->GetFile(), - FileSpec(FileSystem::DEV_NULL), + FileSP f; + FileSystem::Instance().Open(f, FileSpec(FileSystem::DEV_NULL), File::eOpenOptionWrite); - - error_file_sp = output_file_sp; + error_file_sp = output_file_sp = std::make_shared(f); } - FILE *in_file = input_file_sp->GetFile().GetStream(); + FILE *in_file = input_file_sp->GetStream(); FILE *out_file = output_file_sp->GetFile().GetStream(); FILE *err_file = error_file_sp->GetFile().GetStream(); bool success = false; @@ -1007,7 +1003,7 @@ // a running interpreter loop inside the already running Python interpreter // loop, so we won't do it. - if (!debugger.GetInputFile()->GetFile().IsValid()) + if (!debugger.GetInputFile().IsValid()) return; IOHandlerSP io_handler_sp(new IOHandlerPythonInterpreter(debugger, this)); diff --git a/lldb/source/Target/ModuleCache.cpp b/lldb/source/Target/ModuleCache.cpp --- a/lldb/source/Target/ModuleCache.cpp +++ b/lldb/source/Target/ModuleCache.cpp @@ -48,7 +48,7 @@ class ModuleLock { private: - File m_file; + FileSP m_file_sp; std::unique_ptr m_lock; FileSpec m_file_spec; @@ -157,16 +157,16 @@ return; m_file_spec = JoinPath(lock_dir_spec, uuid.GetAsString().c_str()); - FileSystem::Instance().Open(m_file, m_file_spec, + FileSystem::Instance().Open(m_file_sp, m_file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec); - if (!m_file) { + if (!m_file_sp) { error.SetErrorToErrno(); return; } - m_lock.reset(new lldb_private::LockFile(m_file.GetDescriptor())); + m_lock.reset(new lldb_private::LockFile(m_file_sp->GetDescriptor())); error = m_lock->WriteLock(0, 1); if (error.Fail()) error.SetErrorStringWithFormat("Failed to lock file: %s", @@ -174,10 +174,11 @@ } void ModuleLock::Delete() { - if (!m_file) + if (!m_file_sp) return; - m_file.Close(); + m_file_sp->Close(); + m_file_sp.reset(); llvm::sys::fs::remove(m_file_spec.GetPath()); } diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -1226,15 +1226,15 @@ if (fs::is_symlink_file(source.GetPath())) source_open_options |= File::eOpenOptionDontFollowSymlinks; - File source_file; + FileSP source_file; Status error = FileSystem::Instance().Open( source_file, source, source_open_options, lldb::eFilePermissionsUserRW); - uint32_t permissions = source_file.GetPermissions(error); + if (!source_file || !source_file->IsValid()) + return Status("PutFile: unable to open source file"); + uint32_t permissions = source_file->GetPermissions(error); if (permissions == 0) permissions = lldb::eFilePermissionsFileDefault; - if (!source_file.IsValid()) - return Status("PutFile: unable to open source file"); lldb::user_id_t dest_file = OpenFile( destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate | File::eOpenOptionCloseOnExec, @@ -1249,7 +1249,7 @@ uint64_t offset = 0; for (;;) { size_t bytes_read = buffer_sp->GetByteSize(); - error = source_file.Read(buffer_sp->GetBytes(), bytes_read); + error = source_file->Read(buffer_sp->GetBytes(), bytes_read); if (error.Fail() || bytes_read == 0) break; @@ -1262,7 +1262,7 @@ if (bytes_written != bytes_read) { // We didn't write the correct number of bytes, so adjust the file // position in the source file we are reading from... - source_file.SeekFromStart(offset); + source_file->SeekFromStart(offset); } } CloseFile(dest_file, error); @@ -1796,8 +1796,7 @@ if (!process_sp) return nullptr; - error = - process_sp->ConnectRemote(debugger.GetOutputFile().get(), connect_url); + error = process_sp->ConnectRemote(&debugger.GetOutputStream(), connect_url); if (error.Fail()) return nullptr; diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -1649,7 +1649,7 @@ Address symbol_address = symbol->GetAddress(); load_addr = ResolveIndirectFunction(&symbol_address, error); if (!error.Success() && show_error) { - GetTarget().GetDebugger().GetErrorFile()->Printf( + GetTarget().GetDebugger().GetErrorStream().Printf( "warning: failed to resolve indirect function at 0x%" PRIx64 " for breakpoint %i.%i: %s\n", symbol->GetLoadAddress(&GetTarget()), @@ -1688,7 +1688,7 @@ } else { if (show_error || use_hardware) { // Report error for setting breakpoint... - GetTarget().GetDebugger().GetErrorFile()->Printf( + GetTarget().GetDebugger().GetErrorStream().Printf( "warning: failed to set breakpoint site at 0x%" PRIx64 " for breakpoint %i.%i: %s\n", load_addr, owner->GetBreakpoint().GetID(), owner->GetID(), @@ -4300,9 +4300,9 @@ : IOHandler(process->GetTarget().GetDebugger(), IOHandler::Type::ProcessIO), m_process(process), + m_read_file(GetInputFD(), File::eOpenOptionRead, false), m_write_file(write_fd, File::eOpenOptionWrite, false) { m_pipe.CreateNew(false); - m_read_file.SetDescriptor(GetInputFD(), File::eOpenOptionRead, false); } ~IOHandlerProcessSTDIO() override = default; diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1358,15 +1358,15 @@ if (module_sp && !module_sp->LoadScriptingResourceInTarget( target, error, &feedback_stream)) { if (error.AsCString()) - target->GetDebugger().GetErrorFile()->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().GetErrorFile()->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 --- a/lldb/source/Target/ThreadPlanTracer.cpp +++ b/lldb/source/Target/ThreadPlanTracer.cpp @@ -46,7 +46,7 @@ else { TargetSP target_sp(m_thread.CalculateTarget()); if (target_sp) - return target_sp->GetDebugger().GetOutputFile().get(); + return &(target_sp->GetDebugger().GetOutputStream()); } return nullptr; } diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp --- a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp @@ -581,11 +581,14 @@ } TEST_F(PythonDataObjectsTest, TestPythonFile) { - File file; + lldb::FileSP file; FileSystem::Instance().Open(file, FileSpec(FileSystem::DEV_NULL), File::eOpenOptionRead); - PythonFile py_file(file, "r"); - EXPECT_TRUE(PythonFile::Check(py_file.get())); + EXPECT_TRUE(file); + if (file) { + PythonFile py_file(*file, "r"); + EXPECT_TRUE(PythonFile::Check(py_file.get())); + } } TEST_F(PythonDataObjectsTest, TestObjectAttributes) {