mintty / wsltty

Mintty as a terminal for Bash on Ubuntu on Windows / WSL
Other
3.12k stars 104 forks source link

Exit 1 from wslbridge / terminal size not updated, if window is maximized before WSL starts #220

Closed Terrance closed 4 years ago

Terrance commented 4 years ago

Initially, I would launch wsltty, and quickly maximize the window (e.g. with Win-↑) when it appeared but before my shell starts (currently just measuring from when my .bashrc starts executing), at which point it would promptly exit:

/bin/wslbridge2: Exit 1.

Quickly dragging the corner to resize the window doesn't seem to cause it to exit. Once WSL has started up, I can maximize or restore the window going forward without issues.

As far as I can tell it's not a config issue, as starting with an empty config file also triggers it, though once I started faffing with the config it became trickier to reproduce consistently.

Now, when it does successfully open without exiting, the terminal size doesn't get updated, so launching e.g. tmux or vim only uses the first 120 cols / 40 rows, as defined in my config as the default window size. As before, maximizing after WSL initialises works fine, and subsequent resizes fix WSL's view of the terminal size going forward.

Could be another case of #73 -- I replaced my .bashrc with stty size on its own, and it also confirms my default window size 40 120 when I trigger an early maximize. Adding mintty's -w max option to the launch command does successfully maximize the window, and stty size then reports the correct size of 93 383.


Using v3.1.0.2 x64, though the wsltty build number disagrees, unless it's truncated?

mintty 3.1.0 (x86_64-pc-cygwin) – wsltty 3.1.0

Launching with the WSL Terminal shortcut:

C:\Users\User\AppData\Local\wsltty\bin\mintty.exe --WSL= --configdir="C:\Users\User\AppData\Roaming\wsltty" -~ -

Config file ``` Locale=en_GB Charset=UTF-8 Columns=120 Rows=40 PgUpDnScroll=no CursorType=block Font=Iosevka Term FontHeight=7 BoldAsFont=yes ForegroundColour=230,230,230 BackgroundColour=34,34,34 CursorColour=255,255,255 Black=83,83,83 Red=220,92,92 BoldRed=240,62,62 Green=165,194,97 BoldGreen=174,244,117 Yellow=255,228,109 BoldYellow=255,248,139 Blue=108,153,187 BoldBlue=118,193,247 Magenta=209,151,217 BoldMagenta=239,181,247 Cyan=160,224,255 BoldCyan=200,234,255 White=230,230,230 BoldWhite=255,255,255 AllowBlinking=yes Term=xterm-256color Answerback= BellType=2 BellSound=yes Hold=error Scrollbar=none Transparency=low OpaqueWhenFocused=yes FontSmoothing=full ClicksPlaceCursor=yes ClickTargetMod=shift ```
Biswa96 commented 4 years ago

I assume it's a cygwin issue but not sure. wslbridge2 gets notified from cygwin when there is window resize event happens i.e. sigaction(SIGWINCH). Some random experiments pop-up in my mind:

  1. Try with no mintty config, no bashrc.
  2. Try with older wsltty version 3.0.6 and 3.1.0. Uninstall the newer one before testing.
  3. Advanced: Open Command Prompt here C:\Users\User\AppData\Local\wsltty\bin. Run mintty.exe -e .\wslbridge2.exe -x (Do not forget .\ string). The hidden window will be shown with columns and rows (kind of debug output) and those are updated when mintty window is resized.
Terrance commented 4 years ago

Try with no mintty config, no bashrc

With no config file, no system/user bashrc/profile, and maximized:

image

After a restore/maximize:

image

Try with older wsltty version 3.0.6 and 3.1.0

Repro'd with 3.1.0 but not 3.0.6. I tried about 20 times on 3.0.6 with no success -- WSL is launching a lot faster now; at Windows startup it's a good few seconds where I could trigger it, so it's tricky to get in early enough. However, I can catch it about every other try with 3.1.0. Not entirely convinced though, given the size reporting issue has been seen before.

