xfce4-session doesn't reap zombies
Revisiting issue #10 (closed) which was closed due to age ( and the prior https://bugzilla.xfce.org/show_bug.cgi?id=9056 )
In addition to what's detailed in the above bugs, here are steps to reproduce:
- Create a ~/.xsession file and run something in it. In my case I ran some backgrounded pipewire daemons but I'm sure
sleep 3600&
would work too. - Examine the process tree under xfce4-session to find zombies - in my case the shell used to run .xsession was itself left as a zombie
nn:[eam]:~$ ps -ef|grep 848
eam 848 831 0 Aug27 ? 00:00:00 xfce4-session
eam 858 848 0 Aug27 ? 00:00:01 /usr/bin/pipewire
eam 859 848 0 Aug27 ? 00:00:00 [sh] <defunct>
eam 860 848 0 Aug27 ? 00:00:00 /usr/bin/wireplumber
eam 945 848 0 Aug27 ? 00:00:11 xfwm4
...
This would happen because xfce4-session is spawning child processes and not wait()ing on them:
- it forked a /bin/sh to run .xesssion
- That shell exited
- xfce4-session did not call wait()
I grabbed the code and took a quick look, but I did not see where xfce4-session spawns the shell to execute .xsession. If someone could point me at where that happens I might be able to offer specific advice as to how to fix - I'm not familiar with this codebase. Maybe it's in another component?
Interestingly, I did see that xfce4-session DOES successfully wait() on some of its child processes. Here, I strace
'd xfce4-session and then killed xfce4-screensaver. We can see that xfce4-session did correctly reap the dead screensaver process
nn:[eam]:~$ sudo strace -f -p 848
strace: Process 848 attached with 4 threads
[pid 894] futex(0x5620e1487620, FUTEX_WAIT_PRIVATE, 1, NULL <unfinished ...>
[pid 848] restart_syscall(<... resuming interrupted read ...> <unfinished ...>
[pid 896] restart_syscall(<... resuming interrupted futex ...> <unfinished ...>
[pid 895] restart_syscall(<... resuming interrupted futex ...> <unfinished ...>
[pid 848] <... restart_syscall resumed>) = 1
[pid 896] <... restart_syscall resumed>) = 1
[pid 848] waitid(P_PIDFD, 26, <unfinished ...>
[pid 896] write(7, "\1\0\0\0\0\0\0\0", 8 <unfinished ...>
[pid 848] <... waitid resumed>0x7ffcc02649e0, WNOHANG|WEXITED, NULL) = -1 ECHILD (No child processes)
I did not see a call to waitid() in xfce4-session's codebase so maybe this is done in a library somewhere?