Comment est-il possible que kill -9 pour un processus sous Linux n'ait aucun effet?
j'écris un plugin pour mettre en surbrillance les chaînes de texte automatiquement lorsque vous visitez un site web. C'est comme les résultats de recherche de surbrillance, mais automatique et pour beaucoup de mots; il pourrait être utilisé pour les gens avec des allergies pour faire des mots vraiment se démarquer, par exemple, quand ils parcourent un site alimentaire.
mais j'ai un problème. Quand j'essaie de fermer une fenêtre FF vide, ça bloque tout le processus. Quand je tue le processus, toutes les fenêtres disparaissent, mais le processus Firefox reste en vie (parent PID est 1, n'écoute aucun signal, a beaucoup de ressources ouvertes, mange toujours CPU, mais ne bougera pas).
donc deux questions:
-
Comment est-il possible pour un processus de ne pas écouter kill -9 (ni en tant qu'utilisateur ni en tant que root)?
-
est-ce que je peux faire autre chose qu'un redémarrage?
[EDIT] C'est le fautif process:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
digulla 16688 4.3 4.2 784476 345464 pts/14 D Mar28 75:02 /opt/firefox-3.0/firefox-bin
même chose que ps -ef | grep firefox
UID PID PPID C STIME TTY TIME CMD
digulla 16688 1 4 Mar28 pts/14 01:15:02 /opt/firefox-3.0/firefox-bin
c'est le seul procédé qui reste. Comme vous pouvez le voir, ce n'est pas un zombie, il court! Il n'écoute pas kill -9, peu importe si je tue par PID ou nom! Si j'essaie de me connecter avec strace
, alors le strace
est suspendu et ne peut pas être tué. Il n'y a pas de sortie, soit. À mon avis, est-ce que FF est accroché à une certaine routine du noyau, mais laquelle?
[Edit 2] Basé sur le feedback de sigjuice:
ps axopid,comm,wchan
peut vous montrer dans quelle routine du noyau un processus est suspendu. Dans mon cas, le plugin incriminé était L'indexeur Beagle (openSUSE 11.1). Après avoir désactivé le plugin, FF était à nouveau un renard rapide et heureux.
7 réponses
tel que noté dans les commentaires à L'OP, un État de processus ( STAT
) de D
indique que le processus est dans un État de" sommeil ininterrompu". En termes réels, cela signifie généralement qu'il attend l'arrivée des e/s et qu'il ne peut ou ne veut rien faire - y compris mourir - tant que l'opération d'e/s n'est pas terminée.
dans un État D
ne seront normalement présents que pendant une fraction de seconde avant la fin de l'opération et ils reviendront à R
/ S
. D'après mon expérience, si un processus est bloqué dans D
, il s'agit le plus souvent d'essayer de communiquer avec un NFS inaccessible ou un autre système de fichiers distant, d'essayer d'accéder à un disque dur défaillant, ou de faire usage d'une pièce de matériel par le biais d'un pilote de périphérique flasque. Dans de tels cas, la seule façon de récupérer et de permettre au processus de mourir est soit de remettre le fs/drive/hardware en marche pour que l'E/S puisse terminer, soit d'abandonner et de redémarrer le système. Dans le cas particulier de NFS, le montage peut aussi éventuellement s'arrêter et revenir de l'opération d'E/S (avec un code de défaillance), mais cela dépend des options de montage et il est très courant que les montages NFS soient définis pour attendre éternellement.
c'est distinct d'un processus zombie, qui aura un statut de Z
.
vérifiez que le parent-id est vraiment 1. Si non, et c'est firefox
, essayez d'abord de sudo killall -9 firefox-bin
. Après cela, essayez de tuer le processus spécifique IDs individuellement avec sudo killall -9 [process-id]
.
Comment est-il possible pour un processus de ne pas écouter kill -9 (neiter en tant qu'utilisateur ou root)?
si un processus est allé <defunct>
et devient alors un zombie avec un parent de 1, vous ne pouvez pas le tuer manuellement; seulement init
peut. Les processus zombies sont déjà morts et partis - ils ont perdu la possibilité d'être tués car ils ne sont plus des processus, seulement une entrée de table de processus et son code de sortie associé, en attente d'être collecté. Vous devez tuer le parent, et vous ne pouvez pas tuer init
pour des raisons évidentes.
mais voir ici pour plus d'Informations générales. Un redémarrage sera tuer tout, naturellement.
est-il possible que ce processus soit redémarré (par exemple par init) juste au moment où vous le tuez?
Vous pouvez le vérifier facilement. Si le PID est le même après kill -9 PID
alors le processus n'a pas été tué, mais s'il a changé le processus a été redémarré.
je me suis récemment pris au piège dans un piège de double fourche et avait atterri à cette page avant de finalement trouver ma réponse. Les symptômes sont identiques, même si le problème n'est pas la même:
- WYKINWYT :Ce que Vous Tuer n'Est Pas Ce que Vous avez Pensé
le code d'essai minimal est montré ci-dessous basé sur un exemple pour un démon SNMP
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
int main(int argc, char* argv[])
{
//We omit the -f option (do not Fork) to reproduce the problem
char * options[]={"/usr/local/sbin/snmpd",/*"-f","*/-d","--master=agentx", "-Dagentx","--agentXSocket=tcp:localhost:1706", "udp:10161", (char*) NULL};
pid_t pid = fork();
if ( 0 > pid ) return -1;
switch(pid)
{
case 0:
{ //Child launches SNMP daemon
execv(options[0],options);
exit(-2);
break;
}
default:
{
sleep(10); //Simulate "long" activity
kill(pid,SIGTERM);//kill what should be child,
//i.e the SNMP daemon I assume
printf("Signal sent to %d\n",pid);
sleep(10); //Simulate "long" operation before closing
waitpid(pid);
printf("SNMP should be now down\n");
getchar();//Blocking (for observation only)
break;
}
}
printf("Bye!\n");
}
au cours de la première phase le principal processus (7699) lance le démon SNMP (7700) mais on peut voir que celui-ci est maintenant Défunte/Zombie . À côté nous pouvons voir un autre processus (7702) avec les options nous avons spécifié
[nils@localhost ~]$ ps -ef | tail
root 7439 2 0 23:00 ? 00:00:00 [kworker/1:0]
root 7494 2 0 23:03 ? 00:00:00 [kworker/0:1]
root 7544 2 0 23:08 ? 00:00:00 [kworker/0:2]
root 7605 2 0 23:10 ? 00:00:00 [kworker/1:2]
root 7698 729 0 23:11 ? 00:00:00 sleep 60
nils 7699 2832 0 23:11 pts/0 00:00:00 ./main
nils 7700 7699 0 23:11 pts/0 00:00:00 [snmpd] <defunct>
nils 7702 1 0 23:11 ? 00:00:00 /usr/local/sbin/snmpd -Lo -d --master=agentx -Dagentx --agentXSocket=tcp:localhost:1706 udp:10161
nils 7727 3706 0 23:11 pts/1 00:00:00 ps -ef
nils 7728 3706 0 23:11 pts/1 00:00:00 tail
après la simulation de 10 Secondes nous allons essayer de tuer le seul processus que nous connaissons (7700). Ce que nous réussissons enfin avec waitpid() . Mais le processus 7702 est toujours là
[nils@localhost ~]$ ps -ef | tail
root 7431 2 0 23:00 ? 00:00:00 [kworker/u256:1]
root 7439 2 0 23:00 ? 00:00:00 [kworker/1:0]
root 7494 2 0 23:03 ? 00:00:00 [kworker/0:1]
root 7544 2 0 23:08 ? 00:00:00 [kworker/0:2]
root 7605 2 0 23:10 ? 00:00:00 [kworker/1:2]
root 7698 729 0 23:11 ? 00:00:00 sleep 60
nils 7699 2832 0 23:11 pts/0 00:00:00 ./main
nils 7702 1 0 23:11 ? 00:00:00 /usr/local/sbin/snmpd -Lo -d --master=agentx -Dagentx --agentXSocket=tcp:localhost:1706 udp:10161
nils 7751 3706 0 23:12 pts/1 00:00:00 ps -ef
nils 7752 3706 0 23:12 pts/1 00:00:00 tail
après avoir donné un caractère au getchar() fonction de nos principaux processus se termine, mais le démon SNMP avec le pid 7002 est toujours là
[nils@localhost ~]$ ps -ef | tail
postfix 7399 1511 0 22:58 ? 00:00:00 pickup -l -t unix -u
root 7431 2 0 23:00 ? 00:00:00 [kworker/u256:1]
root 7439 2 0 23:00 ? 00:00:00 [kworker/1:0]
root 7494 2 0 23:03 ? 00:00:00 [kworker/0:1]
root 7544 2 0 23:08 ? 00:00:00 [kworker/0:2]
root 7605 2 0 23:10 ? 00:00:00 [kworker/1:2]
root 7698 729 0 23:11 ? 00:00:00 sleep 60
nils 7702 1 0 23:11 ? 00:00:00 /usr/local/sbin/snmpd -Lo -d --master=agentx -Dagentx --agentXSocket=tcp:localhost:1706 udp:10161
nils 7765 3706 0 23:12 pts/1 00:00:00 ps -ef
nils 7766 3706 0 23:12 pts/1 00:00:00 tail
Conclusion
le fait que nous ayons ignoré le mécanisme double fourche nous a fait penser que l'action de tuer n'a pas réussi. Mais en fait, nous avons simplement tué le mauvais processus !!
en ajoutant l'option - f (do Not (Double) Fork ) all go comme prévu
sudo killall -9 firefox
devrait fonctionner
EDITION: [PID] a changé de firefox
vous pouvez aussi faire un pstree et tuer le parent. Cela fait en sorte que vous obtenez l'arbre entier de processus offensant et pas seulement la feuille.