Run mintty.exe -e .\wslbridge2.exe -x

This one was a bit harder to get the timing right, as the debug window takes focus, but...

image

No initial resize logged, just the default rows/cols. After a restore/maximize again:

image

BtbN commented 4 years ago

I've been seeing the exact same thing. Even just dragging a corner and resizing the Terminal before it has started the shell will make it close again right away.

ghost commented 4 years ago

I've noticed this annoying bug too. Though now this finally forced me to change the shortcut to run maximized, which is what I want 99% of the time anyway.

mintty commented 4 years ago

It's a bit hard to reproduce this if WSL starts too fast... One way is from a cygwin mintty: (sleep 0.1; echo -e "\e[31;80t") & wslbridge2 It seems that a SIGWINCH arrives at wslbridge2 and is forwarded via resize_window to a socket which is not yet fully functional. Maybe the signal should be postponed in that case.

mintty commented 4 years ago

@Biswa96, it seems to help to add a 100ms delay at the beginning of function resize_window: usleep(100000);

Biswa96 commented 4 years ago

I can reproduce the issue. There is a delay between sending the first window size and registering the windows resize signal. If one open the wslbridge2 between those the size gets mismatched. Working on it...

mintty commented 4 years ago

I think there are two issues:

  1. The "terminal size not updated" is likely due to that delay. You could tackle that by registering the signal callback earlier, e.g. first action in main(), however at the cost of making issue 2 worse:
  2. The gap between registering the signal and setting up the socket channel to send to from resize_window(). If a signal arrives in between, it will act on an uninitialized socket and thus crash, the "Exit 1" issue. Therefore, the actual signal handling needs to be noted but postponed in that case. I have implemented that (wslbridge2.zip) but it does not fully solve the issue, probably because of the addtional initialization delay on the server side. Therefore the usleep I added, admittedly a bit ad-hoc.
Terrance commented 4 years ago

No change for me, I'm still getting exit 1 with that build.

Biswa96 commented 4 years ago

I didn't find any "actual working" solution yet. If anyone have a solid solution feel free to contribute. The workarounds are:

  1. wait for the window resize or
  2. add full window size in wsltty shortcut or
  3. remove any Hold option in config or from mintty settings.
mintty commented 4 years ago

After some further experiments with my approach (pending SIGWINCH propagation), it does not seem to make a difference whether the pending/postponing is invoked (by respective timing) or not. I've also tried to replace direct invocation of resize_window in the postponed case with an indirect kill(getpid(), SIGWINCH), with no improvement. My next attempt was to drop usage of that controlSocket, and send a token to the inputSocket instead. That works realiably, no crashes, token is fed into WSL input. So if you/we define a control char token, and an escape mechanism to convey that char if needed literally, and handle both in the backend, I guess that would solve the issue.

Biswa96 commented 4 years ago

define a control char token

Do you mean a escape sequence like thing? But then the backend has to parse every bit of input buffer, hasn't it?

I was thinking of the actual rprichard's wslbridge logic but that would re-welcome static linking issue.

mintty commented 4 years ago

It should not be a normal escape sequence. Rather a special escape (e.g. NUL) to initiate some "in-band" signalling. If you agree on the approach, I could work something out. How's rprichard's logic about the issue?

mintty commented 4 years ago

Uploaded a fix.

mintty commented 4 years ago

Released 3.1.8. Please check.

BtbN commented 4 years ago

The issue appears not to be happening anymore. However, I also upgraded from WSL1 to WSL2 in the meantime, and made the same observation already with that upgrade only, so cannot say for certain what exactly fixed it.

Terrance commented 4 years ago

Looks good so far, I'll report back if it does end up happening again.

mintty commented 2 years ago

Released 3.6.1, which needed to drop the previous patch as a hotfix (#302). Please retest this issue.