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

Pty stalls when pasting long text #810

Closed
wangqr opened this issue Oct 14, 2018 · 18 comments
Closed

Pty stalls when pasting long text #810

wangqr opened this issue Oct 14, 2018 · 18 comments

Comments

@wangqr
Copy link

wangqr commented Oct 14, 2018

When pasting text with length ~350k chars, mintty quits immediately. I can reproduce this consistently on both mintty v2.9.3 (installed from cygwin x86_64) and wsltty 1.8.4 (mintty 2.8.4).

@mintty
Copy link
Owner

mintty commented Oct 14, 2018

I can paste 400KB into mintty without problems, using various test scenarios, e.g.
cat > tst
then middle-mouse-click, or Paste from the context menu.

Do you paste into a specific application that runs in mintty?
Specify your test case precisely so it can be reproduced.

@mintty
Copy link
Owner

mintty commented Oct 14, 2018

The following is needed for a minimal sound incident report:
What do you paste? (exact copy of /dev/clipboard, uploaded here)
How do you paste?
Which application is running in the foreground when you paste? (e.g. bash)
Failing to provide a well-described test case that can be reproduced, I can only close the issue.

@mintty mintty added the invalid label Oct 14, 2018
@wangqr
Copy link
Author

wangqr commented Oct 14, 2018

I was pasting into some self-written program, but pasting into bash or cat > tst has the same effect.
I copied 350k small letter ccccccccc..ccc from Notepad++ and pasting into mintty, by right click inside mintty's window, and select 'Paste'. I have tried middle-mouse-click, and mintty also crashes.
cat /dev/clipboard works fine.

@wangqr
Copy link
Author

wangqr commented Oct 14, 2018

Oh I have also found a mintty.exe.stackdump in the home directory

$ cat mintty.exe.stackdump
Exception: STATUS_STACK_OVERFLOW at rip=0010040B252
rax=00000000003D0730 rbx=00000000000A2BDC rcx=000006FFFFEB0010
rdx=00000000000A2BDC rsi=0000000100496D80 rdi=00000000000A2BDC
r8 =00000000003D0728 r9 =00000000003D0000 r10=00000000FFE031E0
r11=00000000FFC2B1E0 r12=0000000000060B30 r13=0000000000000111
r14=0000000000000000 r15=0000000000000000
rbp=00000000FFFFC260 rsp=00000000FFFFC1E0
program=C:\cygwin64\bin\mintty.exe, pid 788, thread
cs=0033 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame        Function    Args
000FFFFC260  0010040B252 (000000A2BDC, 000FFFFC350, 00000060B30, 00000000111)
000FFFFC350  0010041937F (000035BF040, 00000000000, 00000000000, 7FFCC3E6B900)
000FFFFC350  001004315C1 (7FFCC3E6B900, 00000000030, 00000000000, 00000000111)
000FFFFC350  00100433C5B (00000000002, 000014A0188, 00000060B30, 00001086C40)
000FFFFC350  00100420AC6 (00000000000, 00000000000, 00000000022, 00000000000)
000FFFFC620  7FFCC3E4CA66 (0010041F7C0, 00000060B30, 000FFFFC6C0, 00000000030)
000FFFFC620  7FFCC3E4C582 (00000000001, 7FFCC3E4ECB0, 7FFCC3E971F0, 00600000001)
000FFFFC620  0010043FB74 (0018022CDD0, 000FFFFCC74, 00000000030, FF0700010302FF00)
000FFFFCCD0  00180049E16 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000  00180047973 (00000000000, 00000000000, 00000000000, 00000000000)
000FFFFFFF0  00180047A24 (00000000000, 00000000000, 00000000000, 00000000000)
End of stack trace

@mintty
Copy link
Owner

mintty commented Oct 14, 2018

I've pasted 431284 bytes of lines of 71 'c's each, terminated with DOS lineends (CRLF) into cat > tst.
No problem here.
Please describe your input file precisely (line structure) or simply upload it here (compressed if possible).

@mintty
Copy link
Owner

mintty commented Oct 14, 2018

OK, if I remove all the lineends, I do indeed get a crash. To be analysed.

@mintty mintty removed the invalid label Oct 14, 2018
@wangqr
Copy link
Author

wangqr commented Oct 14, 2018

I have made a debug build from 250cbd7, and attached gdb to mintty when crashing. Here is the backtrace:

(gdb) c
Continuing.
[Thread 788.0x1bf0 exited with code 0]

