[Lldb-commits] [lldb] [lldb][windows] do not use ConPTY in tests (PR #192657)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Apr 17 06:46:46 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Charles Zablit (charles-zablit)
<details>
<summary>Changes</summary>
This patch ensure lldb do not run tests with the ConPTY enabled by default. Instead, it introduces ConPTY specific tests.
ConPTY injects VT escape sequences into the output stream, which breaks tests that check for specific stdout/stderr content. Separating the ConPTY tests from other tests ensure proper separation regarding what each test is testing.
---
Full diff: https://github.com/llvm/llvm-project/pull/192657.diff
7 Files Affected:
- (modified) lldb/source/API/SBTarget.cpp (+3)
- (modified) lldb/source/Target/Target.cpp (+2-1)
- (modified) lldb/test/API/lit.cfg.py (+4)
- (added) lldb/test/API/windows/conpty/Makefile (+3)
- (added) lldb/test/API/windows/conpty/TestConPTY.py (+75)
- (added) lldb/test/API/windows/conpty/main.c (+22)
- (modified) lldb/test/Shell/lit.cfg.py (+6)
``````````diff
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/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;
+}
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/192657
More information about the lldb-commits
mailing list