LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Desktop (https://www.linuxquestions.org/questions/linux-desktop-74/)
-   -   Can't cleanup orphan process (https://www.linuxquestions.org/questions/linux-desktop-74/cant-cleanup-orphan-process-4175607638/)

shogun1234 06-09-2017 05:21 PM

Can't cleanup orphan process
 
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?

Thanks

Laserbeak 06-09-2017 06:06 PM

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.

Laserbeak 06-10-2017 09:43 AM

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.

ondoho 06-10-2017 02:18 PM

and that's why you shouldn't use kill -9.

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.

Code:

man ps
/parent

looks like there are more elegant ways.

rknichols 06-10-2017 03:36 PM

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.

Laserbeak 06-10-2017 09:30 PM

From ORACLE/Sun:

Quote:

Code:


#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.

Laserbeak 06-10-2017 09:46 PM

From ORACLE/Sun:

Quote:

Code:


#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.

I can do something similar on the Mac in Xcode.

Laserbeak 06-10-2017 10:08 PM

Actually if you don't care anything about your children, you can put this at the beginning of your code:

Code:

    signal(SIGCHLD, SIG_IGN);
Which makes your program ignore the signal, thus allowing the child to die.


All times are GMT -5. The time now is 06:59 AM.