O que um programa faz quando é enviado o sinal SIGKILL?

39

Quando eu costumava killall -9 namematar um programa, o estado se tornava zumbi. Alguns minutos depois, parou realmente. Então, o que está acontecendo durante esses minutos?

haikun ele
fonte

Respostas:

66

Na verdade, o programa nunca recebe o sinal SIGKILL, pois o SIGKILL é completamente tratado pelo sistema operacional / kernel.

Quando o SIGKILL para um processo específico é enviado, o agendador do kernel para imediatamente, dando a esse processo mais tempo de CPU para executar o código do espaço do usuário. Se o processo tiver algum encadeamento executando o código do espaço do usuário em outras CPUs / núcleos no momento em que o planejador tomar essa decisão, esses encadeamentos também serão interrompidos. (Nos sistemas de núcleo único, isso era muito mais simples: se o único núcleo da CPU no sistema estava executando o agendador, por definição, não estava executando o processo ao mesmo tempo!)

Se o processo / encadeamento estiver executando o código do kernel (por exemplo, uma chamada do sistema ou uma operação de E / S associada a um arquivo mapeado na memória) no momento do SIGKILL, fica um pouco mais complicado: apenas algumas chamadas do sistema são interrompíveis, portanto, o O kernel marca internamente o processo como estando em um estado "morto" especial até que as chamadas do sistema ou operações de E / S sejam resolvidas. O tempo da CPU para resolvê-los será agendado como de costume. Chamadas de sistema interrompidas ou operações de E / S verificarão se o processo que as chamou está morrendo em qualquer ponto de parada adequado e sairão mais cedo nesse caso. Operações ininterruptas serão concluídas e verificarão o estado "morrendo" pouco antes de retornar ao código de espaço do usuário.

Depois que qualquer rotina do kernel em processo é resolvida, o estado do processo é alterado de "morto" para "morto" e o kernel começa a limpá-lo, semelhante a quando um programa sai normalmente. Depois que a limpeza for concluída, um código de resultado maior que 128 será atribuído (para indicar que o processo foi interrompido por um sinal; veja esta resposta para detalhes confusos ), e o processo passará para o estado "zumbi" . O pai do processo morto será notificado com um sinal SIGCHLD.

Como resultado, o próprio processo nunca terá a chance de realmente processar as informações que recebeu um SIGKILL.

Quando um processo está no estado "zumbi", significa que o processo já está morto, mas seu processo pai ainda não o reconheceu lendo o código de saída do processo morto usando a wait(2)chamada do sistema. Basicamente, o único recurso que um processo zumbi está consumindo mais é um espaço na tabela de processos que contém seu PID, o código de saída e algumas outras "estatísticas vitais" do processo no momento de sua morte.

Se o processo pai morrer antes de seus filhos, os processos filhos órfãos serão adotados automaticamente pelo PID # 1, que tem um dever especial de continuar ligando wait(2)para que qualquer processo órfão não fique como zumbi.

Se levar vários minutos para que um processo zumbi seja resolvido, isso sugere que o processo pai do zumbi está lutando ou não está fazendo seu trabalho corretamente.

Há uma descrição explícita sobre o que fazer em caso de problemas com zumbis em sistemas operacionais semelhantes ao Unix: "Você não pode fazer nada pelos próprios zumbis, pois eles já estão mortos. Em vez disso, mate o malvado mestre de zumbis! " (ou seja, o processo pai dos zumbis problemáticos)

telcoM
fonte
5
O que acontece se o processo estiver em uma chamada do kernel (por exemplo, fazendo E / S) quando o SIGKILL é enviado?
gidds
9
@gidds A E / S será cancelada para executar o SIGKILL ou o SIGKILL será adiado até que a E / S seja concluída. Essa é a diferença entre os estados de suspensão 'S' e 'D' em ps: 'S' é para E / S espera que o kernel possa cancelar para entregar um sinal e 'D' para aqueles que não pode.
Zwol 03/12/19
6
Não é totalmente preciso dizer que a programação para imediatamente de fornecer tempo de CPU ao processo. O lado do kernel da manipulação do sinal ainda é executado por esse processo, mas o processo só estará executando o código do kernel, portanto você está certo quando diz que o programa nunca recebe o sinal. O processo executará o código do kernel responsável pela maior parte da limpeza de recursos (arquivos abertos, memória virtual etc.). As últimas etapas deste código de limpeza são alterar o estado do processo para zumbi e chamar o agendador. Então nunca será agendado novamente.
kasperd
4
@gidds Há pelo menos quatro estados diferentes nos quais o processo pode estar. Ele pode estar executando o código do kernel no momento ou pode estar inativo em um dos três estados diferentes de inatividade. Os estados de suspensão podem ser interruptíveis, ininterruptos ou ininterruptos, exceto para sinais mortais. Se estiver em sono ininterrupto, ele ficará dormindo pelo tempo que for necessário e somente quando acordar terá chance de morrer. Se ele estava em um dos outros dois estados de suspensão, será acordado imediatamente e agendado assim que houver uma CPU disponível para ele.
kasperd
2
@ gidds O que acontece a seguir depende do código do kernel que estava sendo executado. Independentemente de ele já estar em execução ou ter que ser acordado primeiro e, em seguida, poder começar a executar o código do kernel em que estava no momento, será permitido que continue. E esse código do kernel é responsável por perceber que o processo foi instruído a morrer e agir de acordo. Na maioria das vezes, a maneira correta de lidar com isso no código do kernel é apenas retornar um erro de qualquer função que esteja executando. Uma vez que a pilha de chamadas do kernel foi desenrolada, o código de manipulação de sinais pode assumir o controle imediatamente antes de retornar ao modo de usuário.
kasperd