[Lldb-commits] [lldb] f545a3b - [lldb] Make PTY initialization idempotent (#197717)

via lldb-commits lldb-commits at lists.llvm.org
Fri May 29 06:02:24 PDT 2026


Author: Charles Zablit
Date: 2026-05-29T14:02:19+01:00
New Revision: f545a3b3f558a29e2d7c2dc18748e8bedc3ce6c6

URL: https://github.com/llvm/llvm-project/commit/f545a3b3f558a29e2d7c2dc18748e8bedc3ce6c6
DIFF: https://github.com/llvm/llvm-project/commit/f545a3b3f558a29e2d7c2dc18748e8bedc3ce6c6.diff

LOG: [lldb] Make PTY initialization idempotent (#197717)

Added: 
    

Modified: 
    lldb/include/lldb/Host/PseudoTerminal.h
    lldb/include/lldb/Host/windows/PseudoConsole.h
    lldb/source/Host/common/PseudoTerminal.cpp
    lldb/source/Host/windows/PseudoConsole.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Host/PseudoTerminal.h b/lldb/include/lldb/Host/PseudoTerminal.h
index 245deec997d80..79475e9977b30 100644
--- a/lldb/include/lldb/Host/PseudoTerminal.h
+++ b/lldb/include/lldb/Host/PseudoTerminal.h
@@ -44,6 +44,11 @@ class PseudoTerminal {
   /// Close the secondary file descriptor if it is valid.
   void CloseSecondaryFileDescriptor();
 
+  /// Close both file descriptors and clear cached state. Used to recycle a
+  /// PseudoTerminal across multiple launches without invalidating any
+  /// outstanding shared_ptr references.
+  void Reset();
+
   /// Fork a child process that uses pseudo terminals for its stdio.
   ///
   /// In the parent process, a call to this function results in a pid being

diff  --git a/lldb/include/lldb/Host/windows/PseudoConsole.h b/lldb/include/lldb/Host/windows/PseudoConsole.h
index d2f6d80a88ef4..cf910354f1bca 100644
--- a/lldb/include/lldb/Host/windows/PseudoConsole.h
+++ b/lldb/include/lldb/Host/windows/PseudoConsole.h
@@ -69,6 +69,10 @@ class PseudoConsole {
   /// CreateProcessW to avoid keeping the pipes alive indefinitely.
   void CloseAnonymousPipes();
 
+  /// Closes any open ConPTY/pipe handles and resets internal state to a
+  /// freshly-constructed PseudoConsole.
+  void Reset();
+
   /// Returns whether the ConPTY and its pipes are currently open and valid.
   bool IsConnected() const;
 

diff  --git a/lldb/source/Host/common/PseudoTerminal.cpp b/lldb/source/Host/common/PseudoTerminal.cpp
index 53e91aff212a4..571ea34a27ead 100644
--- a/lldb/source/Host/common/PseudoTerminal.cpp
+++ b/lldb/source/Host/common/PseudoTerminal.cpp
@@ -38,10 +38,7 @@ PseudoTerminal::PseudoTerminal() = default;
 // are valid and ownership has not been released using the
 // ReleasePrimaryFileDescriptor() or the ReleaseSaveFileDescriptor() member
 // functions.
-PseudoTerminal::~PseudoTerminal() {
-  ClosePrimaryFileDescriptor();
-  CloseSecondaryFileDescriptor();
-}
+PseudoTerminal::~PseudoTerminal() { Reset(); }
 
 // Close the primary file descriptor if it is valid.
 void PseudoTerminal::ClosePrimaryFileDescriptor() {
@@ -59,7 +56,13 @@ void PseudoTerminal::CloseSecondaryFileDescriptor() {
   }
 }
 
+void PseudoTerminal::Reset() {
+  ClosePrimaryFileDescriptor();
+  CloseSecondaryFileDescriptor();
+}
+
 llvm::Error PseudoTerminal::OpenFirstAvailablePrimary(int oflag) {
+  Reset();
 #if LLDB_ENABLE_POSIX
   // Open the primary side of a pseudo terminal
   m_primary_fd = ::posix_openpt(oflag);

diff  --git a/lldb/source/Host/windows/PseudoConsole.cpp b/lldb/source/Host/windows/PseudoConsole.cpp
index 477fe36d64bb4..b404b2c19a6be 100644
--- a/lldb/source/Host/windows/PseudoConsole.cpp
+++ b/lldb/source/Host/windows/PseudoConsole.cpp
@@ -91,23 +91,14 @@ llvm::Error PseudoConsole::CreateOverlappedPipePair(HANDLE &out_read,
   return llvm::Error::success();
 }
 
-PseudoConsole::~PseudoConsole() {
-  Close();
-  ClosePseudoConsolePipes();
-  CloseAnonymousPipes();
-}
+PseudoConsole::~PseudoConsole() { Reset(); }
 
 llvm::Error PseudoConsole::OpenPseudoConsole() {
-  assert(m_mode == Mode::None &&
-         "Attempted to open a PseudoConsole in a 
diff erent mode than None");
+  Reset();
 
   if (!kernel32.IsConPTYAvailable())
     return llvm::make_error<llvm::StringError>("ConPTY is not available",
                                                llvm::errc::io_error);
-
-  assert(m_conpty_handle == INVALID_HANDLE_VALUE &&
-         "ConPTY has already been opened");
-
   // A 4096 bytes buffer should be large enough for the majority of console
   // burst outputs.
   wchar_t pipe_name[MAX_PATH];
@@ -215,9 +206,15 @@ void PseudoConsole::CloseAnonymousPipes() {
   m_pipe_child_stdout = INVALID_HANDLE_VALUE;
 }
 
+void PseudoConsole::Reset() {
+  Close();
+  ClosePseudoConsolePipes();
+  CloseAnonymousPipes();
+  m_mode = Mode::None;
+}
+
 llvm::Error PseudoConsole::OpenAnonymousPipes() {
-  assert(m_mode == Mode::None &&
-         "Attempted to open a AnonymousPipes in a 
diff erent mode than None");
+  Reset();
 
   SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE};
   HANDLE hStdinRead = INVALID_HANDLE_VALUE;


        


More information about the lldb-commits mailing list