After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 777686 - End of cmd output discarded with "Hold the terminal open"
End of cmd output discarded with "Hold the terminal open"
Status: RESOLVED FIXED
Product: vte
Classification: Core
Component: general
0.46.x
Other Linux
: Normal normal
: ---
Assigned To: VTE Maintainers
VTE Maintainers
Depends on:
Blocks:
 
 
Reported: 2017-01-24 10:18 UTC by Igor
Modified: 2019-11-18 14:46 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Igor 2017-01-24 10:18:51 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.
Comment 1 Egmont Koblinger 2017-01-24 10:50:03 UTC
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.
Comment 2 Egmont Koblinger 2017-01-24 11:23:55 UTC
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...
Comment 3 Christian Persch 2017-01-24 16:09:02 UTC
(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.
Comment 4 Christian Persch 2017-01-24 16:11:21 UTC
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.
Comment 5 Egmont Koblinger 2017-01-24 18:09:51 UTC
> 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?
Comment 6 Egmont Koblinger 2017-01-24 18:16:15 UTC
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.
Comment 7 Igor 2017-01-24 18:19:46 UTC
(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.
Comment 8 Christian Persch 2017-01-25 23:38:16 UTC
(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.
Comment 9 Egmont Koblinger 2017-01-25 23:43:59 UTC
Obviously. I didn't think it through.
Comment 10 Igor 2017-02-27 18:45:12 UTC
Hi guys, any progress on this one?
Comment 11 Christian Persch 2019-11-17 20:59:01 UTC
Should be fixed on master now; please test.
Comment 12 Igor 2019-11-18 14:46:41 UTC
Looks like it's fixed, thanks!