Rimuovi un processo zombi dalla tabella dei processi


8

Ho un fastidioso processo di zombi che viene adottato da init e non andrà via. Ho letto che esiste un modo per creare un processo fittizio, collegare lo zombi come figlio di quel nuovo processo e quindi ucciderlo, rimuovendolo dalla tabella dei processi.

Come lo farei, precisamente?

E sì, ho letto la maggior parte di queste cose:

Un processo di zombi è già morto, quindi non può essere ucciso.

O

Dovresti semplicemente riavviare il sistema

E

I processi di zombi non usano alcuna risorsa, dovresti semplicemente lasciarli essere

Sfortunatamente, molti programmi controllano la tabella dei processi per vedere se un'istanza è già in esecuzione e si rifiuteranno di avviarne una nuova se è presente una voce nella tabella dei processi.

E riavviare ogni volta che la mia connessione SSHFS si interrompe, portando Sublime con sé, è un po 'sciocco.


7
... con un fucile da caccia. ;)
Nathan C,

+1, perché ho guardato il principale e ho visto "uccidi zombi"
HopelessN00b,

Risposte:


16

L' unico modo per sbarazzarsi di uno zombi è quello di fare il genitore in wait()modo che possa segnalare il suo stato di uscita. Puoi farlo inviando SIGCHLDal genitore, supponendo che il genitore sia scritto correttamente.

Se hai zombi di solito significa che il genitore NON è scritto correttamente (perché il bambino ha già inviato SIGCHLDal genitore quando è morto ed è diventato uno zombi), quindi il passo successivo è uccidere il genitore.
Uno strumento come pstree(con l' -popzione) può mostrarti il ​​lignaggio dei tuoi zombi in modo da sapere quale processo è il genitore.
Quando il genitore muore, lo zombi sarà adottato init, il che è sempre wait()ingannevole per i bambini, e ucciderà felicemente tutti gli zombi che adotta.

Se il processo genitore è effettivamente init(PID 1), sei già in una situazione che non dovrebbe mai accadere. Puoi provare a inviare SIGCHLDa init, ma in realtà non dovresti farlo, e se non funziona l'unica soluzione è riavviare perché il sistema initè rotto e non sta facendo il suo lavoro.

(Queste sono le opzioni "fucile".)


Alcune persone più creative di me hanno anche escogitato questa opzione se si desidera evitare di uccidere il processo genitore:

  1. Determinare i PIDS dei processi genitore e zombi
    (per questo esempio supponiamo che lo zombi sia PID 3101 e il genitore sia PID 3100)
  2. Accendi gdbe attachverso il genitore:
    attach 3100
  3. Chiama waitpidper lo zombi:
    call waitpid(3101,0,0)
  4. Staccare dal genitore ( detach) ed uscire dal debugger.

(Questo è un fucile di precisione finemente sintonizzato.)


1
eh, ottima risposta. Fucile "Mosin" proprio lì.
Danila Ladner,

1
@DanilaLadner Vorrei potermi prendere il merito, ma fino a quando non sono andato a caccia di google per vedere cosa intendesse skerit "attaccare lo zombi come figlio di un processo fittizio", il pensiero di usare il debugger per forzare waitpid()non mi è mai venuto in mente. Sono un ex programmatore terribile ...
voretaq7,

call waitpidnon ritorna mai per me
deFreitas,

0

Perché sei preoccupato per i processi di zombi? Le risorse che tengono legate sono minime (spazio per un'attività di struttura scheletro, un PID e non molto altro). Certo, è sconveniente, ma è quello. Cerca i loro genitori e correggili, sostituiscili con alternative scritte migliori (potrebbe avere altri effetti collaterali benefici), segnalalo come bug (che certamente sono).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.