it-swarm-pt.tech

E se 'kill -9' não funcionar?

Eu tenho um processo que não consigo matar com kill -9 <pid>. Qual é o problema nesse caso, principalmente porque sou o proprietário desse processo. Eu pensei que nada poderia escapar dessa opção kill.

491
tshepang

kill -9 ( SIGKILL ) sempre funciona, desde que você tenha permissão para interromper o processo. Basicamente, o processo deve ser iniciado por você e não ser setuid ou setgid, ou você deve ser root. Há uma exceção: mesmo o root não pode enviar um sinal fatal para o PID 1 (o processo init).

Contudo kill -9 não é garantido que funcione imediatamente. Todos os sinais, incluindo o SIGKILL, são entregues de forma assíncrona: o kernel pode demorar para entregá-los. Geralmente, a entrega de um sinal leva no máximo alguns microssegundos, o tempo necessário para o alvo obter uma fatia de tempo. No entanto, se o alvo tiver bloqueado o sinal , o sinal ficará na fila de espera até que o alvo o desbloqueie.

Normalmente, os processos não podem bloquear o SIGKILL. Mas o código do kernel pode, e os processos executam o código do kernel quando chamam chamadas do sistema . O código do kernel bloqueia todos os sinais ao interromper a chamada do sistema, resultando em uma estrutura de dados mal formada em algum lugar do kernel ou, mais geralmente, em alguma invariância do kernel sendo violada. Portanto, se (devido a um erro ou erro de design) uma chamada do sistema é bloqueada indefinidamente, pode não haver maneira eficaz de interromper o processo. (Mas o processo será será eliminado se alguma vez concluir a chamada do sistema.)

Um processo bloqueado em uma chamada do sistema está em suspensão ininterrupta . O comando ps ou top (na maioria das unidades) o mostrará no estado D (originalmente para “ d isk ”, eu acho).

Um caso clássico de suspensão ininterrupta é o processo de acesso a arquivos por NFS quando o servidor não está respondendo; implementações modernas tendem a não impor suspensão ininterrupta (por exemplo, no Linux, a opção de montagem intr permite que um sinal interrompa o acesso a arquivos NFS).

Às vezes, você pode ver entradas marcadas com Z (ou H no Linux, não sei qual é a distinção) na saída ps ou top. Tecnicamente, esses não são processos, são processos zumbis, que nada mais são do que uma entrada na tabela de processos, mantidos em torno para que o processo pai possa ser notificado da morte de seu filho. Eles desaparecem quando o processo pai presta atenção (ou morre).

577

Algum processo existe e não pode ser eliminado devido a:

  • sendo zumbi. I.e. processo cujo pai não leu o status de saída. Esse processo não consome nenhum recurso, exceto a entrada do PID. Em top é sinalizado Z
  • sono ininterrupto e errôneo. Isso não deveria acontecer, mas com uma combinação de código do kernel com bugs e/ou hardware com bugs, algumas vezes acontece. O único método é reiniciar ou aguardar. Em top é sinalizado por D.
101
Maciej Piechotka

Parece que você pode ter um processo de zumbi . Isso é inofensivo: o único recurso que um processo zumbi consome é uma entrada na tabela de processos. Ele desaparecerá quando o processo pai morrer ou reagir à morte de seu filho.

Você pode ver se o processo é um zumbi usando top ou o seguinte comando:

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

Verifique seu /var/log/kern.log e /var/log/dmesg (ou equivalentes) para qualquer pista. Na minha experiência, isso aconteceu comigo apenas quando a conexão de rede de uma montagem NFS caiu de repente ou um driver de dispositivo travou. Poderia acontecer se um disco rígido travar também, acredito.

Você pode usar lsof para ver quais arquivos de dispositivo o processo abriu.

26
LawrenceC

Se as respostas de @ Maciej e @ Gilles não solucionam seu problema, e você não reconhece o processo (e perguntar o que há com sua distribuição não faz aparecer respostas). Verifique o Rootkit e quaisquer outros sinais de que você pertence . Um rootkit é mais do que capaz de impedir que você interrompa o processo. De fato, muitos são capazes de impedir que você os veja. Mas se eles esquecerem de modificar 1 programa pequeno, poderão ser detectados (por exemplo, eles modificaram top, mas não htop). Provavelmente não é esse o caso, mas é melhor prevenir do que remediar.

17
xenoterracide

Matar, na verdade, significa enviar um sinal. existem vários sinais que você pode enviar. kill -9 é um sinal especial.

Ao enviar um sinal, o aplicativo lida com ele. caso contrário, o kernel lida com isso. para que você possa capturar um sinal em seu aplicativo.

Mas eu disse que matar -9 era especial. É especial porque o aplicativo não o entende. vai direto para o kernel, que realmente mata o aplicativo na primeira oportunidade possível. em outras palavras, mata-o morto

