¿Qué pasa si 'kill -9' no funciona?


466

Tengo un proceso con el que no puedo matar kill -9 <pid>. ¿Cuál es el problema en tal caso, especialmente porque soy el dueño de ese proceso? Pensé que nada podría evadir esa killopción.

Respuestas:


560

kill -9( SIGKILL ) siempre funciona, siempre que tenga permiso para eliminar el proceso. Básicamente, el proceso debe ser iniciado por usted y no ser setuid o setgid, o debe ser root. Hay una excepción: incluso el root no puede enviar una señal fatal al PID 1 (el initproceso).

Sin embargo, kill -9no se garantiza que funcione de inmediato . Todas las señales, incluida SIGKILL, se entregan de forma asíncrona: el núcleo puede tardar en entregarlas. Por lo general, la entrega de una señal lleva como máximo unos pocos microsegundos, justo el tiempo que le toma al objetivo obtener un segmento de tiempo. Sin embargo, si el objetivo ha bloqueado la señal , la señal se pondrá en cola hasta que el objetivo la desbloquee.

Normalmente, los procesos no pueden bloquear SIGKILL. Pero el código del núcleo puede y los procesos ejecutan el código del núcleo cuando llaman a las llamadas del sistema . El código del kernel bloquea todas las señales cuando la interrupción de la llamada del sistema daría como resultado una estructura de datos mal formada en algún lugar del kernel, o más generalmente en la violación de algún invariante del kernel. Entonces, si (debido a un error o diseño incorrecto) una llamada del sistema se bloquea indefinidamente, es posible que no haya forma de matar el proceso. (Sin embargo, el proceso va a ser matado si alguna vez se completa la llamada al sistema.)

Un proceso bloqueado en una llamada al sistema está en suspensión ininterrumpida . El comando pso top(en la mayoría de los dispositivos) lo mostrará en estado D(originalmente para " d isk", creo).

Un caso clásico de suspensión prolongada e ininterrumpida es el acceso a archivos a través de NFS cuando el servidor no responde; Las implementaciones modernas tienden a no imponer la suspensión ininterrumpida (por ejemplo, en Linux, la intropción de montaje permite que una señal interrumpa el acceso a los archivos NFS).

A veces puede ver entradas marcadas Z(o Hen Linux, no sé cuál es la distinción) en la salida pso top. Estos no son técnicamente procesos, son procesos zombies, que no son más que una entrada en la tabla de procesos, guardados para que el proceso padre pueda ser notificado de la muerte de su hijo. Se irán cuando el proceso principal preste atención (o muera).


92
Su respuesta parece contradictoria. Empiezas a decir que SIGKILL siempre funciona, pero terminas citando el caso de suspensión ininterrumpida, donde SIGKILL podría nunca funcionar fuera de cerrar el núcleo. También hay dos casos en los que SIGKILL no funciona. Obviamente, con zombis, ya que no puedes matar procesos ya muertos y con init, que por diseño ignora las señales de SIGKILL.
jlliagre

41
@jlliagre: matar a un zombie no tiene sentido, para empezar no está vivo. Y matando a un proceso en el sueño interrumpible hace el trabajo, es sólo (al igual que con otras señales) asíncrono. Intenté aclarar esto en mi edición.
Gilles

3
También escribí que matar a un zombie no tiene sentido, pero eso no impide que muchas personas lo intenten y se quejen. Matar un proceso en suspensión interrumpible de hecho funciona por diseño, pero estaba hablando de matar un proceso en suspensión ininterrumpible que puede fallar si la llamada al sistema nunca se activa.
jlliagre

11
man 5 nfs: "La opción intr/ nointrmount está en desuso después del núcleo 2.6.25. Solo SIGKILL puede interrumpir una operación NFS pendiente en estos núcleos, y si se especifica, esta opción de montaje se ignora para proporcionar compatibilidad con versiones anteriores de núcleos".
Martin Schröder

44
@ imz - IvanZakharyaschev No que yo sepa (pero podría no saber). Con sshfs, como último recurso, puede matar el sshfsproceso (y de la misma manera con cualquier otro sistema de archivos FUSE: siempre puede forzar el desmontaje de esta manera).
Gilles

100

