force - kill-9 linux
¿Cómo es posible que kill-9 para un proceso en Linux no tenga ningún efecto? (7)
Últimamente me quedé atrapado en una trampa de Double Fork y había aterrizado en esta página antes de encontrar finalmente mi respuesta. Los síntomas son idénticos, incluso si el problema no es el mismo:
- WYKINWYT: Lo que matas no es lo que pensabas
El código de prueba mínimo se muestra a continuación basado en un ejemplo para un Daemon de 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");
}
Durante la primera fase, el proceso principal (7699) inicia el daemon de SNMP (7700) pero podemos ver que este ahora es Defunct / Zombie . Al lado podemos ver otro proceso (7702) con las opciones que especificamos
[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
Después de simular los 10 segundos, intentaremos matar al único proceso que conocemos (7700). Lo que finalmente tenemos éxito con waitpid () . Pero el Proceso 7702 todavía está aquí
[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
Después de darle un carácter a la función getchar (), nuestro proceso principal finaliza pero el daemon SNMP con el pid 7002 todavía está aquí.
[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
Conclusión
El hecho de que ignoramos el mecanismo de doble horquilla nos hizo pensar que la acción de matar no tuvo éxito. ¡Pero de hecho simplemente matamos el proceso equivocado!
Al agregar la opción -f (Tenedor Do not (Double)) todo sale como se esperaba
Estoy escribiendo un complemento para resaltar las cadenas de texto automáticamente al visitar un sitio web. Es como los resultados de búsqueda más destacados, pero automático y para muchas palabras; podría usarse para personas con alergias para hacer que las palabras realmente se destaquen, por ejemplo, cuando exploran un sitio de comida.
Pero tengo un problema. Cuando trato de cerrar una ventana FF vacía y fresca, de alguna manera bloquea todo el proceso. Cuando elimino el proceso, todas las ventanas se desvanecen, pero el proceso de Firefox permanece vivo (el PID padre es 1, no escucha ninguna señal, tiene muchos recursos abiertos, todavía come CPU, pero no se moverá).
Entonces dos preguntas:
¿Cómo es posible que un proceso no escuche kill -9 (ni como usuario ni como root)?
¿Hay algo que pueda hacer, pero un reinicio?
[EDITAR] Este es el proceso ofensivo:
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
Lo mismo con ps -ef | grep firefox
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
Es el único proceso que queda. Como puedes ver, no es un zombie, ¡se está ejecutando! No escucha matar -9, ¡no importa si mato por PID o nombre! Si trato de conectarme con strace
, entonces el strace
también se cuelga y no se puede matar. No hay salida, tampoco. Mi suposición es que FF se cuelga en alguna rutina kernel, pero ¿cuál?
[EDIT2] Basado en la retroalimentación de sigjuice:
ps axopid,comm,wchan
puede mostrarle en qué rutina del kernel se cuelga un proceso. En mi caso, el complemento ofensivo era el indexador de Beagle (openSUSE 11.1). Después de deshabilitar el complemento, FF era un zorro rápido y feliz de nuevo.
¿Es posible que este proceso se reinicie (por ejemplo, por init) justo en el momento en que lo mata?
Puedes verificar esto fácilmente. Si el PID es el mismo después de kill -9 PID
entonces el proceso no se eliminó, pero si ha cambiado, el proceso se ha reiniciado.
Como se señala en los comentarios al PO, un estado de proceso ( STAT
) de D
indica que el proceso está en un estado de "suspensión ininterrumpida". En términos del mundo real, esto generalmente significa que está esperando E / S y no puede / no hará nada, incluido el tiempo de espera, hasta que la operación de E / S se complete.
Los procesos en un estado D
normalmente solo estarán allí durante una fracción de segundo antes de que la operación se complete y vuelvan a R
/ S
En mi experiencia, si un proceso se atasca en D
, a menudo intenta comunicarse con un NFS inalcanzable u otro sistema de archivos remoto, tratando de acceder a un disco duro defectuoso, o haciendo uso de algún hardware a través de un controlador de dispositivo escamoso. . En tales casos, la única forma de recuperar y permitir que el proceso muera es hacer que la unidad fs / drive / hardware vuelva a funcionar para que la E / S pueda completar o renunciar y reiniciar el sistema. En el caso específico de NFS, el montaje también puede agotar el tiempo de espera y regresar de la operación de E / S (con un código de falla), pero esto depende de las opciones de montaje y es muy común que los montajes NFS se configuren para esperar para siempre. .
Esto es distinto de un proceso zombie, que tendrá un estado de Z
También puedes hacer un pstree y matar al padre. Esto asegura que obtienes todo el árbol del proceso infractor y no solo la hoja.
Verifique dos veces que el ID padre es realmente 1. Si no es así, y esto es firefox
, primero intente con sudo killall -9 firefox-bin
. Después de eso, intente eliminar los identificadores de proceso específicos individualmente con sudo killall -9 [process-id]
.
¿Cómo es posible que un proceso no escuche kill -9 (neiter como usuario ni como root)?
Si un proceso se ha ido <defunct>
y luego se convierte en un zombie con un padre de 1, no puede matarlo manualmente; solo init
puede Los procesos de Zombie ya están muertos y desaparecidos: han perdido la capacidad de ser eliminados porque ya no son procesos, solo una entrada de tabla de proceso y su código de salida asociado, a la espera de ser recopilados. Debes matar al padre y no puedes matar a init
por razones obvias.
Pero mira here para obtener más información general. Un reinicio matará a todo, naturalmente.
ps -ef | grep firefox; y puedes ver 3 procesos, mátalos a todos.
sudo killall -9 firefox
Deberia trabajar
EDITAR: [PID] cambiado a firefox