Pourquoi le processus / programme devient zombie?

13

Si le script fonctionne correctement à partir de la ligne de commande, pourquoi le même script devient-il un état zombie après avoir exécuté Cron et comment dépanner le même?

Voici un exemple réel:

[root@abc ~]# ps ax | grep Z
23880 ?        Zs     0:00 [checkloadadv.sh] <defunct>
23926 pts/0    S+     0:00 grep Z
[root@abc ~]# strace -p 23880
attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted
[root@abc ~]# pstree | grep  checkload
init-+-crond---crond-+-checkloadadv.sh
[root@abc ~]# bash /usr/bin/checkloadadv.sh
System Load is OK : 0.05
Rahul Patil
la source
Le dépannage se produit en cas de problème. Les zombies ne sont pas un problème.
Gilles 'SO- arrête d'être méchant'
@ Gilles, vous avez raison, mais ai-je besoin de prendre soin et de savoir les prévenir? ce que tu penses ?
Rahul Patil,
Ce ne sont pas des problèmes, donc non, vous n'avez pas besoin de vous en soucier.
Gilles 'SO- arrête d'être méchant'

Réponses:

21

entrez la description de l'image ici

Comme un véritable zombie, un processus zombie ne peut pas être tué, car il est déjà mort.

Comment ça se passe

Lorsque sous Linux / Unix un processus meurt / se termine, toutes les informations du processus sont supprimées de la mémoire système, seul le descripteur de processus reste. Le processus passe à l'état Z (zombie). Son processus parent reçoit un signal du noyau: SIGCHLDcela signifie que l'un de ses enfants traite les sorties, est interrompu ou reprend après avoir été interrompu (dans notre cas, il se termine simplement).

Le processus parent doit maintenant exécuter l' wait()appel système pour lire l'état de sortie et d'autres informations de son processus enfant. Ensuite, le descripteur est supprimé de la mémoire et le processus n'est plus un zombie.

Si le processus parent n'appelle jamais l'appel wait()système, le descripteur de processus zombie reste en mémoire et mange le cerveau. Normalement, vous ne voyez pas les processus zombies, car la procédure ci-dessus prend moins de temps.

L'aube des morts

Chaque descripteur de processus a besoin d'une très petite quantité de mémoire, donc quelques zombies ne sont pas très dangereux (comme dans la vraie vie). Un problème est que chaque processus zombie conserve son identifiant de processus, et un système d'exploitation Linux / Unix a un nombre limité de pid. Si un logiciel mal programmé génère beaucoup de processus zombies, il peut arriver que les processus ne puissent plus être démarrés car il n'y a plus d'ID de processus disponibles.

Donc, s'ils sont en groupes énormes, ils sont très dangereux (comme dans de nombreux films, cela est très bien démontré)

Comment se défendre contre une horde de zombies?

Un coup dans la tête fonctionnerait, mais je ne connais pas la commande pour cela (SIGKILL ne fonctionnera pas car le processus est déjà mort).

Eh bien, vous pouvez envoyer SIGCHLD via kill au processus parent, mais quand il ignore ce signal, alors quoi? Votre seule option est de tuer le processus parent et que le processus init "adopte" le zombie. Init appelle périodiquement le wait()syscall pour nettoyer ses enfants zombies.

Dans ton cas

Dans votre cas, vous devez envoyer SIGCHLD au processus crond:

root@host:~# strace -p $(pgrep cron)
Process 1180 attached - interrupt to quit

Puis depuis un autre terminal:

root@host:~$ kill -17 $(pgrep cron)

La sortie est:

restart_syscall(<... resuming interrupted call ...>) = ? ERESTART_RESTARTBLOCK (To be restarted)
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, 0x7fff51be39dc, WNOHANG, NULL) = -1 ECHILD (No child processes) <-- Here it happens
rt_sigreturn(0xffffffffffffffff)        = -1 EINTR (Interrupted system call)
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=1892, ...}) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {0x403170, [CHLD], SA_RESTORER|SA_RESTART, 0x7fd6a7e9d4a0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({42, 0}, ^C <unfinished ...>
Process 1180 detached

Vous voyez le wait4()syscall renvoie -1 ECHILD, ce qui signifie qu'aucun processus enfant n'est là. La conclusion est donc: cron réagit au syscall SIGCHLD et ne doit pas forcer l'apocalypse.

le chaos
la source
1
Quoi, pas de battes de cricket et de LPs?
Alexios
-3

Si le thread parent est tué avant son thread enfant, tous les threads enfants deviendront des processus zombies.

Sandeep
la source
7
Ce n'est pas vrai, ils seront simplement réparés. Les processus Zombie n'ont pas appelé waitpid.
Chris Down
Peut-être parlait-il des processus parent-enfant; un processus enfant devient un "orphelin" lorsque son parent "meurt".
Barun