Windows Terminal version
1.23.20211.0
Windows build number
10.0.19045.6937 and 10.0.26200.7840
Other Software
No response
Steps to reproduce
Input a 2-column wide character (e.g., "キ" / U+30AD) into a ConPTY instance configured with a screen width of 1 column.
Reproduction Code:
#include <windows.h>
#include <stdio.h>
#include <process.h>
#pragma comment(lib, "kernel32.lib")
// Thread function to drain ConPTY output
unsigned int __stdcall OutputThread(void* pParam) {
HANDLE hRead = (HANDLE)pParam;
char buffer[4096];
DWORD bytesRead;
while (ReadFile(hRead, buffer, sizeof(buffer), &bytesRead, NULL) && bytesRead > 0) {}
return 0;
}
int main() {
HRESULT hr = S_OK;
HANDLE hPipeInRead = NULL, hPipeInWrite = NULL;
HANDLE hPipeOutRead = NULL, hPipeOutWrite = NULL;
CreatePipe(&hPipeInRead, &hPipeInWrite, NULL, 0);
CreatePipe(&hPipeOutRead, &hPipeOutWrite, NULL, 0);
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, OutputThread, hPipeOutRead, 0, NULL);
HPCON hPC = NULL;
COORD consoleSize = { 1, 20 };
hr = CreatePseudoConsole(consoleSize, hPipeInRead, hPipeOutWrite, 0, &hPC);
if (FAILED(hr)) return (int)hr;
CloseHandle(hPipeInRead);
CloseHandle(hPipeOutWrite);
STARTUPINFOEXW si = { 0 };
si.StartupInfo.cb = sizeof(STARTUPINFOEXW);
SIZE_T attrListSize = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &attrListSize);
si.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attrListSize);
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attrListSize);
UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, hPC, sizeof(HPCON), NULL, NULL);
PROCESS_INFORMATION pi = { 0 };
wchar_t cmdLine[] = L"cmd.exe";
CreateProcessW(NULL, cmdLine, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &si.StartupInfo, &pi);
const char* inputChar = "\xe3\x82\xad"; // "キ" in UTF-8
DWORD bytesWritten;
WriteFile(hPipeInWrite, inputChar, (DWORD)strlen(inputChar), &bytesWritten, NULL);
Sleep(500); // Give cmd.exe a moment to process before closing
ClosePseudoConsole(hPC);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(hPipeInWrite);
CloseHandle(hPipeOutRead);
HeapFree(GetProcessHeap(), 0, si.lpAttributeList);
printf("Execution finished cleanly.\n");
return 0;
}
This bug appears to be causing resource leaks in the Vim test suite.
vim/vim#19013
Expected Behavior
The process should close gracefully without hanging, even if the character cannot be displayed correctly in a 1-column space.
Actual Behavior
The behavior varies slightly depending on the OS version, but both result in a hang:
-
Windows 10 (10.0.19045.6937): ClosePseudoConsole() never returns. ConPTY continuously emits the string \r\n (CRLF + space), and EOF is never reached on the output pipe.
-
Windows 11 (10.0.26200.7840): ClosePseudoConsole() returns immediately (as it does not wait for the ConPTY process to terminate). However, the output pipe continues to receive the \r\n sequence indefinitely. Consequently, the output reading thread never terminates, causing the main process to hang at WaitForSingleObject(hThread, INFINITE).
The reason Vim experiences a conhost.exe leak (vim/vim#19013) instead of a hang is probably due to ClosePseudoConsole() returning immediately on Windows 11 24H2+, combined with Vim’s (unusual) logic of closing pipes prior to calling ClosePseudoConsole() when shutting down a terminal.
Windows Terminal version
1.23.20211.0
Windows build number
10.0.19045.6937 and 10.0.26200.7840
Other Software
No response
Steps to reproduce
Input a 2-column wide character (e.g., "キ" / U+30AD) into a ConPTY instance configured with a screen width of 1 column.
Reproduction Code:
This bug appears to be causing resource leaks in the Vim test suite.
vim/vim#19013
Expected Behavior
The process should close gracefully without hanging, even if the character cannot be displayed correctly in a 1-column space.
Actual Behavior
The behavior varies slightly depending on the OS version, but both result in a hang:
Windows 10 (10.0.19045.6937):
ClosePseudoConsole()never returns. ConPTY continuously emits the string\r\n(CRLF + space), and EOF is never reached on the output pipe.Windows 11 (10.0.26200.7840):
ClosePseudoConsole()returns immediately (as it does not wait for the ConPTY process to terminate). However, the output pipe continues to receive the\r\nsequence indefinitely. Consequently, the output reading thread never terminates, causing the main process to hang atWaitForSingleObject(hThread, INFINITE).The reason Vim experiences a
conhost.exeleak (vim/vim#19013) instead of a hang is probably due toClosePseudoConsole()returning immediately on Windows 11 24H2+, combined with Vim’s (unusual) logic of closing pipes prior to callingClosePseudoConsole()when shutting down a terminal.