Control: found -1 4.8.0-6
Control: tags -1 patch upstream

On 2021-08-02 15:37:59 +0200, Vincent Lefevre wrote:
> As you can see, the clone I was wondering of last night comes from
> removeLineFromUtmp (function of libutempter), which also plays with
> signal handlers, probably clashing with screen if the SIGCHLD signal
> from the terminated shell process arrives exactly at this time[*].
> This would be the race condition.
> 
> [*] With strace, this seems to never happen: the SIGCHLD in question
> arrives earlier. But the strace makes the SCREEN process slower, so
> that in practice, the signal may arrive later, possibly at the same
> time as the clone (since the scheduler is involved).
> 
> In libutempter, one has:
[...]
> As you can see the SIGCHLD handler is modified, before being restored
> at the end.

This is even documented in its man page.

Same problem if I recompile screen 4.8.0-6 on this VM.

I've attached a patch, which consists in sending a SIGCHLD to oneself
there, in case one has been lost. It can be applied against either the
stable version (4.6.2-3+deb10u1) or the unstable version (4.8.0-6),
and it makes zombies disappear for both.

-- 
Vincent Lefèvre <vinc...@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)
Description: Avoid zombies after shell exit.
Author: Vincent Lefevre <vinc...@vinc17.net>
Bug-Debian: https://bugs.debian.org/991715
Bug: https://savannah.gnu.org/bugs/?25089
Last-Update: 2021-08-05

Index: screen-4.8.0/utmp.c
===================================================================
--- screen-4.8.0.orig/utmp.c
+++ screen-4.8.0/utmp.c
@@ -582,6 +582,14 @@ struct win *wi;
 	addToUtmp(wi->w_tty, host, wi->w_ptyfd);
       else
 	removeLineFromUtmp(wi->w_tty, wi->w_ptyfd);
+      /*
+       * As documented in libutempter: "During execution of the privileged
+       * process spawned by these functions, SIGCHLD signal handler will be
+       * temporarily set to the default action."
+       * Thus in case a SIGCHLD has been lost, we send a SIGCHLD to oneself
+       * in order to avoid zombies: https://savannah.gnu.org/bugs/?25089
+       */
+      kill(getpid(), SIGCHLD);
       return 1;	/* pray for success */
     }
 #endif

Reply via email to