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
SIGCHLDsem 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 handlerSIGCHLD - Use a tecnica de double fork para orfanar o neto sob
init - Defina
SIGCHLDcomoSIG_IGN-- sistemas compatíveis com POSIX fazem a coleta automatica dos filhos