Skip to content

[lldb] Make GetOutputStreamSP and GetErrorStreamSP protected #127682

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 19, 2025

Conversation

JDevlieghere
Copy link
Member

This makes GetOutputStreamSP and GetErrorStreamSP protected members of Debugger. Users who want to print to the debugger's stream should use GetAsyncOutputStreamSP and GetAsyncErrorStreamSP instead and the few remaining stragglers have been migrated.

This makes GetOutputStreamSP and GetErrorStreamSP protected members of
Debugger. Users who want to print to the debugger's stream should use
GetAsyncOutputStreamSP and GetAsyncErrorStreamSP instead and the few
remaining stragglers have been migrated.
@JDevlieghere JDevlieghere requested a review from labath February 18, 2025 18:43
@llvmbot llvmbot added the lldb label Feb 18, 2025
@JDevlieghere
Copy link
Member Author

More context/background in #126630.

@llvmbot
Copy link
Member

llvmbot commented Feb 18, 2025

@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)

Changes

This makes GetOutputStreamSP and GetErrorStreamSP protected members of Debugger. Users who want to print to the debugger's stream should use GetAsyncOutputStreamSP and GetAsyncErrorStreamSP instead and the few remaining stragglers have been migrated.


Full diff: https://github.com/llvm/llvm-project/pull/127682.diff

13 Files Affected:

  • (modified) lldb/include/lldb/Core/Debugger.h (+12-8)
  • (modified) lldb/include/lldb/Target/ThreadPlanTracer.h (+1-1)
  • (modified) lldb/source/API/SBDebugger.cpp (+6-6)
  • (modified) lldb/source/Commands/CommandObjectGUI.cpp (+4-4)
  • (modified) lldb/source/Commands/CommandObjectLog.cpp (+2-1)
  • (modified) lldb/source/Core/Debugger.cpp (+4-4)
  • (modified) lldb/source/Interpreter/CommandInterpreter.cpp (+2-2)
  • (modified) lldb/source/Interpreter/ScriptInterpreter.cpp (+2-2)
  • (modified) lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp (+5-4)
  • (modified) lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp (-2)
  • (modified) lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp (+2-2)
  • (modified) lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp (+2-2)
  • (modified) lldb/source/Target/ThreadPlanTracer.cpp (+20-19)
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index d7751ca045bb2..7f08f3dd26106 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -131,17 +131,13 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
 
   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; }
 
-  File &GetOutputFile() { return m_output_stream_sp->GetFile(); }
+  lldb::FileSP GetInputFileSP() { return m_input_file_sp; }
+
+  lldb::FileSP GetOutputFileSP() { return m_output_stream_sp->GetFileSP(); }
 
-  File &GetErrorFile() { return m_error_stream_sp->GetFile(); }
+  lldb::FileSP GetErrorFileSP() { return m_error_stream_sp->GetFileSP(); }
 
   repro::DataRecorder *GetInputRecorder();
 
@@ -649,6 +645,14 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
 
   void PrintProgress(const ProgressEventData &data);
 
+  /// Except for Debugger and IOHandler, GetOutputStreamSP and GetErrorStreamSP
+  /// should not be used directly. Use GetAsyncOutputStream and
+  /// GetAsyncErrorStream instead.
+  /// @{
+  lldb::StreamFileSP GetOutputStreamSP() { return m_output_stream_sp; }
+  lldb::StreamFileSP GetErrorStreamSP() { return m_error_stream_sp; }
+  /// @}
+
   void PushIOHandler(const lldb::IOHandlerSP &reader_sp,
                      bool cancel_top_handler = true);
 
diff --git a/lldb/include/lldb/Target/ThreadPlanTracer.h b/lldb/include/lldb/Target/ThreadPlanTracer.h
index a6fd2f031dc22..7c45e213f94f1 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;
 
-  Stream *GetLogStream();
+  lldb::StreamSP GetLogStreamSP();
 
   virtual void Log();
 
diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index bf19d2ff8333c..e646b09e05852 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -509,14 +509,14 @@ SBFile SBDebugger::GetInputFile() {
 FILE *SBDebugger::GetOutputFileHandle() {
   LLDB_INSTRUMENT_VA(this);
   if (m_opaque_sp)
-    return m_opaque_sp->GetOutputStreamSP()->GetFile().GetStream();
+    return m_opaque_sp->GetOutputFileSP()->GetStream();
   return nullptr;
 }
 
 SBFile SBDebugger::GetOutputFile() {
   LLDB_INSTRUMENT_VA(this);
   if (m_opaque_sp)
-    return SBFile(m_opaque_sp->GetOutputStreamSP()->GetFileSP());
+    return SBFile(m_opaque_sp->GetOutputFileSP());
   return SBFile();
 }
 
@@ -524,7 +524,7 @@ FILE *SBDebugger::GetErrorFileHandle() {
   LLDB_INSTRUMENT_VA(this);
 
   if (m_opaque_sp)
-    return m_opaque_sp->GetErrorStreamSP()->GetFile().GetStream();
+    return m_opaque_sp->GetErrorFileSP()->GetStream();
   return nullptr;
 }
 
@@ -532,7 +532,7 @@ SBFile SBDebugger::GetErrorFile() {
   LLDB_INSTRUMENT_VA(this);
   SBFile file;
   if (m_opaque_sp)
-    return SBFile(m_opaque_sp->GetErrorStreamSP()->GetFileSP());
+    return SBFile(m_opaque_sp->GetErrorFileSP());
   return SBFile();
 }
 
@@ -573,8 +573,8 @@ void SBDebugger::HandleCommand(const char *command) {
 
     sb_interpreter.HandleCommand(command, result, false);
 
-    result.PutError(m_opaque_sp->GetErrorStreamSP()->GetFileSP());
-    result.PutOutput(m_opaque_sp->GetOutputStreamSP()->GetFileSP());
+    result.PutError(m_opaque_sp->GetErrorFileSP());
+    result.PutOutput(m_opaque_sp->GetOutputFileSP());
 
     if (!m_opaque_sp->GetAsyncExecution()) {
       SBProcess process(GetCommandInterpreter().GetProcess());
diff --git a/lldb/source/Commands/CommandObjectGUI.cpp b/lldb/source/Commands/CommandObjectGUI.cpp
index b56e49b073b03..8630171bae9d1 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();
 
-  File &input = debugger.GetInputFile();
-  File &output = debugger.GetOutputFile();
-  if (input.GetStream() && output.GetStream() && input.GetIsRealTerminal() &&
-      input.GetIsInteractive()) {
+  FileSP input_sp = debugger.GetInputFileSP();
+  FileSP output_sp = debugger.GetOutputFileSP();
+  if (input_sp->GetStream() && output_sp->GetStream() &&
+      input_sp->GetIsRealTerminal() && input_sp->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 5fb2dfaab8de0..17efae189b05e 100644
--- a/lldb/source/Commands/CommandObjectLog.cpp
+++ b/lldb/source/Commands/CommandObjectLog.cpp
@@ -394,7 +394,8 @@ class CommandObjectLogDump : public CommandObjectParsed {
           (*file)->GetDescriptor(), /*shouldClose=*/true);
     } else {
       stream_up = std::make_unique<llvm::raw_fd_ostream>(
-          GetDebugger().GetOutputFile().GetDescriptor(), /*shouldClose=*/false);
+          GetDebugger().GetOutputFileSP()->GetDescriptor(),
+          /*shouldClose=*/false);
     }
 
     const std::string channel = std::string(args[0].ref());
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 18569e155b517..18cdec4e0af73 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -947,7 +947,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 (!GetOutputFile().GetIsTerminalWithColors())
+  if (!GetOutputFileSP()->GetIsTerminalWithColors())
     SetUseColor(false);
 
   if (Diagnostics::Enabled()) {
@@ -1678,7 +1678,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, GetOutputFile().GetDescriptor(),
+        CreateLogHandler(log_handler_kind, GetOutputFileSP()->GetDescriptor(),
                          /*should_close=*/false, buffer_size);
   } else {
     auto pos = m_stream_handlers.find(log_file);
@@ -2111,8 +2111,8 @@ 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.
-  File &file = GetOutputFile();
-  if (!file.GetIsInteractive() || !file.GetIsTerminalWithColors())
+  FileSP file_sp = GetOutputFileSP();
+  if (!file_sp->GetIsInteractive() || !file_sp->GetIsTerminalWithColors())
     return;
 
   StreamSP output = GetAsyncOutputStream();
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index acdec84a1689b..5346d5a2d162a 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -2837,8 +2837,8 @@ void CommandInterpreter::HandleCommandsFromFile(
   }
 
   if (flags & eHandleCommandFlagPrintResult) {
-    debugger.GetOutputFile().Printf("Executing commands in '%s'.\n",
-                                    cmd_file_path.c_str());
+    debugger.GetOutputFileSP()->Printf("Executing commands in '%s'.\n",
+                                       cmd_file_path.c_str());
   }
 
   // Used for inheriting the right settings when "command source" might
diff --git a/lldb/source/Interpreter/ScriptInterpreter.cpp b/lldb/source/Interpreter/ScriptInterpreter.cpp
index 8d10e5de01225..a392d5777a021 100644
--- a/lldb/source/Interpreter/ScriptInterpreter.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreter.cpp
@@ -245,8 +245,8 @@ ScriptInterpreterIORedirect::ScriptInterpreterIORedirect(
       if (outfile_handle)
         ::setbuf(outfile_handle, nullptr);
 
-      result->SetImmediateOutputFile(debugger.GetOutputStreamSP()->GetFileSP());
-      result->SetImmediateErrorFile(debugger.GetErrorStreamSP()->GetFileSP());
+      result->SetImmediateOutputFile(debugger.GetOutputFileSP());
+      result->SetImmediateErrorFile(debugger.GetErrorFileSP());
     }
   }
 
diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index cff44b588e26e..1d4cda6c046b7 100644
--- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -1193,7 +1193,7 @@ bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
           m_kext_summary_header.version = data.GetU32(&offset);
           if (m_kext_summary_header.version > 128) {
             lldb::StreamSP s =
-                m_process->GetTarget().GetDebugger().GetOutputStreamSP();
+                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);
@@ -1208,7 +1208,7 @@ bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
               // If we get an improbably large entry_size, we're probably
               // getting bad memory.
               lldb::StreamSP s =
-                  m_process->GetTarget().GetDebugger().GetOutputStreamSP();
+                  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);
@@ -1226,7 +1226,7 @@ bool DynamicLoaderDarwinKernel::ReadKextSummaryHeader() {
             // If we get an improbably large number of kexts, we're probably
             // getting bad memory.
             lldb::StreamSP s =
-                m_process->GetTarget().GetDebugger().GetOutputStreamSP();
+                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);
@@ -1330,7 +1330,8 @@ bool DynamicLoaderDarwinKernel::ParseKextSummaries(
       number_of_old_kexts_being_removed == 0)
     return true;
 
-  lldb::StreamSP s = m_process->GetTarget().GetDebugger().GetOutputStreamSP();
+  lldb::StreamSP s =
+      m_process->GetTarget().GetDebugger().GetAsyncOutputStream();
   if (load_kexts) {
     if (number_of_new_kexts_being_added > 0 &&
         number_of_old_kexts_being_removed > 0) {
diff --git a/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp b/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
index 8c2700cf21de9..c2db3540a797b 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
+++ b/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp
@@ -116,8 +116,6 @@ 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 74e0fa7d49f82..d61c59776eee6 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp
+++ b/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp
@@ -210,8 +210,8 @@ bool ReportRetriever::NotifyBreakpointHit(ProcessSP process_sp,
         InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData(
             *thread_sp, description, report));
 
-  if (StreamFileSP stream_sp = StreamFileSP(
-          process_sp->GetTarget().GetDebugger().GetOutputStreamSP()))
+  if (StreamSP stream_sp =
+          process_sp->GetTarget().GetDebugger().GetAsyncOutputStream())
     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/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
index 7e8eee9f5aa4f..6d028e324ee4e 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
@@ -45,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.GetOutputFile().GetStream(),
-        debugger.GetErrorFile().GetStream()));
+        debugger.GetOutputFileSP()->GetStream(),
+        debugger.GetErrorFileSP()->GetStream()));
     llvm::cantFail(m_script_interpreter.EnterSession(debugger.GetID()));
   }
 
