Skip to content

🍒 [lldb][windows] add Windows Virtual Console support#12621

Open
charles-zablit wants to merge 28 commits intoswiftlang:stable/21.xfrom
charles-zablit:cz/lldb/windows/conpty-to-stable
Open

🍒 [lldb][windows] add Windows Virtual Console support#12621
charles-zablit wants to merge 28 commits intoswiftlang:stable/21.xfrom
charles-zablit:cz/lldb/windows/conpty-to-stable

Conversation

@charles-zablit
Copy link
Copy Markdown

@charles-zablit charles-zablit commented Mar 19, 2026

rdar://168587474

@charles-zablit charles-zablit requested a review from a team as a code owner March 19, 2026 12:48
@charles-zablit charles-zablit changed the title 🍒 [lldb][windows] add Windows Virtual Console support ( 🍒 [lldb][windows] add Windows Virtual Console support Mar 19, 2026
@charles-zablit charles-zablit force-pushed the cz/lldb/windows/conpty-to-stable branch 2 times, most recently from acbad78 to f55fd5f Compare March 19, 2026 12:59
@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test

@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test macos

@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test windows

@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please smoke test Windows

@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test windows

2 similar comments
@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test windows

@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test windows

@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test windows

@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test

1 similar comment
@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test

@charles-zablit charles-zablit force-pushed the cz/lldb/windows/conpty-to-stable branch from 8ba03b2 to ed52961 Compare April 1, 2026 16:18
@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test

charles-zablit and others added 13 commits April 2, 2026 16:25
…lvm#177934)

This patch ensures lldb will not try to read from a PseudoConsole if it
has not been opened.

llvm#168729 introduces support for
the Windows ConPTY in `lldb-dap`. This caused a regression in `lldb`
which was not caught by our tests:
llvm#175652.

This patch fixes llvm#175652.

`lldb_private::ProcessLauncherWindows::LaunchProcess` connects the
debuggee to a PseudoConsole only if:
```cpp
if (hPC != INVALID_HANDLE_VALUE && launch_info.GetNumFileActions() == 0 && launch_info.GetFlags().Test(lldb::eLaunchFlagLaunchInTTY))
```

lldb needs to check the same condition in
`lldb_private::PlatformWindows::DebugProcess` to ensure that it does not
read from a PseudoConsole which has not been opened.

This patch reverts what llvm#168729
did by adding ConPTY support.
llvm#175812 is the proper fix,
however it's causing tests failures which we can't reliably reproduce at
desk. Given llvm#168729 breaks
`22.x` lldb, it's better to revert the change ahead of the release of
`22.x` rather than pushing for the proper fix.

(cherry picked from commit c4585b4)
…m#180565)

This NFC patch extracts the `UpdateProcThreadAttribute` logic to a
dedicated method be able to reuse it in
llvm#180561.

(cherry picked from commit 352932c)
…lvm#180579)

Remove an unneeded call to `DeleteProcThreadAttributeList`, which is
already done in the `ProcThreadAttributeList` destructor.

(cherry picked from commit be711a0)
Add a step to drain the init sequences emitted by the ConPTY before
attaching it to the debuggee.

A ConPTY (PseudoConsole) emits init sequences which flush the screen and
contain the name of the program (ESC[2J for clear screen, ESC[H for
cursor home and more). It's not desirable to filter them out: if a
debuggee also emits them, lldb would filter that output as well. To work
around this, the ConPTY is drained by attaching a dummy process to it,
consuming the init sequences and then attaching the actual debuggee.

---------

Co-authored-by: Nerixyz <nero.9@hotmail.de>
(cherry picked from commit d7e5a7d)
…lvm#181811)

When running multiple targets in lldb, the `ProcessLaunchInfo` instance
gets re-used. This is a problem for the ConPTY instance which is owned
by `launch_info` because, when creating a second target, we close and
reopen the `m_pty` of the first target.

This patch replaces the `GetPTYSP` method with `ReleasePTY`, which moves
the `std::shared_ptr` out of `launch_info` instead of creating a new
`std::shared_ptr`. The `m_pty` instance is moved into the target's
process. This way, each target's `Process` instance owns its PTY
instance and is responsible for closing it.

---------

Co-authored-by: Adrian Prantl <adrian.prantl@gmail.com>
(cherry picked from commit 71f49eb)
)

`DAPTestCaseBase.get_stdout()` was originally not supported on Windows
due to the lack of ConPTY support.
llvm#168729 fixed that by
implenenting the ConPTY support. It was partly reverted in
llvm#177610 due to hard to
reproduce test failures.

The tests are now fixed (see the 2 patches below) and removing the check
for `GetFlags().Test(lldb::eLaunchFlagLaunchInTTY);` is the last step to
re-enabling ConPTY support.

This patch requires:
- llvm#181811
- llvm#181809

Fixes llvm#137599.

rdar://168932366
(cherry picked from commit 6a365b0)
…vm#182109)

This patch mitigates a race condition when closing the ConPTY of a
process on Windows.

This is a temporary solution, I am working on a better one. This would
however unlock the
[lldb-aarch64-windows](https://lab.llvm.org/buildbot/#/builders/141/builds/15535)
bot while still keeping STDIN and STDOUT support in lldb.

The race condition happens because the ConPTY is closed when a process
exits, however the data was not fully received yet from the process.
I think the correct solution would be to close the ConPTY when we
receive the EOF in `ConnectionGenericFile::Read`.

(cherry picked from commit e7266ad)
…ile (llvm#182536)

If a read is interrupted in `ConnectionGenericFile::Read`, the data that
has already been read by `ReadFile` is lost.

This patch adds `m_read_pending` to mark a read as interrupted. The next
read will pick up the results of the previous read and return the number
of `bytes_read`.

(cherry picked from commit ef20b6a)
…2302)

This patch fixes a race condition when closing the ConPTY of a process
on Windows.

The read operation in `ConnectionGenericFile::Read` is asynchronous
because the ConPTY does not work with synchronous reads. However, this
is prone to a race condition if the ConPTY is closed between the
`ReadFile` and the `WaitForMultipleObjects`. This eventually leads to
the data being truncated, i.e some of the STDOUT is missing.

The fix is to introduce a mutex which prevents the ConPTY from closing
while a Read loop is in progress.

At the end of the pipe, `WaitForMultipleObjects` hangs until it receives
a `ERROR_BROKEN_PIPE` event, which is signaled when closing the ConPTY.
It's important to close the Read thread before closing the ConPTY,
otherwise the thread deadlocks waiting for the `ERROR_BROKEN_PIPE` which
is never sent because the ConPTY is waiting for the thread to exit
before closing.

All of this logic is encapsulated in the `ConnectionConPTY` class which
is a subclass of `ConnectionGenericFile`. `ConnectionConPTY` only
supports reading from the ConPTY. To write to it,
`IOHandlerProcessSTDIOWindows` should be used instead.

This patch depends on:
- llvm#182536

This patch replaces llvm#182109.

---------

Co-authored-by: Nerixyz <nero.9@hotmail.de>
(cherry picked from commit 796a1ea)
This patch fixes the `(lldb)` prompt being overwriten by the cursor
position movements the ConPTY emits.

To be a complete solution we should also add a resize hook for the
console's window.

I also think that we should look into injecting conpty VT sequences
before printing the `(lldb)` prompt.
For instance, if we break on a breakpoint and the pty added a "hide
cursor" VT sequence, we should emit a `show cursor` sequence before
printing `(lldb)`. This should be done outside of this PR however.

(cherry picked from commit 214246e)
In some environments like swiftlang, the `''` causes the command used to
drain the init sequence of the ConPTY to fail. Replacing with a `cls`
invocation removes the need for quotation marks and works just as well.

(cherry picked from commit 29c083a)
@charles-zablit charles-zablit force-pushed the cz/lldb/windows/conpty-to-stable branch from ed52961 to 7ae6747 Compare April 2, 2026 15:27
@charles-zablit charles-zablit self-assigned this Apr 2, 2026
@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test windows

2 similar comments
@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test windows

@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test windows

@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test Windows

@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test windows

@charles-zablit charles-zablit force-pushed the cz/lldb/windows/conpty-to-stable branch from 2babb41 to 19cac12 Compare April 8, 2026 17:00
@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test windows

@charles-zablit charles-zablit force-pushed the cz/lldb/windows/conpty-to-stable branch from 19cac12 to 9efcb34 Compare April 8, 2026 17:57
@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test windows

1 similar comment
@charles-zablit
Copy link
Copy Markdown
Author

@swift-ci please test windows

@charles-zablit charles-zablit force-pushed the cz/lldb/windows/conpty-to-stable branch from 9efcb34 to d445828 Compare April 9, 2026 10:23
@charles-zablit
Copy link
Copy Markdown
Author

Please test with following PR:
swiftlang/swift#88379

@swift-ci Please test Windows platform

2 similar comments
@charles-zablit
Copy link
Copy Markdown
Author

Please test with following PR:
swiftlang/swift#88379

@swift-ci Please test Windows platform

@charles-zablit
Copy link
Copy Markdown
Author

Please test with following PR:
swiftlang/swift#88379

@swift-ci Please test Windows platform

@charles-zablit
Copy link
Copy Markdown
Author

Please test with following PR:
swiftlang/swift#88379

@swift-ci Please test Windows platform

1 similar comment
@charles-zablit
Copy link
Copy Markdown
Author

Please test with following PR:
swiftlang/swift#88379

@swift-ci Please test Windows platform

@charles-zablit
Copy link
Copy Markdown
Author

Please test with following PR:
swiftlang/swift#88379

@swift-ci Please test Windows platform

…m#186472)

In `internalConsole` mode (especially in VSCode), lldb-dap should not
use the ConPTY to read the process' output. This is because the
internalConsole is not a real terminal, there is no reason to use
terminal emulation, which will add arbitrary line returns to the output.

Instead, this patch introduces the `eLaunchFlagUsePipes` flag in
ProcessLaunchInfo which tells ProcessLaunchWindows to use regular pipes
instead of a ConPTY to get the stdin and stdout of the debuggee.

The result is that output which is supposed to be on a single line is
properly rendered.

---

The following example is when debugging a program through lldb-dap on
Windows. The program prints the numbers 0 through 999 on a single line.

<img width="2214" height="672" alt="Screenshot 2026-03-13 at 17 07 35"
src="https://github.com/user-attachments/assets/26292d11-2288-46ee-a6d2-0b66bfa41288"
/>

The line is split if it's longer than 80 characters (default terminal
size).

<img width="2215" height="689" alt="Screenshot 2026-03-13 at 17 12 39"
src="https://github.com/user-attachments/assets/c9cad9af-b1ce-4c7b-91d5-f684e48e64ca"
/>

The line is correctly printed as a single line.

rdar://172491166
(cherry picked from commit 87085a8)
@charles-zablit
Copy link
Copy Markdown
Author

Please test with following PR:
swiftlang/swift#88379

@swift-ci Please test Windows platform

@charles-zablit
Copy link
Copy Markdown
Author

Please test with following PR:
swiftlang/swift#88379

@swift-ci Please test Windows platform

@charles-zablit charles-zablit force-pushed the cz/lldb/windows/conpty-to-stable branch from ba3087e to 292ca4d Compare April 10, 2026 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants