Supprimer un processus zombie de la table des processus

8

J'ai un processus de zombie ennuyeux qui est adopté par init, et il ne disparaîtra pas. J'ai lu qu'il existe un moyen de créer un processus factice, d'attacher le zombie en tant qu'enfant de ce nouveau processus, puis de le tuer, en le supprimant de la table des processus.

Comment pourrais-je faire cela, précisément?

Et oui, j'ai lu la plupart de ces trucs:

Un processus zombie est déjà mort, il ne peut donc pas être tué.

Ou

Vous devez simplement redémarrer votre système

Et

Les processus zombies n'utilisent aucune ressource, vous devez simplement les laisser être

Malheureusement, de nombreux programmes vérifient la table de processus pour voir si une instance est déjà en cours d'exécution et refusent d'en démarrer une nouvelle s'il existe une entrée dans la table de processus.

Et redémarrer à chaque fois que ma connexion SSHFS s'arrête, emportant Sublime avec, est un peu idiot.

skerit
la source
7
... avec un fusil de chasse. ;)
Nathan C
+1, car j'ai regardé le principal et j'ai vu "tuer un zombie"
HopelessN00b

Réponses:

16

La seule façon de se débarrasser d'un zombie est de faire son parent wait()afin qu'il puisse signaler son statut de sortie. Vous pouvez le faire en envoyant SIGCHLDau parent, en supposant que le parent est écrit correctement.

Si vous avez des zombies, cela signifie généralement que le parent n'est PAS écrit correctement (parce que l'enfant a déjà été envoyé SIGCHLDà son parent lorsqu'il est décédé et est devenu un zombie), la prochaine étape consiste donc à tuer le parent.
Un outil comme pstree(avec l' -poption) peut vous montrer la lignée de vos zombies afin que vous sachiez quel processus est le parent.
Lorsque le parent décède, le zombie sera adopté par init, qui est toujours en wait()train de mourir pour les enfants, et tuera joyeusement tous les zombies qu'il adopte.

Si le processus parent est en fait init(PID 1), vous êtes déjà dans une situation qui ne devrait jamais se produire. Vous pouvez essayer d'envoyer SIGCHLDvers init, mais vous ne devriez vraiment pas avoir à le faire, et si cela ne fonctionne pas, votre seul recours est de redémarrer car votre système initest en panne et ne fait pas son travail.

(Ce sont les options de "fusil de chasse".)


Des gens plus créatifs que moi ont également proposé cette option si vous voulez éviter de tuer le processus parent:

  1. Déterminer le PIDS du processus zombie et parent
    (pour cet exemple, disons que le zombie est PID 3101 et le parent est PID 3100)
  2. Allumez gdbet attachau parent:
    attach 3100
  3. Appelez waitpidle zombie:
    call waitpid(3101,0,0)
  4. Détachez-vous du parent ( detach) et quittez le débogueur.

(Il s'agit d'un fusil de sniper finement réglé.)

voretaq7
la source
1
heh, excellente réponse. Fusil "Mosin" juste là.
Danila Ladner
1
@DanilaLadner J'aimerais pouvoir prendre le crédit, mais jusqu'à ce que je parte pour une petite chasse à Google pour voir ce que le skerit voulait dire "attacher le zombie comme un enfant d'un processus factice", l'idée d'utiliser le débogueur pour forcer un waitpid()ne m'est jamais venue à l'esprit . Je suis un terrible ancien programmeur ...
voretaq7
call waitpidne revient jamais pour moi
deFreitas
0

Pourquoi vous inquiétez-vous des processus zombies? Les ressources qu'ils gardent liées sont minimes (espace pour une tâche de structure squelette, un PID et pas grand chose d'autre). Bien sûr, c'est inconvenant, mais c'est tout. Recherchez leurs parents et corrigez-les, remplacez-les par de meilleures alternatives écrites (pourraient avoir d'autres effets secondaires bénéfiques), signalez cela comme des bogues (ce qu'ils sont certainement).

vonbrand
la source