[Lldb-commits] [lldb] c814ac1 - [lldb] Correct use_editline check in IOHandlerEditline (#171733)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Dec 11 09:24:13 PST 2025
Author: Jonas Devlieghere
Date: 2025-12-11T17:24:04Z
New Revision: c814ac1928b264a5bdeb98ec9035412fa37fb243
URL: https://github.com/llvm/llvm-project/commit/c814ac1928b264a5bdeb98ec9035412fa37fb243
DIFF: https://github.com/llvm/llvm-project/commit/c814ac1928b264a5bdeb98ec9035412fa37fb243.diff
LOG: [lldb] Correct use_editline check in IOHandlerEditline (#171733)
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
Added:
Modified:
lldb/include/lldb/Host/StreamFile.h
lldb/source/Core/IOHandler.cpp
lldb/source/Host/common/Editline.cpp
Removed:
################################################################################
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..5cc15ad2ed6ff 100644
--- a/lldb/source/Core/IOHandler.cpp
+++ b/lldb/source/Core/IOHandler.cpp
@@ -245,8 +245,13 @@ 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();
+ // 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
+ 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);
More information about the lldb-commits
mailing list