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 740929 - Leaves zombie shell when closing with X
Leaves zombie shell when closing with X
Status: RESOLVED FIXED
Product: vte
Classification: Core
Component: general
0.38.x
Other Linux
: Normal major
: ---
Assigned To: VTE Maintainers
VTE Maintainers
Depends on:
Blocks:
 
 
Reported: 2014-11-30 17:43 UTC by Egmont Koblinger
Modified: 2014-12-04 21:01 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Fix (1.35 KB, patch)
2014-11-30 18:17 UTC, Egmont Koblinger
none Details | Review
Fix v2 (1.28 KB, patch)
2014-12-01 10:57 UTC, Egmont Koblinger
committed Details | Review
widget: Reap only when a child is present (1.23 KB, patch)
2014-12-04 15:48 UTC, Debarshi Ray
committed Details | Review

Description Egmont Koblinger 2014-11-30 17:43:01 UTC
Found at https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=770596

When closing a tab or window with the X button or with Ctrl+Shift+W or alike (as opposed to asking the shell to exit), a defunct bash is left behind.

These are not cleaned up until you exit from g-t, which might take (depending on someone's workflow) days/weeks, and easily result in hundreds of zombies cluttering the output of ps and consuming the scarce resource of 32k possible process IDs.
Comment 1 Egmont Koblinger 2014-11-30 17:43:31 UTC
Probably relevant:
bug 112172
https://git.gnome.org/browse/vte/commit/?id=de112fd
Comment 2 Christian Persch 2014-11-30 18:03:20 UTC
Hmm. vte_terminal_finalize first removes the child watch source, then kill()s the process. So the child won't be reaped. But I'm not sure inverting the order of these calls will fix it.
Comment 3 Egmont Koblinger 2014-11-30 18:17:25 UTC
Created attachment 291842 [details] [review]
Fix

Here's my first attempt to fix it (I hope it's good).

Sending a SIGHUP to the child is necessary (we need to notify the shell), but I don't think shuffling the order would solve anything:

- We shouldn't leave zombies even if the child ignores sighup (maybe is not even a shell, but some random app)

- There's a race condition, we can't be sure when the shell will actually exit.

My current attempt is to install another child_watch handler, one that does nothing when executed.

Not sure if the child_watch source cleans up itself or if I leave around some stuff in Glib, but it's already better than zombies.
Comment 4 Debarshi Ray 2014-12-01 10:27:26 UTC
Review of attachment 291842 [details] [review]:

A child watch source is always removed after the callback is called. See g_child_watch_dispatch in GLib. That is why GChildWatchFunc does not need to return a boolean unlike a GSourceFunc.

I am not a vte reviewer, though.
Comment 5 Egmont Koblinger 2014-12-01 10:57:24 UTC
Created attachment 291877 [details] [review]
Fix v2

Thanks Debarshi, based on this I'm even more positive that this is the right fix.

Update: cosmetic changes only.
Comment 6 Christian Persch 2014-12-01 11:52:06 UTC
Or we could re-introduce the reaper but keep it private not exported.
Comment 7 Egmont Koblinger 2014-12-01 12:12:46 UTC
As far as I understand, the reaper was removed for good reasons.

At this point I'd like to go for the easiest possible fix, and cherry-pick to stable.

I'm not against further refactoring to make it more proper OO, maybe even bringing back a better reaper, but IMO such change should go in master only, not in stable branches.  I'd like to commit my change if you're not against it, and then let you refactor it if you wish :)
Comment 8 Christian Persch 2014-12-01 12:18:41 UTC
Sure, please commit.

The reason the reaper was removed was that we wanted it gone from the public API, and I didn't realise this subtle problem exists.
Comment 9 Egmont Koblinger 2014-12-01 12:25:53 UTC
I just realized there were 8 years between the initial bugreport and the removal of the reaper. Initial concerns (e.g. manually hijacking sigchld) didn't exist by the time it was removed. So it's okay to bring it back, but of not much use.
Comment 10 Egmont Koblinger 2014-12-01 12:33:02 UTC
Comment on attachment 291877 [details] [review]
Fix v2

Committed to master. Will backport to stable in a few days if no problem arises.
Comment 11 Egmont Koblinger 2014-12-04 15:13:32 UTC
Fixed in 0-38 too.
Comment 12 Debarshi Ray 2014-12-04 15:48:08 UTC
Review of attachment 291877 [details] [review]:

::: src/vte.c
@@ +8460,3 @@
+                               terminal->pvt->pty_pid,
+                               (GChildWatchFunc)vte_terminal_child_watch_cb,
+                               NULL, NULL);

This needs to go inside the if block. Otherwise, when we are closing the terminal by actually quitting the shell, pvt->pty_pid would be -1 (and pvt->child_watch_source would be 0), which lead to a CRITICAL from g_child_watch_add_full.
Comment 13 Debarshi Ray 2014-12-04 15:48:47 UTC
Created attachment 292134 [details] [review]
widget: Reap only when a child is present
Comment 14 Egmont Koblinger 2014-12-04 21:00:44 UTC
Comment on attachment 292134 [details] [review]
widget: Reap only when a child is present

Oops, indeed, thanks a lot for this hotfix! Committed.