Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

winpty-agent.exe hangs on Windows 10 upon terminal resize #31

Closed
aleherb opened this issue Aug 4, 2015 · 7 comments
Closed

winpty-agent.exe hangs on Windows 10 upon terminal resize #31

aleherb opened this issue Aug 4, 2015 · 7 comments

Comments

@aleherb
Copy link

aleherb commented Aug 4, 2015

E.g. within mintty, execute

console.exe cmd

then resize the terminal window -> winpty-agent.exe hangs in

(gdb) bt
#0 0x77c28c3c in ntdll!ZwDeviceIoControlFile () from C:\Windows\SYSTEM32\ntdll.dll
#1 0x76e8c8e9 in KERNELBASE!GetConsoleMode () from C:\Windows\SYSTEM32\KernelBase.dll
#2 0x76e8c7fa in KERNELBASE!GetConsoleMode () from C:\Windows\SYSTEM32\KernelBase.dll
#3 0x76f03230 in SetConsoleScreenBufferSize () from C:\Windows\SYSTEM32\KernelBase.dll
#4 0x0040485c in Win32Console::resizeBuffer(Coord const&) ()
#5 0x00404a97 in Win32Console::reposition(Coord const&, SmallRect const&) ()
#6 0x004033b1 in Agent::resizeWindow(int, int) ()
#7 0x00402dff in Agent::handleSetSizePacket(ReadBuffer&) ()
#8 0x0040295d in Agent::handlePacket(ReadBuffer&) ()
#9 0x004028d1 in Agent::pollControlSocket() ()
#10 0x0040275c in Agent::onPipeIo(NamedPipe*) ()
#11 0x0040154a in EventLoop::run() ()
#12 0x004064e6 in main () 

Workaround: Enable legacy console in cmd > Properties.

The following patch seems to prevent the hang:

diff --git a/agent/Agent.cc b/agent/Agent.cc
index 5983ab9..52c5c4b 100644
--- a/agent/Agent.cc
+++ b/agent/Agent.cc
@@ -392,8 +392,8 @@ void Agent::resizeWindow(int cols, int rows)
         markEntireWindowDirty();
     m_dirtyWindowTop = newWindowRect.top();

-    m_console->reposition(newBufferSize, newWindowRect);
     unfreezeConsole();
+    m_console->reposition(newBufferSize, newWindowRect);
 }

 void Agent::scrapeOutput()
@trofimander
Copy link

Confirm: that fixes the hang on Windows 10.

@leycec
Copy link

leycec commented Aug 13, 2015

Could someone post that as a pull request? Pleaaaase.

aleherb pushed a commit to aleherb/winpty that referenced this issue Aug 13, 2015
@rprichard
Copy link
Owner

I think I understand what's happening. The new Windows 10 console rewraps the console lines when the console is resized. When the console is "frozen" (i.e. the "Select All" system command is active), writes to the console block. Presumably, with Windows 10, attempts to resize the console also block.

I really need to test with Windows 10, though.

I'm wondering what happens if one of the console programs prints new lines before/during the Win32Console::reposition call.

I suspect Windows 10's line rewrapping is going to confuse winpty. Normally, winpty tries to detect changes and send only changed lines, but with rewrapping, I think it's going to lose track of what's new.

@aleherb
Copy link
Author

aleherb commented Aug 14, 2015

Presumably, with Windows 10, attempts to resize the console also block.

No, it doesn't, but the selection is cleared. This is different to a Windows 7 console.

I'm wondering what happens if one of the console programs prints new lines before/during the Win32Console::reposition call.

I wonder what freezing the console during the reposition should actually protect. Printing lines does not affect window or buffer size.

I suspect Windows 10's line rewrapping is going to confuse winpty.

The only bad impact I have seen so far is, that a resize confuses editing of the current input line in cmd.exe, in particular history navigation. It seems to work fine with e.g. bash (+readline).

@rprichard
Copy link
Owner

I tested programmatically resizing the console buffer while selection was in-progress, and it apparently hangs the Windows console, such that the conhost.exe process must be killed from the Task Manager. This actually seems like a Windows bug to me.

See https://github.com/rprichard/winpty/blob/win10/misc/Win10ResizeWhileFrozen.cc

@rprichard
Copy link
Owner

rprichard added a commit that referenced this issue Sep 30, 2015
…ing.

 * Unfreeze the console while changing the buffer size.  Changing the
   buffer size hangs conhost.exe.  See:
    - #31
    - https://wpdev.uservoice.com/forums/266908-command-prompt/suggestions/9941292-conhost-exe-hangs-in-win10-if-setconsolescreenbuff

 * Detect buffer size changes and switch to a "direct mode".  Direct mode
   makes no attempt to track incremental console changes.  Instead, the
   content of the current console window is printed.  This mode is
   intended for full-screen apps that resize the console.

 * Reopen CONOUT$, which detects apps that change the active screen buffer.
   Fixes #34.

 * In the scroll scraping (scrollingScrapeOutput), consider a line changed
   if the new content is truncated relative to the content previously
   output.  Previously, we only compared against the line-buffer up to the
   current console width.  e.g.

   If this:
      |C:\Program|

   turns into:
      |C:\Prog|
      |ram    |

   we previously left |C:\Program| in the line-buffer for the first line
   and did not re-output the first line.

   We *should* reoutput the first line at this point so that, if the line
   scrolls upward, and the terminal is later expanded, we will have
   output an "Erase in Line" CSI command to clear the obscured "ram" text.

   We need to update the line-buffer for the sake of Windows 10 combined
   with terminals like xterm and putty.  On such a terminal, if the
   terminal later widened, Windows 10 will restore the console to the
   first state.  At that point, we need to reoutput the line, because
   xterm and putty do not save and restore truncated line content extending
   past the current terminal width.
@rprichard
Copy link
Owner

Fixed by d464089. Unfortunately, conhost.exe can still hang if something other than winpty resizes the console.

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

No branches or pull requests

4 participants