win32-console-docs icon indicating copy to clipboard operation
win32-console-docs copied to clipboard

Test failures on 15063's non-legacy console

Open rprichard opened this issue 7 years ago • 2 comments

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

rprichard avatar May 20 '17 07:05 rprichard

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.

rprichard avatar May 20 '17 07:05 rprichard

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.

rprichard avatar May 21 '17 00:05 rprichard