En algún momento el proceso existe y no puede ser eliminado debido a:

  • siendo zombie Es decir, procesar qué padre no leyó el estado de salida. Dicho proceso no consume ningún recurso, excepto la entrada PID. En topella se señala Z
  • sueño ininterrumpido erróneo. No debería suceder, pero con una combinación de código de kernel defectuoso y / o hardware defectuoso lo hace en algún momento. El único método es reiniciar o esperar. En topella está señalado por D.

2
¿El zombi no consume recursos?
Luc M

77
@Luc M: AFAIK no (al menos en Linux) - con excepción de la entrada en la tabla de proceso (es decir, PID junto con información como el propietario, el estado de salida, etc.). Es solo el proceso el que espera el acuse de recibo del participante de que finalizó.
Maciej Piechotka

18
@xenoterracide: Eventualmente sí, pero si el proceso padre sigue vivo (por ejemplo, es una sesión de gnomo o algo que cumple una función similar), aún puede tener zombies. Técnicamente, es tarea de los padres limpiar, pero si el zombi queda huérfano, init limpia después (la terminología es la razón por la cual las clases de Unix se realizan con las puertas cerradas; cualquiera que escuche sobre huérfanos, zombis y asesinatos en una oración puede tener impresiones equivocadas).
Maciej Piechotka

55
"... el único método es reiniciar o esperar". ¿Cuánto tiempo esperar? Han pasado cinco meses y mis zombis siguen ahí.
DarenW

3
@DarenW hasta que el padre reconozca la muerte de los niños. Para más detalles, consulte al autor del programa.
Maciej Piechotka

32

Parece que podrías tener un proceso zombie . Esto es inofensivo: el único recurso que consume un proceso zombie es una entrada en la tabla de procesos. Desaparecerá cuando el proceso padre muera o reaccione a la muerte de su hijo.

Puedes ver si el proceso es un zombie usando topo el siguiente comando:

ps aux | awk '$8=="Z" {print $2}'

14
Umm, siempre me disgusta este tipo de nombres de campo "duros" ps. ¿Quién puede estar seguro de que el campo requerido siempre será el octavo, con todas las implementaciones psen todos los Unices?
syntaxerror

26

Verifique su /var/log/kern.logy /var/log/dmesg(o equivalentes) en busca de pistas. En mi experiencia, esto me ha sucedido solo cuando la conexión de red de una montura NFS se ha caído repentinamente o un controlador de dispositivo se ha bloqueado. Podría suceder si un disco duro también falla, creo.

Puede usar lsofpara ver qué archivos de dispositivo ha abierto el proceso.


66
+1 por mención de NFS. Hace unos años, esto me sucedió cada dos meses: si el servidor NFS fallaba, los clientes NFS en todos los cuadros RHEL (parcheados) se colgarían. kill -9por lo general no funcionó, incluso después de esperar 60 minutos. La única solución fue reiniciar.
Stefan Lasiewski

17

Si las respuestas de @ Maciej y @ Gilles no resuelven su problema, y ​​no reconoce el proceso (y preguntar qué es con su distribución no arroja respuestas). Verifique si hay Rootkit y cualquier otro signo que le haya pertenecido . Un rootkit es más que capaz de evitar que mates el proceso. De hecho, muchos son capaces de evitar que los veas. Pero si se olvidan de modificar 1 programa pequeño, podrían verse (por ejemplo, modificaron top, pero no htop). Lo más probable es que este no sea el caso, pero es mejor prevenir que curar.


Supongo que muchos rootkits se insertan en el kernel para simplificar las cosas (no es necesario adivinar qué tienen los usuarios y descargar MB de programas parcheados). Sin embargo, todavía vale la pena verificarlo (++ votos).
Maciej Piechotka

11

Matar en realidad significa enviar una señal. Hay múltiples señales que puede enviar. kill -9 es una señal especial.

Al enviar una señal, la aplicación se ocupa de ello. si no, el kernel lo trata. para que pueda atrapar una señal en su aplicación.

Pero dije que matar -9 era especial. Es especial porque la aplicación no lo entiende. va directamente al kernel que luego mata realmente la aplicación en la primera oportunidad posible. en otras palabras, lo mata

kill -15 envía la señal SIGTERM que significa SIGNAL TERMINATE en otras palabras, le dice a la aplicación que se cierre. Esta es la manera amigable de decirle a una aplicación que es hora de cerrarla. pero si la aplicación no responde, kill -9 la matará.

