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); _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
