https://github.com/JDevlieghere updated 
https://github.com/llvm/llvm-project/pull/171733

>From cb83cdce863b25bf7eda68889cc772e1cfda8ad8 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <[email protected]>
Date: Wed, 10 Dec 2025 15:03:42 -0800
Subject: [PATCH 1/2] [lldb] Correct use_editline check in IOHandlerEditline

Correct the use_editline check in IOHandlerEditline to prevent a crash
when we have an output and/or error file, but no stream. This fixes a
regression introduced by 58279d1 that results in a crash when calling
el_init with a NULL stream.

The original code was checking the stream: GetOutputFILE and
GetErrorFILE.

```
use_editline = GetInputFILE() && GetOutputFILE() && GetErrorFILE() &&
                 m_input_sp && m_input_sp->GetIsRealTerminal();
```

The new code is checking the file: `m_output_sp` and `m_error_sp`.

```
use_editline = m_input_sp && m_output_sp && m_error_sp &&
                            m_input_sp->GetIsRealTerminal();
```
The correct check is:

```
use_editline =
      m_input_sp && m_input_sp->GetIsRealTerminal() &&
      m_output_sp && m_output_sp->GetUnlockedFile().GetStream() &&
      m_error_sp && m_error_sp->GetUnlockedFile().GetStream();
```

We don't need to update the check for the input, because we're handling
the missing stream there correctly in the call to the constructor:

```
    m_editline_up = std::make_unique<Editline>(
        editline_name, m_input_sp ? m_input_sp->GetStream() : nullptr,
        m_output_sp, m_error_sp, m_color);
```

We can't do the same for the output and error because we need to pass
the file, not the stream (to do proper locking).

As I was debugging this I added some more assertions. They're generally
useful so I'm keeping them.

Fixes #170891
---
 lldb/include/lldb/Host/StreamFile.h  | 5 ++++-
 lldb/source/Core/IOHandler.cpp       | 6 ++++--
 lldb/source/Host/common/Editline.cpp | 3 ++-
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/lldb/include/lldb/Host/StreamFile.h 
b/lldb/include/lldb/Host/StreamFile.h
index 8b01eeab6f586..172a9a29bf491 100644
--- a/lldb/include/lldb/Host/StreamFile.h
+++ b/lldb/include/lldb/Host/StreamFile.h
@@ -92,7 +92,10 @@ class LockableStreamFile {
   /// Unsafe accessors to get the underlying File without a lock. Exists for
   /// legacy reasons.
   /// @{
-  File &GetUnlockedFile() { return *m_file_sp; }
+  File &GetUnlockedFile() {
+    assert(m_file_sp && "GetUnlockedFile requires a valid FileSP");
+    return *m_file_sp;
+  }
   std::shared_ptr<File> GetUnlockedFileSP() { return m_file_sp; }
   /// @}
 
diff --git a/lldb/source/Core/IOHandler.cpp b/lldb/source/Core/IOHandler.cpp
index c2530aa0d00c5..752390aeef659 100644
--- a/lldb/source/Core/IOHandler.cpp
+++ b/lldb/source/Core/IOHandler.cpp
@@ -245,8 +245,10 @@ 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();
+  const bool use_editline =
+      m_input_sp && m_input_sp->GetIsRealTerminal() &&             // Input
+      m_output_sp && m_output_sp->GetUnlockedFile().GetStream() && // Output
+      m_error_sp && m_error_sp->GetUnlockedFile().GetStream();     // Error
   if (use_editline) {
     m_editline_up = std::make_unique<Editline>(
         editline_name, m_input_sp ? m_input_sp->GetStream() : nullptr,
diff --git a/lldb/source/Host/common/Editline.cpp 
b/lldb/source/Host/common/Editline.cpp
index e2995b37429fd..39b0a649a7f60 100644
--- a/lldb/source/Host/common/Editline.cpp
+++ b/lldb/source/Host/common/Editline.cpp
@@ -1511,7 +1511,8 @@ Editline::Editline(const char *editline_name, FILE 
*input_file,
     : 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);
+  assert(output_stream_sp && output_stream_sp->GetUnlockedFile().GetStream());
+  assert(error_stream_sp && output_stream_sp->GetUnlockedFile().GetStream());
   // Get a shared history instance
   m_editor_name = (editline_name == nullptr) ? "lldb-tmp" : editline_name;
   m_history_sp = EditlineHistory::GetHistory(m_editor_name);

>From fe2d87e88f3634471a867d734a27c8110d6efbee Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <[email protected]>
Date: Thu, 11 Dec 2025 09:17:38 -0800
Subject: [PATCH 2/2] Address David's request for a comment

---
 lldb/source/Core/IOHandler.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lldb/source/Core/IOHandler.cpp b/lldb/source/Core/IOHandler.cpp
index 752390aeef659..5cc15ad2ed6ff 100644
--- a/lldb/source/Core/IOHandler.cpp
+++ b/lldb/source/Core/IOHandler.cpp
@@ -245,6 +245,9 @@ IOHandlerEditline::IOHandlerEditline(
   SetPrompt(prompt);
 
 #if LLDB_ENABLE_LIBEDIT
+  // To use Editline, we need an input, output, and error stream. Not all valid
+  // files will have a FILE* stream. Don't use Editline if the input is not a
+  // real terminal.
   const bool use_editline =
       m_input_sp && m_input_sp->GetIsRealTerminal() &&             // Input
       m_output_sp && m_output_sp->GetUnlockedFile().GetStream() && // Output

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to