Risposte:
kill -9
( SIGKILL ) funziona sempre, a condizione che tu abbia l'autorizzazione per terminare il processo. Fondamentalmente o il processo deve essere avviato da te e non essere setuid o setgid, oppure devi essere root. C'è un'eccezione: anche il root non può inviare un segnale fatale al PID 1 (il init
processo).
Tuttavia, kill -9
non è garantito che funzioni immediatamente . Tutti i segnali, incluso SIGKILL, vengono inviati in modo asincrono: il kernel potrebbe impiegare del tempo per consegnarli. Di solito, la trasmissione di un segnale richiede al massimo alcuni microsecondi, proprio il tempo impiegato dall'obiettivo per ottenere una fascia oraria. Tuttavia, se il bersaglio ha bloccato il segnale , il segnale verrà messo in coda fino a quando il bersaglio non lo sblocca.
Normalmente, i processi non possono bloccare SIGKILL. Ma il codice del kernel può e i processi eseguono il codice del kernel quando chiamano le chiamate di sistema . Il codice del kernel blocca tutti i segnali quando si interrompe la chiamata di sistema si tradurrebbe in una struttura di dati mal formata da qualche parte nel kernel, o più in generale nella violazione di un invariante del kernel. Quindi se (a causa di un bug o di un errore di progettazione) una chiamata di sistema si blocca indefinitamente, potrebbe effettivamente non esserci modo di terminare il processo. (Ma il processo verrà interrotto se mai completa la chiamata di sistema.)
Un processo bloccato in una chiamata di sistema è in modalità di sospensione ininterrotta . Il comando ps
o top
(nella maggior parte dei computer) lo mostrerà nello stato D
(originariamente per " d isk", credo).
Un caso classico di lungo sonno ininterrotto è rappresentato dai processi di accesso ai file su NFS quando il server non risponde; le implementazioni moderne tendono a non imporre un sonno ininterrotto (ad es. sotto Linux, l' intr
opzione mount consente a un segnale di interrompere l'accesso ai file NFS).
A volte potresti vedere voci contrassegnate Z
(o H
sotto Linux, non so quale sia la distinzione) nell'output ps
o top
. Questi non sono tecnicamente processi, sono processi di zombi, che non sono altro che una voce nella tabella dei processi, mantenuti in modo che il processo genitore possa essere avvisato della morte di suo figlio. Se ne andranno quando il processo genitore presta attenzione (o muore).
man 5 nfs
: "L' opzione intr
/ nointr
mount è obsoleta dopo il kernel 2.6.25. Solo SIGKILL può interrompere un'operazione NFS in sospeso su questi kernel e, se specificata, questa opzione di montaggio viene ignorata per fornire la compatibilità con i kernel precedenti."
sshfs
processo (e allo stesso modo con qualsiasi altro filesystem FUSE: puoi sempre forzare lo smontaggio in questo modo).
A volte esiste un processo che non può essere ucciso a causa di:
top
esso è segnalato Ztop
esso è segnalato da D.Sembra che potresti avere un processo di zombi . Questo è innocuo: l'unica risorsa che un processo di zombi consuma è una voce nella tabella dei processi. Andrà via quando il processo genitore muore o reagisce alla morte di suo figlio.
Puoi vedere se il processo è uno zombi usando top
o il seguente comando:
ps aux | awk '$8=="Z" {print $2}'
ps
. Chi può essere sicuro che il campo richiesto sarà sempre l'ottavo, con tutte le implementazioni di ps
in tutti gli Unices?
Controlla il tuo /var/log/kern.log
e /var/log/dmesg
(o equivalenti) per eventuali indizi. Nella mia esperienza, questo è successo a me solo quando la connessione di rete di un mount NFS è improvvisamente caduta o un driver di dispositivo si è bloccato. Potrebbe accadere se anche un disco rigido si blocca, credo.
Puoi usare lsof
per vedere quali file di dispositivo ha aperto il processo.
kill -9
di solito non ha funzionato, anche dopo aver atteso 60 minuti. L'unica soluzione era riavviare.
Se @ Maciej 's e @ Gilles ' la risposta di s non risolvono il problema, e non si riconosce il processo (e chiedendo che cosa è con la vostra distro non si presenta risposte). Controlla i rootkit e tutti gli altri segni di proprietà . Un rootkit è più che in grado di impedirti di uccidere il processo. In effetti molti sono in grado di impedirti di vederli. Ma se dimenticano di modificare 1 piccolo programma potrebbero essere individuati (ad esempio, hanno modificato top
, ma non htop
). Molto probabilmente non è così, ma è meglio prevenire che curare.
Uccidere in realtà significa inviare un segnale. ci sono più segnali che puoi inviare. uccidere -9 è un segnale speciale.
Quando si invia un segnale, l'applicazione lo gestisce. in caso contrario il kernel lo gestisce. così puoi intercettare un segnale nella tua applicazione.
Ma ho detto che uccidere -9 era speciale. È speciale in quanto l'applicazione non lo capisce. va direttamente al kernel che poi uccide veramente l'applicazione alla prima occasione possibile. in altre parole lo uccide morto
kill -15 invia il segnale SIGTERM che sta per SIGNAL TERMINATE in altre parole dice all'applicazione di uscire. Questo è il modo amichevole per dire a un'applicazione che è tempo di chiudere. ma se l'applicazione non risponde uccidere -9 la ucciderà.
se kill -9 non funziona, probabilmente significa che il tuo kernel non funziona. un riavvio è in ordine. Non ricordo che sia mai successo.
Innanzitutto, controlla se si tratta di un processo Zombie (che è molto possibile):
ps -Al
Vedrai qualcosa come:
0 Z 1000 24589 1 0 80 0 - 0 exit ? 00:00:00 soffice.bin <defunct>
(Nota la "Z" a sinistra)
Se la quinta colonna non è 1, significa che ha un processo padre. Prova a uccidere quell'ID del processo principale .
Se il suo PPID = 1, NON UCCIDARLO !! , pensa quali altri dispositivi o processi potrebbero essere correlati ad esso.
Ad esempio, se si utilizzava un dispositivo o una samba montati, provare a smontarlo. Ciò potrebbe rilasciare il processo Zombie.
NOTA : Se ps -Al
(o top
) mostra una "D" anziché "Z", potrebbe essere correlato al montaggio remoto (come NFS). Nella mia esperienza, il riavvio è l'unico modo per andare lì, ma puoi controllare le altre risposte che coprono quel caso in modo più dettagliato.
Come altri hanno già detto, un processo ininterrotto nel sonno non può essere immediatamente ucciso (o, in alcuni casi, affatto). Vale la pena notare che un altro stato del processo, TASK_KILLABLE, è stato aggiunto per risolvere questo problema in alcuni scenari, in particolare il caso comune in cui il processo è in attesa su NFS. Vedi http://lwn.net/Articles/288056/
Sfortunatamente non credo che questo sia usato da nessuna parte nel kernel ma NFS.
ls
processo accedendo a un sshfs
mount, quando il server remoto è diventato irraggiungibile. Esiste una soluzione per FUSE o sshfs, che potrei usare in futuro per evitare tali situazioni? 2.6.30 kernel
Ho realizzato una piccola sceneggiatura che mi ha aiutato molto a dare un'occhiata!
Puoi usarlo per uccidere qualsiasi processo con un determinato nome nel suo percorso (presta attenzione a questo !!) O puoi uccidere qualsiasi processo di un determinato utente usando il parametro "-u username".
#!/bin/bash
if [ "$1" == "-u" ] ; then\n
PID=`grep "$2" /etc/passwd | cut -d ":" -f3`
processes=`ps aux | grep "$PID" | egrep -v "PID|ps \-au|killbyname|grep" | awk '{ print $2}'`
echo "############# Killing all processes of user: $2 ############################"
else
echo "############# Killing processes by name: $1 ############################"
processes=`ps aux | grep "$1" | egrep -v "killbyname|grep" | awk '{ print $2}' `
fi
for process in $processes ; do
# "command" stores the entire commandline of the process that will be killed
#it may be useful to show it but in some cases it is counter-productive
#command=`ps aux | grep $process | egrep -v "grep" | awk '{ print $2 }'`
echo "Killing process: $process"
echo ""
kill -9 $process
done
Ci sono casi in cui anche se invii un kill -9 a un processo, quel pid si interromperà, ma il processo si riavvia automaticamente (ad esempio, se lo provi gnome-panel
, si riavvierà): potrebbe essere il caso qui?
da qui in origine :
controlla se strace mostra qualcosa
strace -p <PID>
prova ad attaccarti al processo con gdb
gdb <path to binary> <PID>
se il processo interagiva con un dispositivo che è possibile smontare, rimuovere il modulo del kernel o scollegare / scollegare fisicamente ... quindi provare.
Ho avuto questo tipo di problema. Questo era un programma che avevo avviato strace
e interrotto con Ctrl
+ C
. È finito in uno stato T
(tracciato o arrestato). Non so come sia successo esattamente, ma non è stato ucciso SIGKILL
.
Per farla breve, sono riuscito a ucciderlo con gdb
:
gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit
Sulla base di un indizio della risposta di Gilles, avevo un processo contrassegnato con "Z" nella parte superiore ( <defunct>
in ps) che utilizzava risorse di sistema, aveva persino una porta aperta che era in ascolto e si poteva connettersi a quella porta. Questo è stato dopo aver eseguito un kill -9
su di esso. Il suo genitore era "1" (cioè init
), quindi teoricamente dovrebbe essere semplicemente ripetuto e scomparire. Ma non lo era, restava in giro, sebbene non corresse, e "non morisse"
Quindi nel mio caso era uno zombi ma consumava ancora risorse ... FWIW.
E non era killable da qualsiasi numero di kill -9
s'
E il suo genitore lo era, init
ma non veniva raccolto (ripulito). Cioè ha init
avuto un figlio di zombi.
E il riavvio non era necessario per risolvere il problema. Sebbene un riavvio "avrebbe risolto" il problema / lo ha reso più rapido. Semplicemente non aggraziato, il che era ancora possibile.
Ed era una porta LISTEN di proprietà di un processo zombie (e anche alcune altre porte come lo stato CLOSE_WAIT collegavano localhost a localhost). E ha anche accettato connessioni. Anche come uno zombi. Immagino che non sia riuscito a ripulire le porte, quindi le connessioni in entrata sono state ancora aggiunte al backlog della porta di ascolto tcp, anche se non avevano possibilità di essere accettate.
Molti di questi sono dichiarati "impossibili" in vari punti delle interwebs.
Si scopre che avevo al suo interno un thread che stava eseguendo una "chiamata di sistema" (ioctl in questo caso) che impiegava alcune ore per tornare (questo era un comportamento previsto). Apparentemente il sistema non può uccidere il processo "fino in fondo" fino a quando non ritorna dalla ioctl
chiamata, supponendo che entri nella terra del kernel. Dopo alcune ore è tornato, le cose si sono chiarite e le prese sono state automaticamente chiuse, ecc. Come previsto. È un momento languido nel braccio della morte! Il kernel attendeva pazientemente di ucciderlo.
Quindi, per rispondere all'OP, a volte devi aspettare. Tanto tempo. Quindi ucciderà finalmente.
Controlla anche dmesg per vedere se c'è stato un panico nel kernel (cioè un bug del kernel).