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


466

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

Respostas:


560

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 initprocesso).

No entanto, kill -9nã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, apenas 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 de eliminar o processo. (Mas o processo será interrompido se alguma vez concluir a chamada do sistema.)

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

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

Às vezes, você pode ver entradas marcadas Z(ou Hno Linux, não sei qual é a distinção) na saída psou 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).


92
Sua resposta parece contraditória. Você começa a dizer que o SIGKILL sempre funciona, mas termina citando o caso de suspensão ininterrupta, onde o SIGKILL pode nunca funcionar fora, desligando o kernel. Há também dois casos em que o SIGKILL não funciona. Com zumbis, obviamente, como você não pode matar processos já mortos e com init, que por padrão está ignorando os sinais da SIGKILL.
Jlliagre

41
@jlliagre: Matar um zumbi não faz sentido, não está vivo para começar. E matar um processo no sono interruptível faz o trabalho, é apenas (como com outros sinais) assíncrona. Eu tentei esclarecer isso na minha edição.
Gilles

3
Escrevi demais matar um zumbi não faz sentido, mas isso não impede que muitas pessoas tentem reclamar. Matar um processo em suspensão interrompida realmente funciona por design, mas eu estava falando sobre matar um processo em suspensão ininterrupta que pode falhar se a chamada do sistema nunca for ativada.
Jlliagre

11
man 5 nfs: "A opção intr/ nointrmount está obsoleta após o kernel 2.6.25. Somente o SIGKILL pode interromper uma operação NFS pendente nesses kernels e, se especificada, essa opção de montagem é ignorada para fornecer compatibilidade com versões anteriores dos kernels."
Martin Schröder

4
@ imz - IvanZakharyaschev Não que eu saiba (mas talvez eu não saiba). Com o sshfs, como último recurso, você pode interromper o sshfsprocesso (e da mesma forma que com qualquer outro sistema de arquivos FUSE: você sempre pode desmontar à força dessa maneira).
Gilles

100

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

  • sendo zumbi. Ou seja, processo que o pai não leu o status de saída. Esse processo não consome nenhum recurso, exceto a entrada do PID. Em topque Z é sinalizado
  • 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, ocorre algum dia. O único método é reiniciar ou aguardar. Em topque é sinalizado por D.

2
Zumbi não consome recursos?
Luc M

7
@ Luc M: AFAIK no (pelo menos no Linux) - com exceção da entrada na tabela de processos (ou seja, PID junto com informações como proprietário, status de saída etc.). É apenas um processo que aguarda o reconhecimento da parte que terminou.
Maciej Piechotka 11/01

18
@xenoterracide: Eventualmente sim, mas se o processo pai ainda estiver vivo (por exemplo, é uma sessão de gnome ou algo que desempenha papel semelhante), você ainda pode ter zumbis. Tecnicamente, é tarefa dos pais limpar, mas se o zumbi é órfão, o init limpa depois (a terminologia é a razão pela qual as classes unix são feitas com portas fechadas - qualquer pessoa que esteja ouvindo falar de órfãos, zumbis e assassinatos em uma frase pode ter impressões erradas).
Maciej Piechotka 11/01

5
"... único método é reiniciar ou esperar." Espere quanto tempo? Cinco meses se passaram e meus zumbis ainda estão lá.
darenw

3
@ DarenW até que os pais reconheçam a morte de filhos. Para mais detalhes, pergunte ao autor do programa.
Maciej Piechotka 16/01

32

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 topou o seguinte comando:

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

13
Umm, eu sempre não gosto desse tipo de nomes de campo "difíceis" ps. Quem pode ter certeza de que o campo obrigatório será sempre o 8º, com todas as implementações psem todos os Unices?
syntaxerror

26

Verifique seu /var/log/kern.loge /var/log/dmesg(ou equivalentes) em busca de pistas. 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 lsofpara ver quais arquivos de dispositivo o processo abriu.


6
+1 por menção ao NFS. Alguns anos atrás, isso acontecia comigo a cada dois meses - se o servidor NFS falhasse, os clientes NFS em todas as caixas RHEL (corrigidas) seriam interrompidos. kill -9normalmente não funcionava, mesmo depois de esperar 60 minutos. A única solução foi reiniciar.
Stefan Lasiewski

17

