Entendendo e Lidando com Processos Zumbi no Linux

Entendendo e Lidando com Processos Zumbi no Linux

O que e um processo zumbi?

Um processo zumbi e um processo filho que terminou a execucao mas ainda tem uma entrada na tabela de processos (codigo de estado Z, tambem exibido como [defunct]). O processo em si nao esta mais executando -- nao consome CPU nem memoria -- mas seu status de saida ainda nao foi coletado pelo processo pai.

$ ps aux | grep Z
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
www-data  1234  0.0  0.0      0     0 ?        Z    10:01   0:00 [defunct]

O Z na coluna STAT identifica um zumbi.

Por que processos zumbi ocorrem?

A causa raiz e um processo pai que nunca chama wait() ou waitpid() para coletar o status de saida do filho.

Quando um processo termina, o kernel armazena seu status de saida na tabela de processos e envia SIGCHLD ao pai. A entrada permanece la ate o pai recuperar o status. Se o pai nunca o faz, o filho se torna um zumbi permanente.

Causas comuns:

  • O pai ignora SIGCHLD sem configurar coleta automatica
  • O pai tem um bug no seu handler de sinal
  • O pai esta travado e nao consegue processar sinais

Voce nao pode matar um zumbi com kill -9 -- o processo ja esta morto. Apenas o pai (ou seu desaparecimento) pode fazer um zumbi desaparecer.

Como detectar zumbis

Encontrar zumbis e seu pai

$ ps -el | grep Z
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 Z  1000  1234  1100  0  80   0 -     0 -      pts/0    00:00:00 process

A coluna PPID mostra o PID do pai (1100 neste exemplo). Confirme o pai com:

$ ps aux | awk 'NR==1 || $2==1100'

Monitorar contagem de zumbis com top

$ top
Tasks: 142 total,   1 running, 141 sleeping,   0 stopped,   2 zombie

Uma contagem de zumbis crescendo constantemente indica um bug continuo em um processo pai.

Como corrigir processos zumbi

Opcao 1: sinalizar o pai com SIGCHLD

Se o pai pode lidar com SIGCHLD, enviar o sinal pode faze-lo chamar wait() e coletar o zumbi.

$ kill -SIGCHLD <PPID>

Opcao 2: encerrar o processo pai

Quando o pai termina, o novo pai do zumbi se torna init (PID 1) ou systemd, que o coleta imediatamente.

$ kill <PPID>

Se o pai nao responde:

$ kill -9 <PPID>

Antes de forcar o encerramento de um pai que e um servico (nginx, mysqld, etc.), avalie o impacto nas conexoes dependentes e na integridade dos dados.

Opcao 3: reiniciar o sistema

Um ultimo recurso quando zumbis se acumularam a um nivel que prejudica a operacao normal. Um reboot reinicializa a tabela de processos.

Processos zumbi sao perigosos?

Alguns poucos zumbis nao causam dano real. Eles nao consomem CPU nem memoria.

Porem, eles se tornam um problema em escala:

  • Esgotamento de PID: O teto padrao de PID do Linux (/proc/sys/kernel/pid_max) e 32.768. Se zumbis se acumulam, os PIDs disponiveis se esgotam e novos processos nao podem iniciar.
  • Pressao na tabela de processos: Cada entrada consome uma pequena quantidade de memoria do kernel.

Verifique seu limite de PID atual:

$ cat /proc/sys/kernel/pid_max
32768

Prevenindo processos zumbi no codigo da aplicacao

Zumbis sao um sintoma de um bug na aplicacao pai. A correcao real pertence ao codigo.

  • Chame waitpid(-1, NULL, WNOHANG) em um loop dentro de um handler SIGCHLD
  • Use a tecnica de double fork para orfanar o neto sob init
  • Defina SIGCHLD como SIG_IGN -- sistemas compatíveis com POSIX fazem a coleta automatica dos filhos

Proximas leituras