Linux - DesktopThis forum is for the discussion of all Linux Software used in a desktop context.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I play game on Steam platform, but I find sometime the game I am playing would hang without reason known, and can't close or exit normally (through Steam GUI).
This forces me to kill the processes by `ps -ef | grep steam | awk '{print $2}' | xargs kill -9`. It often works; however sometimes it seems that some other related processes can't be not cleanup with this command. For instance I just visited a game web page in Steam, which broadcasted videos, and suddenly it hung. After 'kill'ing steam, the video remains on the desktop. I tried with searching zombie command `ps aux | awk '{print $2 " " $8} | grep -w Z'` Unfortunately there is no process with state at zombie.
How can I find and cleanup those defunct processes without reboot or logout/ login?
It sounds like the code isn't calling wait() or waitpid() or something and leaving a zombie process running. If you have access to the source code, make sure every time fork() or something similar is called you call wait() or something similar to accept that it has died and let it go away. If you don't have access to the source code, just file a bug report with the code maintainers.
The above is usually done by either for the parent to wait for the child to quit (if it is expected to quit quickly), or defining a handler for SIGCHLD, which is a UNIX signal sent to a parent process when a child is quitting. You have to reap it otherwise the "zombie" continues to stick around.
i think a zombie and an orphan are not the same; i once had the same problem, and there's an option to ps to print the parent process. if it is the process you just kill -9'd, then you can go killing the orphan's.
All "orphan" processes are immediately adopted by PID 1 (the init process). If you kill a parent process and the child does not terminate, that child's PPID will immediately show as "1". When that adopted child process terminates, PID 1 will immediately reap its exit status so that it does not become a zombie.
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/resource.h>
void proc_exit()
{
int wstat;
union wait wstat;
pid_t pid;
while (TRUE) {
pid = wait3 (&wstat, WNOHANG, (struct rusage *)NULL );
if (pid == 0)
return;
else if (pid == -1)
return;
else
printf ("Return code: %d\n", wstat.w_retcode);
}
}
main ()
{
signal (SIGCHLD, proc_exit);
switch (fork()) {
case -1:
perror ("main: fork");
exit (0);
case 0:
printf ("I'm alive (temporarily)\n");
exit (rand());
default:
pause();
}
}
SIGCHLD catchers are usually set up as part of process initialization. They must be set before a child process is forked. A typical SIGCHLD handler retrieves the child process's exit status.
You can see in main() signal() is called to install proc_exit() as a handler for the child process's death. Therefore you don't get any zombie or orphan.
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/resource.h>
void proc_exit()
{
int wstat;
union wait wstat;
pid_t pid;
while (TRUE) {
pid = wait3 (&wstat, WNOHANG, (struct rusage *)NULL );
if (pid == 0)
return;
else if (pid == -1)
return;
else
printf ("Return code: %d\n", wstat.w_retcode);
}
}
main ()
{
signal (SIGCHLD, proc_exit);
switch (fork()) {
case -1:
perror ("main: fork");
exit (0);
case 0:
printf ("I'm alive (temporarily)\n");
exit (rand());
default:
pause();
}
}
SIGCHLD catchers are usually set up as part of process initialization. They must be set before a child process is forked. A typical SIGCHLD handler retrieves the child process's exit status.
You can see in main() signal() is called to install proc_exit() as a handler for the child process's death. Therefore you don't get any zombie or orphan.
NOTE: This code is kind of strange, I can't even get it to compile on my Mac. I'll have to try it on Solaris, but even then it might need a Sun compiler.
NOTE2: I tried on Solaris 11.3 x86_64, and it didn't compile even though it was straight off ORACLE's website. But you can get the idea.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.