si kill -9 no funciona, probablemente significa que su núcleo está fuera de control. un reinicio está en orden. No recuerdo que eso haya pasado.


55
15 es SIGTERM (asesinato amistoso), no SIGHUP. SIGHUP es para el terminal de control que se cierra o el canal de comunicación se pierde
JoelFan

11

Primero, verifique si es un proceso Zombie (que es muy posible):

ps -Al

Verás algo como:

0 Z  1000 24589     1  0  80   0 -     0 exit   ?        00:00:00 soffice.bin <defunct>

(Tenga en cuenta la "Z" a la izquierda)

Si la quinta columna no es 1, significa que tiene un proceso padre. Intenta eliminar esa identificación de proceso principal .

Si es PPID = 1, ¡NO LO MATES ! , piense qué otros dispositivos o procesos pueden estar relacionados con él.

Por ejemplo, si estaba utilizando un dispositivo montado o una samba, intente desmontarlo. Eso puede liberar el proceso Zombie.

NOTA : Si ps -Al(o top) muestra una "D" en lugar de "Z", podría estar relacionado con el montaje remoto (como NFS). En mi experiencia, reiniciar es la única forma de llegar allí, pero puede verificar las otras respuestas que cubren ese caso con más detalle.


1
Enviar SIGCHLD al proceso principal puede hacer que los padres reconozcan que el proceso ha muerto. Esto debería funcionar incluso cuando el PPID = 1. Esto normalmente lo envía el núcleo, pero también se puede enviar al padre a través de kill (kill -17 en Linux, consulte las páginas de manual en otro * nix). Este uso de kill en realidad no "matará" al padre, sino que (re) le informa que un niño ha muerto y necesita ser limpiado. Tenga en cuenta que sigchld debe enviarse al padre del zombie, no al zombie en sí.
Stephanie

10

El proceso de inicio es inmune a SIGKILL.

Esto también es cierto también para los hilos del núcleo, es decir, "procesos" con un PPID igual a 0.


1
Las tareas del kernel también pueden ser inmunes a SIGKILL. Esto sucede a menudo con Btrfs.
Tobu

9

Como otros han mencionado, un proceso en sueño ininterrumpido no se puede matar de inmediato (o, en algunos casos, en absoluto). Vale la pena señalar que se agregó otro estado de proceso, TASK_KILLABLE, para resolver este problema en ciertos escenarios, particularmente el caso común donde el proceso está esperando en NFS. Ver http://lwn.net/Articles/288056/

Desafortunadamente, no creo que esto se use en ningún otro lugar del núcleo, excepto en NFS.


Tuve problemas para eliminar un lsproceso de acceso a una sshfsmontura, cuando el servidor remoto se ha vuelto inalcanzable. ¿Existe una solución para FUSE o sshfs, que podría usar en el futuro para evitar tales situaciones? 2.6.30 kernel
imz - Ivan Zakharyaschev

@imz Un consejo de Gilles (para matar sshfs) está ahí: unix.stackexchange.com/a/5648/4319 .
imz - Ivan Zakharyaschev

6

¡Hice un pequeño guión que me ayudó mucho a echar un vistazo!

Puede usarlo para eliminar cualquier proceso con un nombre de pila en su camino (¡preste atención a esto!) O puede eliminar cualquier proceso de un usuario determinado utilizando el parámetro "-u nombre de usuario".

#!/bin/bash

if [ "$1" == "-u" ] ; then\n
        PID=`grep "$2" /etc/passwd | cut -d ":" -f3`
        processes=`ps aux | grep "$PID" | egrep -v "PID|ps \-au|killbyname|grep" | awk '{ print $2}'`
        echo "############# Killing all processes of user: $2 ############################"
else
        echo "############# Killing processes by name: $1 ############################"
        processes=`ps aux | grep "$1" | egrep -v "killbyname|grep" | awk '{ print $2}' `
fi


for process in $processes ; do
        # "command" stores the entire commandline of the process that will be killed
        #it may be useful to show it but in some cases it is counter-productive
        #command=`ps aux | grep $process | egrep -v "grep" | awk '{ print $2 }'`
        echo "Killing process: $process"
        echo ""
        kill -9 $process
