win32-console-docs
win32-console-docs copied to clipboard
Test failures on 15063's non-legacy console
The test suite passes on 14393, with the legacy and non-legacy consoles. With 15063, it passes with the legacy console, but fails with the non-legacy console.
Here's my test run (with successes elided):
rprichard@duck15063 ~/proj/win32-console-docs/src
$ ./build/HandleTests.exe
Using CREATE_NEW_CONSOLE as default creation mode
...
Test_Console_Without_Processes
HandleTests/Modern.cc:127: ERROR: check failed (windowText(hwnd) != title): != Test_Console_Without_Processes-6276-131397375107502604-57
Test_Implicit_Buffer_Reference
HandleTests/Modern.cc:173: ERROR: check failed (activeFirstChar(p) != 'A'): 66 != A
...
Test_Active_ScreenBuffer_Order
HandleTests/MiscTests.cc:171: ERROR: check failed (firstChar(p) != 'a'): 98 != a
HandleTests/MiscTests.cc:183: ERROR: check failed (firstChar(p) != 'a'): 99 != a
...
Using CREATE_NO_WINDOW as default creation mode
...
Test_Console_Without_Processes
HandleTests/Modern.cc:127: ERROR: check failed (windowText(hwnd) != title): != Test_Console_Without_Processes-6276-131397375107502604-304
Test_Implicit_Buffer_Reference
HandleTests/Modern.cc:173: ERROR: check failed (activeFirstChar(p) != 'A'): 66 != A
...
Test_Active_ScreenBuffer_Order
HandleTests/MiscTests.cc:171: ERROR: check failed (firstChar(p) != 'a'): 98 != a
HandleTests/MiscTests.cc:183: ERROR: check failed (firstChar(p) != 'a'): 99 != a
...
Failed tests:
Test_Active_ScreenBuffer_Order
Test_Console_Without_Processes
Test_Implicit_Buffer_Reference
I investigated the Test_Implicit_Buffer_Reference
failure and came up with this test case:
#include <windows.h>
int main() {
const HANDLE buf = CreateConsoleScreenBuffer(
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(buf);
const HANDLE buf2 = CreateFileW(L"CONOUT$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING, 0, NULL);
CloseHandle(buf2);
}
This test program creates a new buffer, activates it, opens and closes CONOUT$
, then exits. It does not restore the originally active screen buffer. Normally, Windows would restore the original buffer, but as of 15063's non-legacy console, it doesn't. If I run this test program from cmd.exe
or powershell.exe
, I'm left with a console where I can still issue commands, but much of the output is hidden. (Everything is hidden with PowerShell, but with cmd.exe, I can only see what I'm typing. I can't see dir
, but I can see a child process' output.)
According to my analysis of the console API, the reference count of the new buffer (buf
) is supposed to be 1 initially, increase to 2 after opening CONOUT$, drop back to 1 after CloseHandle
is called, then drop to 0 when the program exits.
My first instinct is to suspect a reference leak from opening CONOUT$
, but I'm going to look at the other test failures first. Maybe Test_Console_Without_Processes
will be interesting.
It turns out that CONOUT$
isn't that important to this issue -- creating either a \Device\ConDrv\Output
or a \Device\ConDrv\CurrentOut
object is sufficient to leak the screen buffer.