Thread 1 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 788.0x22b0]
0x000000010041d16d in child_sendw (ws=0x6ffffeb0010 L'c' <repeats 200 times>..., wlen=350000) at child.c:690
690       char s[wlen * cs_cur_max];
(gdb) bt
#0  0x000000010041d16d in child_sendw (ws=0x6ffffeb0010 L'c' <repeats 200 times>..., wlen=350000) at child.c:690
#1  0x000000010042cd61 in term_send_paste () at termclip.c:255
#2  0x000000010042cc50 in term_paste (data=0x9de040 L'c' <repeats 200 times>..., len=350000, all=false) at termclip.c:236
#3  0x0000000100457505 in paste_unicode_text (data=0x9de040) at winclip.c:925
#4  0x0000000100457739 in win_paste () at winclip.c:951
#5  0x0000000100405d44 in win_proc (wnd=0x490840, message=273, wp=48, lp=0) at winmain.c:2161
#6  0x00007ffcc3e4ca66 in USER32!DispatchMessageW () from /cygdrive/c/WINDOWS/System32/USER32.dll
#7  0x00007ffcc3e4c582 in USER32!DispatchMessageW () from /cygdrive/c/WINDOWS/System32/USER32.dll
#8  0x000000010040bdba in main (argc=1, argv=0x60004ba90) at winmain.c:4503
(gdb) c
Continuing.
[New Thread 788.0xccc]
[Thread 788.0xccc exited with code 0]
[Thread 788.0x105c exited with code 0]
[Thread 788.0x19cc exited with code 0]
[Thread 788.0xa6c exited with code 139]
[Thread 788.0x122c exited with code 139]
[Thread 788.0x714 exited with code 139]
[Thread 788.0x20ac exited with code 139]
[Inferior 1 (process 788) exited with code 0213]

@mintty
Copy link
Owner

mintty commented Oct 14, 2018

Thanks for the debug info. Analysis to be continued tomorrow.

@wangqr
Copy link
Author

wangqr commented Oct 14, 2018

I made the following change to src/child.c, and now pasting into bash has no problem. But pasting into cat (or cat > test, or wc) will make mintty not responding. When mintty is not responding, it is not using CPU or allocating more memory.

--- a/src/child.c
+++ b/src/child.c
@@ -687,10 +687,14 @@ child_send(const char *buf, uint len)
 void
 child_sendw(const wchar *ws, uint wlen)
 {
-  char s[wlen * cs_cur_max];
-  int len = cs_wcntombn(s, ws, sizeof s, wlen);
+  int len = wlen * cs_cur_max * sizeof(char);
+  char *s = malloc(len);
+  if (!s)
+    return;
+  len = cs_wcntombn(s, ws, len, wlen);
   if (len > 0)
     child_send(s, len);
+  free(s);
 }

And some gdb backtrace:

Attaching to process 8944
[New Thread 8944.0x2b40]
[New Thread 8944.0x1fc]
[New Thread 8944.0x243c]
[New Thread 8944.0x1dcc]
[New Thread 8944.0x10b8]
[New Thread 8944.0xcd0]
[New Thread 8944.0x314]
[New Thread 8944.0x1f38]
[New Thread 8944.0x1e00]
[New Thread 8944.0x68c]
[New Thread 8944.0x2348]
[New Thread 8944.0x19cc]
[New Thread 8944.0x2700]
Reading symbols from /usr/bin/mintty...done.
(gdb) bt
#0  0x00007ffcc43d1f81 in ntdll!DbgBreakPoint () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#1  0x00007ffcc43ff36b in ntdll!DbgUiRemoteBreakin () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#2  0x00007ffcc37a7e94 in KERNEL32!BaseThreadInitThunk () from /cygdrive/c/WINDOWS/System32/KERNEL32.DLL
#3  0x00007ffcc4397ad1 in ntdll!RtlUserThreadStart () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#4  0x0000000000000000 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) i thread
  Id   Target Id         Frame
  1    Thread 8944.0x2b40 0x00007ffcc43ce694 in ntdll!ZwWriteFile () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
  2    Thread 8944.0x1fc 0x00007ffcc43d1f04 in ntdll!ZwWaitForWorkViaWorkerFactory () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
  3    Thread 8944.0x243c 0x00007ffcc43d1f04 in ntdll!ZwWaitForWorkViaWorkerFactory () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
  4    Thread 8944.0x1dcc 0x00007ffcc43ce654 in ntdll!ZwReadFile () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
  5    Thread 8944.0x10b8 0x00007ffcc43d1f04 in ntdll!ZwWaitForWorkViaWorkerFactory () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
  6    Thread 8944.0xcd0 0x00007ffcc43d1f04 in ntdll!ZwWaitForWorkViaWorkerFactory () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
  7    Thread 8944.0x314 0x00007ffcc43cf0e4 in ntdll!ZwWaitForMultipleObjects () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
  8    Thread 8944.0x1f38 0x00007ffcc43d1f04 in ntdll!ZwWaitForWorkViaWorkerFactory () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
  9    Thread 8944.0x1e00 0x00007ffcc43cecb4 in ntdll!ZwFsControlFile () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
  10   Thread 8944.0x68c 0x00007ffcc43ce654 in ntdll!ZwReadFile () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
  11   Thread 8944.0x2348 0x00007ffcc43ce654 in ntdll!ZwReadFile () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
  12   Thread 8944.0x19cc 0x00007ffcc43ce614 in ntdll!ZwWaitForSingleObject () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