done

44
En lugar de simplemente vincularlo, ¿puede publicar el código aquí?
tshepang

3
Agregue un poco de descripción con (o al menos en su lugar) del código ...
vonbrand

Sí, pero el "$ nombre" se está agregando más ... matará cualquier proceso con "$ nombre" en su ruta de ejecución. Puede ser muy útil si tiene estas enormes líneas de comando y no sabe cuál es el nombre del proceso.
user36035

5

Hay casos en los que incluso si envía un kill -9 a un proceso, ese pid se detendrá, pero el proceso se reinicia automáticamente (por ejemplo, si lo intenta con gnome-panel, se reiniciará): ¿podría ser ese el caso aquí?


8
Cuando sucede algo como esto, el PID realmente cambia. Entonces me habría dado cuenta.
tshepang

2

de aquí originalmente :

comprobar si strace muestra algo

strace -p <PID>

intente adjuntar al proceso con gdb

gdb <path to binary> <PID>

si el proceso estaba interactuando con un dispositivo que puede desmontar, quitar el módulo del núcleo o desconectar / desconectar físicamente ... intente eso.


¡Trabajó para mi! (desconectando el dispositivo USB, que estaba colgando texto sublime)
nmz787

1

Tuve una especie de este problema. Este era un programa que había lanzado stracee interrumpido con Ctrl+ C. Terminó en un estado T(rastreado o detenido). No sé cómo sucedió exactamente, pero no se pudo matar SIGKILL.

En pocas palabras, logré matarlo con gdb:

gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit

-1

Basado en una pista de la respuesta de Gilles, tenía un proceso marcado "Z" en la parte superior ( <defunct>en ps) que estaba usando recursos del sistema, incluso tenía un puerto abierto que estaba ESCUCHANDO y se podía conectar a ese puerto. Esto fue después de ejecutar un kill -9en él. Su padre era "1" (es decir init) teóricamente, debería repetirse y desaparecer. Pero no fue así, se quedó, aunque no estaba corriendo, y "no moría"

Entonces, en mi caso, era zombie pero aún consumía recursos ... FWIW.

Y no era killable por cualquier número de kill -9's

Y su padre era initpero no estaba siendo cosechado (limpiado). Es decir, inittenía un niño zombi.

Y reiniciar no fue necesario para solucionar el problema. Aunque un reinicio "habría funcionado" en torno al problema / hizo que el apagado fuera más rápido. Simplemente no agraciado, que todavía era posible.

Y era un puerto LISTEN propiedad de un proceso zombie (y algunos otros puertos también como el estado CLOSE_WAIT conectado localhost a localhost). Y aun así aceptó conexiones. Incluso como un zombie. Supongo que todavía no había llegado a limpiar los puertos, por lo que las conexiones entrantes todavía se agregaron a la cartera de pedidos del puerto de escucha tcp, aunque no tenían ninguna posibilidad de ser aceptadas.

Muchos de los anteriores se declaran como "imposibles" en varios lugares en las redes.

Resulta que tenía un hilo interno dentro que estaba ejecutando una "llamada al sistema" (ioctl en este caso) que estaba demorando unas horas en regresar (este era el comportamiento esperado). Aparentemente, el sistema no puede matar el proceso "hasta el final" hasta que regrese de la ioctlllamada, supongo que entra en la tierra del kernel. Después de unas horas regresó, las cosas se aclararon y los enchufes se cerraron automáticamente, etc., como se esperaba. ¡Ese es un tiempo de languidez en el corredor de la muerte! El grano esperaba pacientemente para matarlo.

Entonces, para responder el OP, a veces hay que esperar. Mucho tiempo. Entonces la muerte finalmente se llevará.

También verifique dmesg para ver si hubo un kernel panic (es decir, un error del kernel).


Parece que estás describiendo tu propio escenario específico en lugar de una respuesta a la pregunta. En su caso, el proceso se arregló por sí solo debido a una operación de larga duración, algo que no se menciona en la pregunta. Sin embargo, puede hacer una nueva pregunta y responderla también. Aunque me temo que esa pregunta podría cerrarse como "no reproducible", ya que el resultado es específico para su implementación.
Centimane

Es cierto, agregué cómo responde OP, ya que ... podría, en algunos casos.
rogerdpack
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.