[Lldb-commits] [lldb] [lldb][windows] do not use ConPTY in tests (PR #192657)

Charles Zablit via lldb-commits lldb-commits at lists.llvm.org
Sat Apr 18 06:13:55 PDT 2026


https://github.com/charles-zablit updated https://github.com/llvm/llvm-project/pull/192657

>From 1f33a06fb39490ecedc4996c2e7974ed4ce885df Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Fri, 17 Apr 2026 14:39:42 +0100
Subject: [PATCH 1/5] [lldb][windows] implement ConPTY specific tests

---
 lldb/test/API/windows/conpty/Makefile      |  3 +
 lldb/test/API/windows/conpty/TestConPTY.py | 75 ++++++++++++++++++++++
 lldb/test/API/windows/conpty/main.c        | 22 +++++++
 3 files changed, 100 insertions(+)
 create mode 100644 lldb/test/API/windows/conpty/Makefile
 create mode 100644 lldb/test/API/windows/conpty/TestConPTY.py
 create mode 100644 lldb/test/API/windows/conpty/main.c

diff --git a/lldb/test/API/windows/conpty/Makefile b/lldb/test/API/windows/conpty/Makefile
new file mode 100644
index 0000000000000..10495940055b6
--- /dev/null
+++ b/lldb/test/API/windows/conpty/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/windows/conpty/TestConPTY.py b/lldb/test/API/windows/conpty/TestConPTY.py
new file mode 100644
index 0000000000000..cee09fd59138a
--- /dev/null
+++ b/lldb/test/API/windows/conpty/TestConPTY.py
@@ -0,0 +1,75 @@
+"""
+Tests for Windows ConPTY (Pseudo Console) process I/O.
+
+These tests explicitly exercise the ConPTY path by clearing
+LLDB_LAUNCH_FLAG_USE_PIPES, which the test suite sets globally to avoid
+ConPTY VT-sequence pollution in unrelated tests.
+"""
+
+import os
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+# Must match main.c.
+_NUM_LINES = 500
+
+
+class ConPTYTestCase(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    def setUp(self):
+        TestBase.setUp(self)
+        # Clear LLDB_LAUNCH_FLAG_USE_PIPES so LLDB uses ConPTY instead of
+        # anonymous pipes. Restored in tearDown.
+        self._saved_pipes_flag = os.environ.pop("LLDB_LAUNCH_FLAG_USE_PIPES", None)
+
+    def tearDown(self):
+        if self._saved_pipes_flag is not None:
+            os.environ["LLDB_LAUNCH_FLAG_USE_PIPES"] = self._saved_pipes_flag
+        TestBase.tearDown(self)
+
+    def _run_to_exit(self, mode):
+        """Build, launch with *mode* as argv[1], run to exit, return stdout."""
+        self.build()
+        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
+        self.assertTrue(target, VALID_TARGET)
+
+        process = target.LaunchSimple(
+            [mode], None, self.get_process_working_directory()
+        )
+        self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
+
+        self.assertState(process.GetState(), lldb.eStateExited)
+
+        return process.GetSTDOUT(1 << 20)
+
+    @skipUnlessWindows
+    def test_stdout_delivery(self):
+        """ConPTY delivers the inferior's stdout to LLDB."""
+        output = self._run_to_exit("basic")
+        self.assertEqual("Hello from ConPTY\r\n", output)
+
+    @skipUnlessWindows
+    def test_vt_init_stripped(self):
+        """ConPTY VT initialization sequences are stripped from GetSTDOUT."""
+        # Sequences emitted by conhost.exe at attach time, defined in
+        # ConnectionConPTYWindows.cpp :: StripConPTYInitSequences.
+        VT_INIT = "\x1b[?9001l\x1b[?1004l"
+
+        output = self._run_to_exit("basic")
+
+        self.assertIn("Hello from ConPTY\r\n", output)
+        self.assertNotIn(VT_INIT, output)
+
+    @skipUnlessWindows
+    def test_large_output(self):
+        """ConPTY delivers all output lines when output spans multiple reads."""
+        output = self._run_to_exit("large")
+        output_lines = output.split("\r\n")[:-1]
+
+        self.assertEqual(_NUM_LINES, len(output_lines), "Got fewer lines than expected.")
+
+        for i, line in enumerate(output_lines):
+            self.assertEqual("line %04d" % i, line)
diff --git a/lldb/test/API/windows/conpty/main.c b/lldb/test/API/windows/conpty/main.c
new file mode 100644
index 0000000000000..40ac96dc307a8
--- /dev/null
+++ b/lldb/test/API/windows/conpty/main.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// Mode "basic"  : print a single well-known line then exit.
+// Mode "large"  : print NUM_LINES numbered lines then exit; used to verify
+//                 that multi-chunk reads over the ConPTY pipe lose no data.
+
+#define NUM_LINES 500
+
+int main(int argc, char *argv[]) {
+    if (strcmp(argv[1], "basic") == 0) {
+        printf("Hello from ConPTY\n");
+        fflush(stdout);
+    } else if (strcmp(argv[1], "large") == 0) {
+        for (int i = 0; i < NUM_LINES; i++)
+            printf("line %04d\n", i);
+        fflush(stdout);
+    }
+
+    return 0;
+}

>From 70d985628a301c041affe48fe7810d5c832eb5a4 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Fri, 17 Apr 2026 14:43:21 +0100
Subject: [PATCH 2/5] [lldb][windows] do not use ConPTY in tests

---
 lldb/source/API/SBTarget.cpp  | 3 +++
 lldb/source/Target/Target.cpp | 3 ++-
 lldb/test/API/lit.cfg.py      | 4 ++++
 lldb/test/Shell/lit.cfg.py    | 6 ++++++
 4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index fd35208196781..a3b500f9011c3 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -334,6 +334,9 @@ SBProcess SBTarget::Launch(SBListener &listener, char const **argv,
     if (getenv("LLDB_LAUNCH_FLAG_DISABLE_ASLR"))
       launch_flags |= eLaunchFlagDisableASLR;
 
+    if (getenv("LLDB_LAUNCH_FLAG_USE_PIPES"))
+      launch_flags |= eLaunchFlagUsePipes;
+
     StateType state = eStateInvalid;
     process_sp = target_sp->GetProcessSP();
     if (process_sp) {
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index cad86bf956e38..518f0b46291e0 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -3871,7 +3871,8 @@ void Target::FinalizeFileActions(ProcessLaunchInfo &info) {
 
       if (default_to_use_pty) {
 #ifdef _WIN32
-        if (info.GetFlags().Test(eLaunchFlagUsePipes)) {
+        if (info.GetFlags().Test(eLaunchFlagUsePipes) ||
+            ::getenv("LLDB_LAUNCH_FLAG_USE_PIPES")) {
           llvm::Error Err = info.SetUpPipeRedirection();
           LLDB_LOG_ERROR(log, std::move(Err),
                          "SetUpPipeRedirection failed: {0}");
diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py
index e532b717110fd..c92b104c9227c 100644
--- a/lldb/test/API/lit.cfg.py
+++ b/lldb/test/API/lit.cfg.py
@@ -357,6 +357,10 @@ def delete_module_cache(path):
     for v in ["SystemDrive"]:
         if v in os.environ:
             config.environment[v] = os.environ[v]
+    # Use anonymous pipes instead of ConPTY for all tests. ConPTY injects VT
+    # escape sequences into the output stream, which breaks tests that check
+    # for specific stdout/stderr content.
+    dotest_cmd += ["--env", "LLDB_LAUNCH_FLAG_USE_PIPES=1"]
 
 # Some steps required to initialize the tests dynamically link with python.dll
 # and need to know the location of the Python libraries. This ensures that we
diff --git a/lldb/test/Shell/lit.cfg.py b/lldb/test/Shell/lit.cfg.py
index 8d28f2d5201b3..64107001e3aae 100644
--- a/lldb/test/Shell/lit.cfg.py
+++ b/lldb/test/Shell/lit.cfg.py
@@ -176,6 +176,12 @@ def calculate_arch_features(arch_string):
 if config.have_dia_sdk:
     config.available_features.add("diasdk")
 
+if platform.system() == "Windows":
+    # Use anonymous pipes instead of ConPTY for all tests. ConPTY injects VT
+    # escape sequences into the output stream, which breaks tests that check
+    # for specific stdout/stderr content.
+    config.environment["LLDB_LAUNCH_FLAG_USE_PIPES"] = "1"
+
 # NetBSD permits setting dbregs either if one is root
 # or if user_set_dbregs is enabled
 can_set_dbregs = True

>From 773d07911d86c97b125562a414cd346f8b72fac9 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Fri, 17 Apr 2026 14:49:32 +0100
Subject: [PATCH 3/5] fixup! [lldb][windows] do not use ConPTY in tests

---
 lldb/test/API/windows/conpty/main.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lldb/test/API/windows/conpty/main.c b/lldb/test/API/windows/conpty/main.c
index 40ac96dc307a8..c38c860670124 100644
--- a/lldb/test/API/windows/conpty/main.c
+++ b/lldb/test/API/windows/conpty/main.c
@@ -9,14 +9,14 @@
 #define NUM_LINES 500
 
 int main(int argc, char *argv[]) {
-    if (strcmp(argv[1], "basic") == 0) {
-        printf("Hello from ConPTY\n");
-        fflush(stdout);
-    } else if (strcmp(argv[1], "large") == 0) {
-        for (int i = 0; i < NUM_LINES; i++)
-            printf("line %04d\n", i);
-        fflush(stdout);
-    }
+  if (strcmp(argv[1], "basic") == 0) {
+    printf("Hello from ConPTY\n");
+    fflush(stdout);
+  } else if (strcmp(argv[1], "large") == 0) {
+    for (int i = 0; i < NUM_LINES; i++)
+      printf("line %04d\n", i);
+    fflush(stdout);
+  }
 
-    return 0;
+  return 0;
 }

>From 7844670f756e59cf5373b6a008acfd6254bb87e1 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Fri, 17 Apr 2026 15:06:14 +0100
Subject: [PATCH 4/5] fixup! [lldb][windows] do not use ConPTY in tests

---
 lldb/test/API/windows/conpty/TestConPTY.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lldb/test/API/windows/conpty/TestConPTY.py b/lldb/test/API/windows/conpty/TestConPTY.py
index cee09fd59138a..a7a1944195d5a 100644
--- a/lldb/test/API/windows/conpty/TestConPTY.py
+++ b/lldb/test/API/windows/conpty/TestConPTY.py
@@ -69,7 +69,9 @@ def test_large_output(self):
         output = self._run_to_exit("large")
         output_lines = output.split("\r\n")[:-1]
 
-        self.assertEqual(_NUM_LINES, len(output_lines), "Got fewer lines than expected.")
+        self.assertEqual(
+            _NUM_LINES, len(output_lines), "Got fewer lines than expected."
+        )
 
         for i, line in enumerate(output_lines):
             self.assertEqual("line %04d" % i, line)

>From d08dbfa45bdf0ad91c044ccb777a7a16eb3d75f7 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Sat, 18 Apr 2026 15:13:37 +0200
Subject: [PATCH 5/5] force sync mode

---
 lldb/test/API/windows/conpty/TestConPTY.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lldb/test/API/windows/conpty/TestConPTY.py b/lldb/test/API/windows/conpty/TestConPTY.py
index a7a1944195d5a..cfed6d4691631 100644
--- a/lldb/test/API/windows/conpty/TestConPTY.py
+++ b/lldb/test/API/windows/conpty/TestConPTY.py
@@ -36,6 +36,8 @@ def _run_to_exit(self, mode):
         target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
         self.assertTrue(target, VALID_TARGET)
 
+        self.dbg.SetAsync(False)
+
         process = target.LaunchSimple(
             [mode], None, self.get_process_working_directory()
         )



More information about the lldb-commits mailing list