* 13   Thread 8944.0x2700 0x00007ffcc43d1f81 in ntdll!DbgBreakPoint () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
(gdb) thread 1
[Switching to thread 1 (Thread 8944.0x2b40)]
#0  0x00007ffcc43ce694 in ntdll!ZwWriteFile () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
(gdb) bt
#0  0x00007ffcc43ce694 in ntdll!ZwWriteFile () from /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll
#1  0x00007ffcc10b012a in WriteFile () from /cygdrive/c/WINDOWS/System32/KERNELBASE.dll
#2  0x00000001800a7e53 in fhandler_pty_common::process_opost_output(void*, void const*, long&, bool) () from /usr/bin/cygwin1.dll
#3  0x00000001800a8048 in fhandler_pty_master::doecho(void const*, unsigned int) () from /usr/bin/cygwin1.dll
#4  0x00000001800a1792 in fhandler_termios::line_edit(char const*, unsigned long, termios&, long*) () from /usr/bin/cygwin1.dll
#5  0x00000001800a2348 in fhandler_pty_master::write(void const*, unsigned long) () from /usr/bin/cygwin1.dll
#6  0x0000000180136c2a in write () from /usr/bin/cygwin1.dll
#7  0x000000018011d81b in _sigfe () from /usr/bin/cygwin1.dll
#8  0x000000010041cf86 in child_write (buf=0x6ffff5c0010 'c' <repeats 200 times>..., len=1333176) at child.c:644
#9  0x000000010041d0d2 in child_send (buf=0x6ffff5c0010 'c' <repeats 200 times>..., len=1333176) at child.c:684
#10 0x000000010041d15b in child_sendw (ws=0x6ffffd70010 L'c' <repeats 200 times>..., wlen=1333176) at child.c:696
#11 0x000000010042cd01 in term_send_paste () at termclip.c:255
#12 0x000000010042cbf0 in term_paste (data=0x35f6040 L'c' <repeats 200 times>..., len=1333176, all=false) at termclip.c:236
#13 0x00000001004574a5 in paste_unicode_text (data=0x35f6040) at winclip.c:925
#14 0x00000001004576d9 in win_paste () at winclip.c:951
#15 0x0000000100405d44 in win_proc (wnd=0xa0bba, message=273, wp=48, lp=0) at winmain.c:2161
#16 0x00007ffcc3e4ca66 in USER32!DispatchMessageW () from /cygdrive/c/WINDOWS/System32/USER32.dll
#17 0x00007ffcc3e4c582 in USER32!DispatchMessageW () from /cygdrive/c/WINDOWS/System32/USER32.dll
#18 0x000000010040bdba in main (argc=4, argv=0x6000536e0) at winmain.c:4503

@mintty
Copy link
Owner

mintty commented Oct 15, 2018

Actually, the hang occurs in write() and also causes trouble in xterm, so it's not strictly a mintty bug, but of course mintty can and will workaround the problem.

@mintty
Copy link
Owner

mintty commented Oct 15, 2018

Splitting up the big write() into smaller chunks does not help as I had hoped.

@mintty
Copy link
Owner

mintty commented Oct 15, 2018

Possibly related to #390??

@mintty
Copy link
Owner

mintty commented Oct 17, 2018

Please confirm that your test case contains lines of excessive length.
I have the suspicion that this cannot be digested on the receiving side of the pty (the child process reading from the terminal).
Also the current mintty pasting mechanism for long text is a bit obscure; it leaves paste contents pending which is later pasted from the main loop but may also be clipped...

@wangqr
Copy link
Author

wangqr commented Oct 17, 2018

Yes it does contain line of excessive length.
Currently I use pipe to feed the input and it works fine.

@mintty
Copy link
Owner

mintty commented Oct 18, 2018

I've uploaded a first patch which should avoid the stalling. However, the terminal is rendered unresponsive after pasting such excessive contents until you send an interrupt (^C or ^).

@mintty
Copy link
Owner

mintty commented Oct 19, 2018

New test case:
Copy 250KB single-line text to the clipboard,
Remote login to a Linux machine,
Try cat > /dev/null and cat > xx, paste with mouse-middle-click.
In both cases, the paste buffer appears inside the terminal window, no hang, operation continues.
However, the xx file is only 4KB long after pasting.
This convinces me that this is not a mintty issue but rather a pty issue, and not only on cygwin. Marking issue "invalid" thus.

I'll leave the patch in place that avoids the total hang and I'll try to improve it to avoid also the need to press ^C to continue. I'll also report the issue on the cygwin mailing list; however, I'll try to extract a minimal test case for a while first which didn't succeed so far.

@mintty mintty changed the title Crashes when pasting long text Pty stalls when pasting long text Oct 22, 2018
@mintty
Copy link
Owner

mintty commented Oct 22, 2018

The current behaviour (uploaded to repository) is also observed inside screen when run in a cygwin console (i.e. mintty not involved). Therefore I'll close this issue after the next release.

@mintty
Copy link
Owner

mintty commented Nov 10, 2018

Released 2.9.4.

@mintty mintty closed this as completed Nov 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants