Come uccidere i processi zombie su Linux

0
179
Una finestra di terminale su un laptop Linux.
Fatmawati Achmad Zaenuri / Shutterstock

I programmi scritti male o che funzionano male possono lasciare processi zombie in agguato all’interno del tuo computer Linux. Scopri come vengono creati gli zombi e come puoi finalmente metterli a riposo.

Come funzionano gli stati del processo su Linux

Linux, ovviamente, deve tenere traccia di tutte le applicazioni e i demoni in esecuzione sul tuo computer. Uno dei modi in cui lo fa è mantenere la tabella dei processi. Questo è un elenco di strutture nella memoria del kernel. Ogni processo ha una voce in questo elenco che contiene alcune informazioni su di esso.

Non c’è molto in ciascuna delle strutture della tabella dei processi. Contengono l’ID del processo, alcuni altri elementi di dati e un puntatore al blocco di controllo del processo (PCB) per quel processo.

È il PCB che contiene i molti dettagli che Linux deve cercare o impostare per ogni processo. Il PCB viene anche aggiornato quando viene creato un processo, dato il tempo di elaborazione e infine distrutto.

Il PCB Linux contiene oltre 95 campi. È definito come una struttura chiamata task_struct.h, ed è lungo oltre 700 righe. Il PCB contiene i seguenti tipi di informazioni:

  • Stato del processo: Gli stati sono descritti di seguito.
  • Numero di processo: Il suo identificatore univoco all’interno del sistema operativo.
  • Contatore di programma: Quando a questo processo viene concesso l’accesso successivo alla CPU, il sistema utilizzerà questo indirizzo per trovare l’istruzione successiva del processo da eseguire.
  • Registri: L’elenco dei registri della CPU utilizzati da questo processo. L’elenco potrebbe contenere accumulatori, registri di indice e puntatori allo stack.
  • Apri elenco file: File associati a questo processo.
  • Informazioni sulla pianificazione della CPU: Utilizzato per determinare la frequenza e la durata del tempo di elaborazione della CPU assegnato a questo processo. La priorità del processo, i puntatori alle code di pianificazione e altri parametri di pianificazione devono essere registrati nel PCB.
  • Informazioni sulla gestione della memoria: Dettagli sulla memoria utilizzata da questo processo, come gli indirizzi iniziale e finale della memoria del processo e i puntatori alle pagine di memoria.
  • Informazioni sullo stato di I / O: Qualsiasi dispositivo di ingresso o uscita utilizzato dal processo.

Lo “stato del processo” può essere uno dei seguenti:

  • R: Un processo in esecuzione o eseguibile. In esecuzione significa che sta ricevendo cicli della CPU ed è in esecuzione. Un processo eseguibile è pronto per essere eseguito e in attesa di uno slot CPU.
  • S: Un processo di sonno. Il processo è in attesa del completamento di un’azione, come un’operazione di input o output, o che una risorsa diventi disponibile.
  • D: Il processo è in uno stato di sospensione ininterrotto. Utilizza una chiamata di sistema di blocco e non può continuare fino al completamento delle chiamate di sistema. A differenza dello stato “Sleep”, un processo in questo stato non risponderà ai segnali finché la chiamata di sistema non sarà completata e l’esecuzione non sarà tornata al processo.
  • T: Il processo è terminato (interrotto) perché ha ricevuto l’estensione SIGSTOP segnale. Risponderà solo a SIGKILL o SIGCONT segnali, che terminano il processo o lo istruiscono a continuare, rispettivamente. Questo è ciò che accade quando si passa dal primo piano (fg) sullo sfondo (bg) compiti.
  • Z: Un processo Zombie. Quando un processo viene completato, non svanisce. Libera tutta la memoria che sta utilizzando e si rimuove dalla memoria, ma la sua voce nella tabella di processo e PCB rimane. Il suo stato è impostato su EXIT_ZOMBIEe il suo processo genitore riceve una notifica (dal SIGCHLD segnale) che il processo figlio è terminato.

Nello stato Zombie, il processo padre chiama uno dei file wait() famiglie di funzioni quando viene creato il processo figlio. Quindi attende un cambiamento di stato nel processo figlio. Il processo figlio è stato interrotto, continuato o interrotto da un segnale? È terminato eseguendo il completamento naturale del suo codice?

Se il cambio di stato indica che il processo figlio ha smesso di funzionare, viene letto il suo codice di uscita. Quindi, il PCB del bambino viene distrutto e la sua voce nella tabella dei processi viene rimossa. Idealmente, tutto questo accade in un batter d’occhio ei processi nello stato di zombi non esistono per molto tempo.

RELAZIONATO: Come eseguire e controllare i processi in background su Linux

Cosa causa i processi zombie su Linux?

Un processo genitore scritto male potrebbe non chiamare il file wait() quando viene creato il processo figlio. Ciò significa che nulla sta guardando i cambiamenti di stato nel processo figlio e il file SIGCHLD il segnale verrà ignorato. Oppure, forse un’altra applicazione sta influenzando l’esecuzione del processo principale, a causa di una cattiva programmazione o di intenti dannosi.

Tuttavia, se il processo genitore non osserva i cambiamenti di stato nel processo figlio, non si verificherà la corretta manutenzione del sistema. Il PCB e la voce nella tabella del processo non verranno rimossi quando il processo figlio termina. Ciò fa sì che lo stato zombie non venga mai rimosso dal PCB.

Gli zombi usano un po ‘di memoria, ma di solito non rappresentano un problema. La voce nella tabella dei processi è piccola, ma, finché non viene rilasciata, l’ID del processo non può essere riutilizzato. Su un sistema operativo a 64 bit, è improbabile che ciò causi problemi perché il PCB è molto più grande della voce della tabella dei processi.

Un numero enorme di zombi potrebbe, presumibilmente, influenzare la quantità di memoria libera per altri processi. Se hai così tanti zombi, però, hai un serio problema con l’applicazione genitore o un bug del sistema operativo.

Come rimuovere i processi zombie

Non puoi uccidere un processo zombi perché è già morto. Non risponderà a nessun segnale perché è stato rimosso dalla memoria: non c’è nessun posto dove inviare un file SIGKILL segnale. Puoi provare a inviare il file SIGCHLD segnale al processo genitore, ma se non ha funzionato quando il processo figlio è terminato, è improbabile che funzioni anche ora.

L’unica soluzione affidabile è uccidere il processo genitore. Quando viene terminato, i suoi processi figli vengono ereditati da init processo, che è il primo processo da eseguire in un sistema Linux (il suo ID processo è 1).

Il init processo esegue regolarmente la necessaria pulizia degli zombi, quindi per ucciderli, devi solo uccidere il processo che li ha creati. Il top Il comando è un modo conveniente per vedere se hai degli zombi.

Digita quanto segue:

top

in alto in una finestra di terminale

Questo sistema ha otto processi zombie. Possiamo elencarli usando il ps comando e convogliarlo in egrep. Anche in questo caso, i processi zombi hanno una bandiera di stato “Z” e di solito vedrai anche “defunto”.

Digita quanto segue:

ps aux | egrep "Z|defunct"

ps aux |  egrep "Z | defunct" in una finestra di terminale

Vengono elencati i processi zombie.

Uscita da ps aux |  egrep "Z | defunct" in una finestra di terminale

Questo è un modo più ordinato per scoprire gli ID di processo degli zombi piuttosto che scorrere avanti e indietro top. Vediamo anche che un’applicazione chiamata “badprg” ha generato questi zombie.

L’ID processo del primo zombie è 7641, ma dobbiamo trovare l’ID processo del suo processo genitore. Possiamo farlo usando ps ancora. Useremo l’opzione di output (-o) dire ps per visualizzare solo l’ID di processo del genitore, quindi passarlo con ppid= bandiera.

Il processo che vogliamo trovare verrà indicato utilizzando il -p (processo), quindi passare l’ID del processo dello zombi.

Pertanto, digitiamo il seguente comando per cercare le informazioni sul processo per il processo 7641, ma riporterà solo l’ID del processo padre:

ps -o ppid= -p 7641

ps -o ppid = -p 7641 in una finestra di terminale

Ci viene detto che l’ID del processo genitore è 7636. Ora possiamo fare un riferimento incrociato usando ps ancora una volta.

ps -e |  grep 7636 in una finestra di terminale

Vediamo che questo corrisponde al nome del processo genitore di prima. Per terminare il processo genitore, utilizzare l’opzione SIGKILL con il comando kill come segue:

kill -SIGKILL 7636

A seconda del proprietario del processo genitore, potrebbe essere necessario utilizzare anche sudo.

Gli zombi non fanno paura …

… a meno che non siano in un’orda enorme. Alcuni non sono nulla di cui preoccuparsi e un semplice riavvio li cancellerà.

Tuttavia, se noti che un’applicazione o un processo genera sempre zombi, è qualcosa che dovresti esaminare. Molto probabilmente è solo un programma scritto in modo sciatto, nel qual caso forse c’è una versione aggiornata che si pulisce correttamente dopo i suoi processi figli.