GNOME Bugzilla – Bug 777686
End of cmd output discarded with "Hold the terminal open"
Last modified: 2019-11-18 14:46:41 UTC
If a program wants to show a large buffer of text, vte output will stop at one point and won't complete. The following script helps indicate the problem: ---- start 16K.sh ---- FILE="/tmp/16K.tmp" # generate about 16 KB of text rm -f $FILE for i in `seq 0 15`; do echo $i: >> $FILE for j in `seq 0 1023`; do echo -n 1 >> $FILE done echo >> $FILE done # print the text cat $FILE ---- stop 16K.sh ---- Now open gnome-terminal, go to Profile Preferences -> Command: When command exits -> Hold the terminal open Run a custom command instead of my shell -> put the path to 16K.sh File -> Open Terminal: a new tab will open, the output will stop at the 7th block for me which means it will show about 8 KB of text instead of 16 KB. The problem is also reproduced with xfce4-terminal when running `xfce4-terminal -H -e 16K.sh` which makes me think it's related to vte. Thanks.
Yup, confirmed. Just for the record: When you click on Relaunch, the missing output from the previous run still does not get shown. it is swallowed for good, not just delayed.
After these years I'm still not familiar enough with vte :) (1) I thought that the terminal (the tty line) existed for the entire duration of the widget, within which a child process may or may not exist at a given moment, and may be started up again once it's finished (see the above Hold+Relaunch possibilities). (2) Turns out this is not the case. The tty is connected to a running instance of a child. When there's no child running, there's no tty allocated. When a child is reswapn, it receives a new tty line. This is quite prominent now with gnome-terminal (or vte?) not closing the ptys (bug 772354 comment 19) [which by the way is a bug we definitely need to address before the next stable release!!!] Just add a "tty" command to the top of the script, and notice that it prints something new as you relaunch it. Knowing this, it looks like a simple race condition. The child exits, vte receives SIGCHLD, and handles it by closing its reading side of the tty line. A clean, robust, foolproof solution is not entire clear to me, though. Vte should add extra code to read and process the remaining bits from the tty before. However, what if there's another process writing to this tty, so effectively vte seeing infinite amount of data arriving even after the SIGCHLD? How should it decide when to stop? @chpe, do you know what was the reason to go for (2) instead of (1)? Was it perhaps to intentionally kick out other writers of the tty? I think I'd prefer (1), in which case we definitley wouldn't see this bug. Refactoring for the sake of addressing this bug is probably not feasible though. So I'm not sure what to do...
(In reply to Egmont Koblinger from comment #2) > This is quite prominent now with gnome-terminal (or vte?) not closing the > ptys (bug 772354 comment 19) [which by the way is a bug we definitely need > to address before the next stable release!!!] This is already fixed.
I think it's so that each process gets a clean PTY, e.g. for security reasons. To fix this, we could delay emitting the child-exited signal until we have read all of the data from the pty.
> This is already fixed. Geez, I haven't updated my repos in a while :) > I think it's so that each process gets a clean PTY, e.g. for security > reasons. Makes perfect sense. > To fix this, we could delay emitting the child-exited signal until we have > read all of the data from the pty. "all of the data" – the exact definition of this is the problematic part. I don't think there's anything like EOF from the tty. There can be another process keeping the terminal open and stuffing with data. Maybe the first short read is a good point to terminate? Or, in more particular, the first read returning 0 bytes?
Another possible approach: Keep the old tty alive and fully functionally working until the user clicks "Relaunch". Then throw away the old and allocate a new one. This way if there's e.g. a background process still writing, that data will still appear in the terminal even when the relaunch header bar is displayed. A special case of this will be the data that's already been written by the immediate child, just not yet read by vte (what this bugreport is about). It would be unnoticable to the user that technically the relaunch header bar is already displayed when the terminal contents are updated to show the last bits of the script's output.
(In reply to Egmont Koblinger from comment #6) > Another possible approach: Keep the old tty alive and fully functionally > working until the user clicks "Relaunch". Then throw away the old and > allocate a new one. > > This way if there's e.g. a background process still writing, that data will > still appear in the terminal even when the relaunch header bar is displayed. > A special case of this will be the data that's already been written by the > immediate child, just not yet read by vte (what this bugreport is about). It > would be unnoticable to the user that technically the relaunch header bar is > already displayed when the terminal contents are updated to show the last > bits of the script's output. I like this approach. "Relaunch" button is not a necessary part of the scenario; as I wrote, the problem is reproducible with xfce4-terminal which doesn't have such button but just keeps open even after receiving child-exited signal from vte.
(In reply to Egmont Koblinger from comment #6) > Another possible approach: Keep the old tty alive and fully functionally > working until the user clicks "Relaunch". Then throw away the old and > allocate a new one. That wouldn't work for auto-relaunch.
Obviously. I didn't think it through.
Hi guys, any progress on this one?
Should be fixed on master now; please test.
Looks like it's fixed, thanks!