Come uccidere i processi zombi su Linux

Pubblicato: 2022-01-29
Una finestra del terminale su un laptop Linux.
Fatmawati Achmad Zaenuri/Shutterstock

I programmi scritti male o con prestazioni scadenti possono lasciare processi zombi 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 di 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 di processo. 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 ha bisogno di cercare o impostare per ogni processo. Il PCB viene aggiornato anche quando un processo viene creato, dato il tempo di elaborazione e infine distrutto.

Il PCB Linux contiene oltre 95 campi. È definito come una struttura chiamata task_struct.h ed è lunga 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 programma : quando a questo processo viene concesso l'accesso alla CPU, il sistema utilizzerà questo indirizzo per trovare l'istruzione successiva del processo che dovrebbe essere eseguita.
  • Registri : l'elenco dei registri della CPU utilizzati da questo processo. L'elenco potrebbe contenere accumulatori, registri di indice e puntatori di stack.
  • Apri elenco file: file associati a questo processo.
  • Informazioni sulla pianificazione della CPU : utilizzate 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 di inizio e fine della memoria di processo e i puntatori alle pagine di memoria.
  • Informazioni sullo stato degli 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 l'esecuzione e attende uno slot CPU.
  • S: Un processo dormiente. Il processo è in attesa del completamento di un'azione, ad esempio un'operazione in entrata o in uscita, o che una risorsa diventi disponibile.
  • D: Il processo è in uno stato di sonno ininterrotto. Sta utilizzando 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 (fermato) perché ha ricevuto il segnale SIGSTOP . Risponderà solo ai segnali SIGKILL o SIGCONT , che rispettivamente interrompono il processo o lo istruiscono a continuare. Questo è ciò che accade quando si passa dalle attività in primo piano ( fg ) a quelle in background ( bg) .
  • Z: Un processo Zombie. Quando un processo viene completato, non semplicemente svanisce. Libera la memoria che sta utilizzando e si rimuove dalla memoria, ma la sua voce nella tabella dei processi e nel PCB rimane. Il suo stato è impostato su EXIT_ZOMBIE e il suo processo padre viene notificato (dal segnale SIGCHLD ) che il processo figlio è terminato.

Annuncio pubblicitario

Nello stato Zombie, il processo padre chiama una delle famiglie di funzioni wait() 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 la modifica dello stato indica che il processo figlio ha interrotto l'esecuzione, viene letto il codice di uscita. Quindi, il PCB del figlio viene distrutto e la sua voce nella tabella dei processi viene rimossa. Idealmente, tutto ciò accade in un batter d'occhio e i processi nello stato di zombi non esistono per molto tempo.

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

Quali sono le cause dei processi zombie su Linux?

Un processo padre scritto male potrebbe non chiamare la funzione wait() quando viene creato il processo figlio. Ciò significa che nulla sta controllando i cambiamenti di stato nel processo figlio e il segnale SIGCHLD verrà ignorato. Oppure, forse un'altra applicazione sta influenzando l'esecuzione del processo padre, a causa di una programmazione scadente o di intenzioni dannose.

Tuttavia, se il processo padre non controlla i cambiamenti di stato nel processo figlio, non si verificherà la corretta gestione del sistema. Il PCB e la voce nella tabella del processo non verranno rimossi al termine del processo figlio. Ciò comporta che lo stato di zombi 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 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 di processo.

Un numero enorme di zombi potrebbe, plausibilmente, influenzare la quantità di memoria libera per altri processi. Se hai così tanti zombi, però, hai un problema serio con l'applicazione madre 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 segnale SIGKILL . Puoi provare a inviare il segnale SIGCHLD al processo padre, ma se non ha funzionato quando il processo figlio è terminato, è improbabile che funzioni anche ora.

Annuncio pubblicitario

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

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

Digita quanto segue:

 superiore 

Questo sistema ha otto processi zombi. Possiamo elencarli usando il comando ps e collegandolo a egrep . Ancora una volta, i processi zombi hanno una bandiera di stato "Z" e di solito vedrai anche "defunto".

Digita quanto segue:

 ps aux | egrep "Z|defunto" 

I processi zombi sono elencati.

Questo è un modo più ordinato per scoprire gli ID di processo degli zombi rispetto a scorrere avanti e indietro nella top . Vediamo anche che un'applicazione chiamata "badprg" ha generato questi zombi.

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

Annuncio pubblicitario

Il processo che vogliamo trovare verrà indicato utilizzando l'opzione -p (processo), quindi passando 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 

Ci è stato detto che l'ID del processo padre è 7636. Ora possiamo fare un riferimento incrociato usando ps ancora una volta.

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

 uccidere -SIGKILL 7636

A seconda del proprietario del processo padre, potresti anche dover utilizzare 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à.

Annuncio pubblicitario

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 pulisce correttamente dopo i suoi processi figlio.