Skip to content

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:

  1. 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.
  2. 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?