kill -15 envia o sinal SIGTERM, que significa SIGNAL TERMINATE, em outras palavras, diz ao aplicativo para sair. Essa é a maneira mais fácil de dizer a um aplicativo que é hora de desligar. mas se o aplicativo não estiver respondendo, kill -9 o matará.

se kill -9 não funcionar, provavelmente significa que seu kernel está fora de sintonia. uma reinicialização está em ordem. Não me lembro de isso ter acontecido.

11
DeveloperChris

Primeiro, verifique se é um processo Zombie (o que é muito possível):

ps -Al

Você verá algo como:

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

(Observe o "Z" à esquerda)

Se a quinta coluna não for 1, significa que ele possui um processo pai. Tente matar o ID do processo pai.

Se seu PPID = 1, NÃO O MATE !!, pense em quais outros dispositivos ou processos podem estar relacionados a ele.

Por exemplo, se você estava usando um dispositivo montado ou samba, tente desmontá-lo. Isso pode liberar o processo Zombie.

NOTE : Se ps -Al (ou top) mostra um "D" em vez de "Z", isso pode estar relacionado à montagem remota (como NFS). Na minha experiência, a reinicialização é o único caminho a percorrer, mas você pode verificar as outras respostas que abordam esse caso em mais detalhes.

11
lepe

O processo init é imune ao SIGKILL.

Isso também se aplica a threads do kernel, ou seja, "processos" com um PPID igual a 0.

10
jlliagre

Como outros já mencionaram, um processo em sono ininterrupto não pode ser morto imediatamente (ou, em alguns casos, de maneira alguma). Vale ressaltar que outro estado do processo, TASK_KILLABLE, foi adicionado para resolver esse problema em certos cenários, particularmente no caso comum em que o processo está aguardando no NFS. Veja http://lwn.net/Articles/288056/

Infelizmente, não acredito que isso seja usado em nenhum lugar do kernel, exceto no NFS.

10
user36054

Fiz um pequeno roteiro que me ajudou bastante a dar uma olhada!

Você pode usá-lo para eliminar qualquer processo com um determinado nome em seu caminho (preste atenção a isso!) Ou pode matar qualquer processo de um determinado usuário usando o parâmetro "-u nome de usuário".

#!/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
6
user36035

Há casos em que, mesmo que você envie um kill -9 para um processo, esse pid será interrompido, mas o processo será reiniciado automaticamente (por exemplo, se você tentar com gnome-panel, ele será reiniciado): poderia ser esse o caso aqui?

5
dag729

de aqui originalmente :

verifique se strace mostra alguma coisa

strace -p <PID>

tente anexar ao processo com gdb

gdb <path to binary> <PID>

se o processo estiver interagindo com um dispositivo que você pode desmontar, remova o módulo do kernel ou desconecte/desconecte fisicamente ... tente isso.

2
nmz787

Eu tive esse problema. Este foi um programa que eu lancei com strace e interrompi com Ctrl + C. Terminou em um estado T (rastreado ou parado). Não sei exatamente como aconteceu, mas não foi possível matar com SIGKILL.

Para encurtar a história, consegui matá-lo com gdb:

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

Baseado em uma pista da resposta de gilles, eu tinha um processo marcado como "Z" ("" no ps) que estava usando recursos do sistema, ele até tinha uma porta aberta que estava LISTEN'ing e era possível conectar-se a ela. Isso foi depois de executar um kill -9 nele. Seu pai era "1" (ou seja, init), portanto teoricamente deveria desaparecer. Mas não era, estava por aí, embora não estivesse correndo.

Então, no meu caso, era zumbi, mas ainda consumia recursos ... FWIW.

E não era matável por kill -9.

E seu pai era init mas não estava sendo colhido (limpo). I.e. init teve um filho zumbi.

E a reinicialização não era necessária para corrigir o problema. Embora uma reinicialização "tenha funcionado" em torno do problema/o tenha tornado mais rápido o desligamento. Apenas não gracioso, o que ainda era possível.

E era uma porta LISTEN de propriedade de um processo zumbi (e algumas outras portas também, como o status CLOSE_WAIT, conectavam host local a host local). E ainda aceitava conexões. Mesmo como um zumbi. Eu acho que ainda não havia conseguido limpar as portas, portanto as conexões recebidas ainda foram adicionadas ao backlog da porta de escuta do tcp, embora elas não tivessem chance de serem aceitas.

Acontece que eu tinha um thread interno que estava executando uma "chamada de sistema" (ioctl nesta instância) que estava demorando algumas horas para retornar (isso era esperado). Aparentemente, o sistema não pode matá-lo "até o fim" até que ele retorne. Depois de algumas horas, tudo ficou limpo e as tomadas foram fechadas automaticamente, etc., conforme o esperado. Isso é algum tempo de morte enfraquecido!

Verifique também o dmesg para ver se houve um pânico no kernel (ou seja, bug do kernel).

0
rogerdpack