diff --git a/lldb/source/Target/ThreadPlanTracer.cpp b/lldb/source/Target/ThreadPlanTracer.cpp
index a119bf8589279..ab63cc7f6c223 100644
--- a/lldb/source/Target/ThreadPlanTracer.cpp
+++ b/lldb/source/Target/ThreadPlanTracer.cpp
@@ -27,6 +27,7 @@
 #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;
@@ -41,13 +42,13 @@ ThreadPlanTracer::ThreadPlanTracer(Thread &thread)
     : m_process(*thread.GetProcess().get()), m_tid(thread.GetID()),
       m_enabled(false), m_stream_sp(), m_thread(nullptr) {}
 
-Stream *ThreadPlanTracer::GetLogStream() {
+StreamSP ThreadPlanTracer::GetLogStreamSP() {
   if (m_stream_sp)
-    return m_stream_sp.get();
+    return m_stream_sp;
   else {
     TargetSP target_sp(GetThread().CalculateTarget());
     if (target_sp)
-      return target_sp->GetDebugger().GetOutputStreamSP().get();
+      return target_sp->GetDebugger().GetAsyncOutputStream();
   }
   return nullptr;
 }
@@ -65,12 +66,11 @@ void ThreadPlanTracer::Log() {
   bool show_frame_index = false;
   bool show_fullpaths = false;
 
-  Stream *stream = GetLogStream();
-  if (stream) {
-    GetThread().GetStackFrameAtIndex(0)->Dump(stream, show_frame_index,
+  if (StreamSP stream_sp = GetLogStreamSP()) {
+    GetThread().GetStackFrameAtIndex(0)->Dump(stream_sp.get(), show_frame_index,
                                               show_fullpaths);
-    stream->Printf("\n");
-    stream->Flush();
+    stream_sp->Printf("\n");
+    stream_sp->Flush();
   }
 }
 
@@ -129,9 +129,9 @@ void ThreadPlanAssemblyTracer::TracingStarted() {
 void ThreadPlanAssemblyTracer::TracingEnded() { m_register_values.clear(); }
 
 void ThreadPlanAssemblyTracer::Log() {
-  Stream *stream = GetLogStream();
+  StreamSP stream_sp = GetLogStreamSP();
 
-  if (!stream)
+  if (!stream_sp)
     return;
 
   RegisterContext *reg_ctx = GetThread().GetRegisterContext().get();
@@ -142,9 +142,10 @@ void ThreadPlanAssemblyTracer::Log() {
   uint8_t buffer[16] = {0}; // Must be big enough for any single instruction
   addr_valid = m_process.GetTarget().ResolveLoadAddress(pc, pc_addr);
 
-  pc_addr.Dump(stream, &GetThread(), Address::DumpStyleResolvedDescription,
+  pc_addr.Dump(stream_sp.get(), &GetThread(),
+               Address::DumpStyleResolvedDescription,
                Address::DumpStyleModuleWithFileAddress);
-  stream->PutCString(" ");
+  stream_sp->PutCString(" ");
 
   Disassembler *disassembler = GetDisassembler();
   if (disassembler) {
@@ -175,7 +176,7 @@ void ThreadPlanAssemblyTracer::Log() {
             instruction_list.GetInstructionAtIndex(0).get();
         const FormatEntity::Entry *disassemble_format =
             m_process.GetTarget().GetDebugger().GetDisassemblyFormat();
-        instruction->Dump(stream, max_opcode_byte_size, show_address,
+        instruction->Dump(stream_sp.get(), max_opcode_byte_size, show_address,
                           show_bytes, show_control_flow_kind, nullptr, nullptr,
                           nullptr, disassemble_format, 0);
       }
@@ -198,12 +199,12 @@ void ThreadPlanAssemblyTracer::Log() {
 
     if (abi->GetArgumentValues(GetThread(), value_list)) {
       for (int arg_index = 0; arg_index < num_args; ++arg_index) {
-        stream->Printf(
+        stream_sp->Printf(
             "\n\targ[%d]=%llx", arg_index,
             value_list.GetValueAtIndex(arg_index)->GetScalar().ULongLong());
 
         if (arg_index + 1 < num_args)
-          stream->PutCString(", ");
+          stream_sp->PutCString(", ");
       }
     }
   }
@@ -222,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->PutCString("\n\t");
-          DumpRegisterValue(reg_value, *stream, *reg_info, true, false,
+          stream_sp->PutCString("\n\t");
+          DumpRegisterValue(reg_value, *stream_sp, *reg_info, true, false,
                             eFormatDefault);
         }
       }
       m_register_values[reg_num] = reg_value;
     }
   }
-  stream->EOL();
-  stream->Flush();
+  stream_sp->EOL();
+  stream_sp->Flush();
 }

Copy link
Collaborator

@labath labath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I am not saying that you have to do anything about this, but there are two things that caught my eye:

  • Debugger::GetOutputFileSP is now the biggest backdoor into our locking mechanism. In a way, it's even worse than GetOutputStreamSP, since it bypasses locking completely. And since it supports Printf I can totally see someone reaching for that without realizing the problem.
  • It would sure be nice if StreamAsync was more of an RAII thing. Like, at least stored in a unique pointer, and maybe even passed by value (if we can make it movable).

@@ -2837,8 +2837,8 @@ void CommandInterpreter::HandleCommandsFromFile(
}

if (flags & eHandleCommandFlagPrintResult) {
debugger.GetOutputFile().Printf("Executing commands in '%s'.\n",
cmd_file_path.c_str());
debugger.GetOutputFileSP()->Printf("Executing commands in '%s'.\n",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one of those suspicious calls.

@JDevlieghere
Copy link
Member Author

LGTM. I am not saying that you have to do anything about this, but there are two things that caught my eye:

  • Debugger::GetOutputFileSP is now the biggest backdoor into our locking mechanism. In a way, it's even worse than GetOutputStreamSP, since it bypasses locking completely. And since it supports Printf I can totally see someone reaching for that without realizing the problem.

Yup. I was thinking about this too, and we definitely need one of the two, at least for the SB API . My reasoning was that handing out the lockable stream potentially gives you this false sense of security. As we probably can't prevent handing out the OutputFileSP, we can make it really ugly and obvious that you shouldn't be using it?

  • It would sure be nice if StreamAsync was more of an RAII thing. Like, at least stored in a unique pointer, and maybe even passed by value (if we can make it movable).

Good idea!

@JDevlieghere JDevlieghere merged commit 65998ab into llvm:main Feb 19, 2025
9 checks passed
@JDevlieghere JDevlieghere deleted the make-stream-sp-protected branch February 19, 2025 16:31
JDevlieghere added a commit to swiftlang/llvm-project that referenced this pull request Mar 27, 2025
…7682)

This makes GetOutputStreamSP and GetErrorStreamSP protected members of
Debugger. Users who want to print to the debugger's stream should use
GetAsyncOutputStreamSP and GetAsyncErrorStreamSP instead and the few
remaining stragglers have been migrated.

(cherry picked from commit 65998ab)
JDevlieghere added a commit to swiftlang/llvm-project that referenced this pull request Mar 28, 2025
…7682)

This makes GetOutputStreamSP and GetErrorStreamSP protected members of
Debugger. Users who want to print to the debugger's stream should use
GetAsyncOutputStreamSP and GetAsyncErrorStreamSP instead and the few
remaining stragglers have been migrated.

(cherry picked from commit 65998ab)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants