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