Se as respostas de @ Maciej e @ Gilles não resolverem o seu problema e você não reconhecer o processo (e perguntar o que há na sua distribuição não gera 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.


Eu acho que muitos rootkits se inserem no kernel para simplificar as coisas (não é necessário adivinhar o que o usuário tem e fazer o download de MBs de programas corrigidos). No entanto, ainda vale a pena conferir (++ ++).
Maciej Piechotka 12/01

11

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.


5
15 é SIGTERM (matança amigável), não SIGHUP. SIGHUP é para o terminal de controlo a ser fechado ou o canal de comunicações a ser perdido
JoelFan

11

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 o 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.

NOTA : Se ps -Al(ou top) mostrar um "D" em vez de "Z", isso poderá estar relacionado à montagem remota (como o 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.


1
Enviar SIGCHLD para o processo pai pode fazer com que o pai reconheça que o processo morreu. Isso deve funcionar mesmo quando o PPID = 1. Isso normalmente é enviado pelo kernel, mas também pode ser enviado ao pai via kill (kill -17 no Linux, verifique as páginas de manual em outro * nix). Esse uso de abate não "mata" o pai, mas (re) informa que uma criança morreu e precisa ser limpa. Observe que o sigchld deve ser enviado ao pai do zumbi, não ao próprio zumbi.
Stephanie

10

O processo init é imune ao SIGKILL.

Isso também é válido para os threads do kernel, ou seja, "processos" com um PPID igual a 0.


1
As tarefas do kernel também podem ser imunes ao SIGKILL. Isso acontece com bastante frequência com o Btrfs.
26413 Tobu

9

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 determinados 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.


Tive problemas para interromper um lsprocesso ao acessar uma sshfsmontagem, quando o servidor remoto se tornou inacessível. Existe uma solução para o FUSE ou sshfs, que eu possa usar no futuro para evitar essas situações? Kernel 2.6.30
imz - Ivan Zakharyaschev

@imz Existe um conselho de Gilles (para matar o sshfs) - unix.stackexchange.com/a/5648/4319 .
imz - Ivan Zakharyaschev 30/03

6

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 eliminar 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

4
Em vez de apenas vincular a ele, você pode postar o código aqui.
22413 tshepang

3
Adicione um pouco de descrição com (ou pelo menos em seu lugar) do código ...
vonbrand

Sim, mas o "$ name" é mais agregador ... ele matará qualquer processo com "$ name" em seu caminho de execução. Pode ser muito útil quando você possui essas enormes linhas de comando e não sabe qual é o nome do processo.
precisa saber é o seguinte

5

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-panelele, será reiniciado): poderia ser esse o caso aqui?


8
Quando algo assim acontece, o PID realmente muda. Então eu teria notado.
tshepang

2

a partir daqui originalmente :

verifique se strace mostra alguma coisa

strace -p <PID>

tente anexar ao processo com gdb

gdb <path to binary> <PID>

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


Trabalhou para mim! (desligar o dispositivo USB, que estava pendurado sublime-text)
nmz787

1

Eu tive esse problema. Este foi um programa que eu havia iniciado stracee interrompido com o Ctrl+ C. Acabou em um estado T(rastreado ou parado). Não sei exatamente como aconteceu, mas não foi matável 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

Com base em uma pista da resposta de gilles, eu tinha um processo marcado como "Z" no topo ( <defunct>em ps) que estava usando recursos do sistema, ele até tinha uma porta aberta que estava LISTEN'ing e você podia conectar-se a essa porta. Isso foi depois de executar um kill -9. Seu pai era "1" (ou seja init), então, teoricamente, deveria ser repetido e desaparecer. Mas não era, estava por aí, embora não estivesse correndo e "não morrendo"

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

E não era killable por qualquer número de kill -9's

E seu pai era, initmas não estava sendo colhido (limpo). Ou seja, initteve um filho zumbi.

E a reinicialização não era necessária para corrigir o problema. Embora uma reinicialização "tivesse funcionado" em torno do problema / o tornasse mais rápido. 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.

Muitos dos itens acima são declarados como "impossíveis" em vários lugares nas interwebs.

Acontece que eu tinha um encadeamento interno que estava executando uma "chamada de sistema" (ioctl nesta instância) que estava demorando algumas horas para retornar (esse era o comportamento esperado). Aparentemente, o sistema não pode matar o processo "até o fim" até retornar da ioctlchamada, suponha que entre no território do kernel. Depois de algumas horas, as coisas foram esclarecidas e as tomadas foram fechadas automaticamente, etc., conforme o esperado. Isso é algum tempo definhando no corredor da morte! O núcleo estava esperando pacientemente para matá-lo.

Então, para responder ao OP, às vezes você precisa esperar. Muito tempo. Então a matança finalmente levará.

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


Parece que você está descrevendo seu próprio cenário específico, e não uma resposta para a pergunta. No seu caso, o processo se consertou sozinho por causa de uma operação de execução longa, algo não mencionado na pergunta. No entanto, você pode fazer uma nova pergunta e fornecer a resposta para ela. Embora eu tema que essa pergunta possa ser encerrada como "não reproduzível", pois o resultado é específico para sua implementação.
Centimane 8/07

É verdade que eu adicionei como ele responde ao OP, uma vez que ... poderia, em alguns casos.
rogerdpack
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.