Bagaimana jika 'kill -9' tidak berfungsi?

466

Saya punya proses yang tidak bisa saya bunuh kill -9 <pid>. Apa masalahnya dalam kasus seperti itu, terutama karena saya adalah pemilik dari proses itu. Saya pikir tidak ada yang bisa menghindari killopsi itu.

tepang
sumber

Jawaban:

560

kill -9( SIGKILL ) selalu berfungsi, asalkan Anda memiliki izin untuk menghentikan prosesnya. Pada dasarnya proses tersebut harus dimulai oleh Anda dan bukan setuid atau setgid, atau Anda harus root. Ada satu pengecualian: bahkan root tidak dapat mengirim sinyal fatal ke PID 1 ( initproses).

Namun kill -9tidak dijamin untuk segera bekerja . Semua sinyal, termasuk SIGKILL, dikirimkan secara serempak: kernel mungkin membutuhkan waktu untuk mengirimkannya. Biasanya, mengirimkan sinyal membutuhkan paling banyak beberapa mikrodetik, hanya waktu yang dibutuhkan target untuk mendapatkan waktu. Namun, jika target telah memblokir sinyal , sinyal akan antri sampai target membuka blokir itu.

Biasanya, proses tidak dapat memblokir SIGKILL. Tetapi kode kernel dapat, dan memproses mengeksekusi kode kernel ketika mereka memanggil panggilan sistem . Kode kernel memblokir semua sinyal ketika menginterupsi panggilan sistem akan menghasilkan struktur data yang terbentuk buruk di suatu tempat di dalam kernel, atau lebih umum lagi pada beberapa invarian kernel yang dilanggar. Jadi jika (karena bug atau kesalahan desain) suatu sistem panggilan blok tanpa batas, mungkin secara efektif tidak ada cara untuk mematikan proses. (Tapi prosesnya akan dimatikan jika ia pernah menyelesaikan panggilan sistem.)

Proses yang diblokir dalam panggilan sistem berada dalam kondisi tidur yang tidak terputus . The psatau topperintah akan (pada kebanyakan beragam Unix) menunjukkan di negara bagian D(awalnya untuk “ d isiko”, saya pikir).

Kasus klasik dari lama tidur yang tidak terputus adalah proses mengakses file melalui NFS ketika server tidak merespons; implementasi modern cenderung tidak memaksakan tidur tanpa gangguan (misalnya di Linux, intropsi mount memungkinkan sinyal untuk mengganggu akses file NFS).

Terkadang Anda mungkin melihat entri bertanda Z(atau Hdi Linux, saya tidak tahu apa perbedaannya) di psatau topkeluaran. Ini secara teknis bukan proses, itu adalah proses zombie, yang tidak lebih dari entri dalam tabel proses, disimpan di sekitar sehingga proses induk dapat diberitahu tentang kematian anaknya. Mereka akan pergi ketika proses induk memperhatikan (atau mati).

Gilles
sumber
92
Jawaban Anda terlihat bertentangan. Anda mulai memberi tahu SIGKILL selalu berfungsi tetapi akhiri mengutip sleep case yang tidak pernah terputus, di mana SIGKILL mungkin tidak pernah bekerja di luar mematikan kernel. Ada juga dua kasus di mana SIGKILL tidak berfungsi. Dengan zombie jelas karena Anda tidak dapat membunuh proses yang sudah mati dan dengan init, yang dengan desain mengabaikan sinyal SIGKILL.
jlliagre
41
@ jlliagre: Membunuh zombie tidak masuk akal, itu tidak hidup untuk memulai. Dan membunuh proses dalam tidur interupsi tidak bekerja, hanya saja (seperti dengan sinyal lain) tidak sinkron. Saya sudah mencoba mengklarifikasi hal ini dalam hasil edit saya.
Gilles
3
Saya menulis terlalu membunuh zombie tidak masuk akal tetapi itu tidak mencegah banyak orang untuk mencobanya dan mengeluh. Membunuh suatu proses dalam tidur interruptible memang bekerja dengan desain, tetapi saya berbicara tentang membunuh proses dalam sleep yang tidak terputus yang dapat gagal jika panggilan sistem tidak pernah bangun.
jlliagre
11
man 5 nfs: "Opsi intr/ nointrmount tidak digunakan lagi setelah kernel 2.6.25. Hanya SIGKILL yang dapat menghentikan operasi NFS yang tertunda pada kernel ini, dan jika ditentukan, opsi mount ini diabaikan untuk memberikan kompatibilitas mundur dengan kernel yang lebih tua."
Martin Schröder
4
@ imz - IvanZakharyaschev Bukan yang saya tahu (tapi saya mungkin tidak tahu). Dengan sshfs, sebagai upaya terakhir, Anda dapat mematikan sshfsproses (dan juga dengan sistem berkas FUSE lainnya: Anda selalu dapat melepas paksa dengan cara ini).
Gilles
100

Kadang-kadang ada proses dan tidak dapat dibunuh karena:

  • menjadi zombie. Yaitu proses yang orang tua tidak membaca status keluar. Proses tersebut tidak menggunakan sumber daya apa pun kecuali entri PID. Di topdalamnya ditandai Z
  • salah tidur tanpa gangguan. Seharusnya tidak terjadi tetapi dengan kombinasi kode kernel kereta dan / atau perangkat keras kereta itu kadang-kadang terjadi. Satu-satunya metode adalah me-reboot atau menunggu. Di topdalamnya ditandai oleh D.
Maciej Piechotka
sumber
2
Zombie tidak mengkonsumsi sumber daya?
Luc M
7
@Luc M: AFAIK no (setidaknya di Linux) - dengan pengecualian entri dalam tabel proses (yaitu PID bersama dengan informasi seperti pemilik, status keluar dll.). Hanya proses yang menunggu pengakuan dari pihak yang diakhiri.
Maciej Piechotka
18
@ xenoterracide: Akhirnya ya tetapi jika proses induk masih hidup (misalnya itu adalah sesi gnome atau sesuatu yang memenuhi peran yang sama) Anda mungkin masih memiliki zombie. Secara teknis itu adalah tugas orang tua untuk membersihkan tetapi jika zombie menjadi yatim piatu membersihkan setelah itu (terminologi adalah alasan mengapa kelas unix dilakukan dengan pintu tertutup - siapa pun yang mendengar tentang anak yatim, zombie dan membunuh dalam satu kalimat mungkin mendapat kesan yang salah).
Maciej Piechotka
5
"... hanya metode untuk reboot atau menunggu." Tunggu berapa lama? Lima bulan telah berlalu dan zombie saya masih ada di sana.
DarenW
3
@ DarenW sampai orang tua mengakui kematian anak-anak. Untuk perinciannya, silakan tanyakan pembuat program.
Maciej Piechotka
32

Sepertinya Anda mungkin memiliki proses zombie . Ini tidak berbahaya: satu-satunya sumber daya yang dikonsumsi proses zombie adalah entri dalam tabel proses. Ini akan hilang ketika proses orang tua meninggal atau bereaksi terhadap kematian anaknya.

Anda dapat melihat apakah prosesnya adalah zombie dengan menggunakan topatau perintah berikut:

ps aux | awk '$8=="Z" {print $2}'
Josh
sumber
13
Umm, aku selalu tidak suka dengan nama field "keras" ini ps. Siapa yang dapat yakin bahwa bidang yang diminta akan selalu menjadi yang ke-8, dengan semua implementasi psdi semua Unit?
syntaxerror
26

Periksa Anda /var/log/kern.logdan /var/log/dmesg(atau yang setara) untuk mencari petunjuk. Dalam pengalaman saya ini hanya terjadi pada saya ketika koneksi jaringan NFS mount tiba-tiba turun atau driver perangkat crash. Bisa terjadi jika hard drive rusak juga, saya percaya.

Anda dapat menggunakan lsofuntuk melihat file perangkat apa yang telah dibuka oleh proses.

LawrenceC
sumber
6
+1 untuk menyebutkan NFS. Beberapa tahun yang lalu ini terjadi pada saya setiap beberapa bulan - jika server NFS crash, klien NFS pada semua kotak RHEL (yang ditambal) akan hang. kill -9biasanya tidak berhasil, bahkan setelah menunggu 60 menit. Satu-satunya solusi adalah reboot.
Stefan Lasiewski
17

Jika jawaban @ Maciej dan @ Gilles tidak menyelesaikan masalah Anda, dan Anda tidak mengenali prosesnya (dan menanyakan apa yang terjadi dengan distro Anda tidak muncul jawaban). Periksa Rootkit dan tanda-tanda lain yang telah Anda miliki . Rootkit lebih dari mampu mencegah Anda membunuh prosesnya. Bahkan banyak yang mampu mencegah Anda melihatnya. Tetapi jika mereka lupa memodifikasi 1 program kecil, mereka mungkin terlihat (misalnya mereka memodifikasi top, tetapi tidak htop). Kemungkinan besar ini bukan masalahnya tetapi lebih baik aman daripada menyesal.

xenoterracide
sumber
Saya kira banyak rootkit menyisipkan diri mereka ke dalam kernel untuk membuat hal-hal lebih sederhana (tidak perlu menebak apa yang dimiliki pengguna dan mengunduh MB dari program yang ditambal). Namun itu masih layak untuk diperiksa (++ suara).
Maciej Piechotka
11

Bunuh sebenarnya berarti mengirim sinyal. ada beberapa sinyal yang dapat Anda kirim. kill -9 adalah sinyal khusus.

Saat mengirim sinyal, aplikasi berurusan dengannya. jika tidak kernel mengatasinya. sehingga Anda dapat menjebak sinyal di aplikasi Anda.

Tapi aku bilang kill -9 itu spesial. Ini istimewa karena aplikasi tidak mendapatkannya. langsung ke kernel yang kemudian benar-benar membunuh aplikasi pada kesempatan pertama. dengan kata lain membunuhnya mati

kill -15 mengirimkan sinyal SIGTERM yang merupakan singkatan SIGNAL TERMINATE dengan kata lain memberitahu aplikasi untuk berhenti. Ini adalah cara yang ramah untuk memberi tahu aplikasi sudah waktunya untuk mematikan. tetapi jika aplikasi tidak merespons kill -9 akan membunuhnya.

Jika kill -9 tidak berfungsi, itu mungkin berarti kernel Anda rusak. reboot sudah beres. Saya tidak ingat itu pernah terjadi.

DeveloperChris
sumber
5
15 adalah SIGTERM (friendly kill), bukan SIGHUP. SIGHUP adalah untuk terminal pengendali ditutup atau saluran komunikasi hilang
JoelFan
11

Pertama, periksa apakah ini proses Zombie (yang sangat mungkin):

ps -Al

Anda akan melihat sesuatu seperti:

0 Z  1000 24589     1  0  80   0 -     0 exit   ?        00:00:00 soffice.bin <defunct>

(Perhatikan "Z" di sebelah kiri)

Jika kolom ke-5 bukan 1, berarti kolom tersebut memiliki proses induk. Coba bunuh id proses induk itu .

Jika PPID = 1, JANGAN BUNUH !! , pikirkan perangkat atau proses lain mana yang mungkin terkait dengannya.

Misalnya, jika Anda menggunakan perangkat atau samba yang terpasang, cobalah untuk melepasnya. Itu mungkin melepaskan proses Zombie.

CATATAN : Jika ps -Al(atau top) menunjukkan "D" dan bukan "Z", itu bisa terkait dengan pemasangan jarak jauh (seperti NFS). Dalam pengalaman saya, me-reboot adalah satu-satunya cara untuk pergi ke sana, tetapi Anda dapat memeriksa jawaban lain yang mencakup kasus itu secara lebih rinci.

lepe
sumber
1
Mengirim SIGCHLD ke proses induk dapat menyebabkan orangtua mengenali proses tersebut telah mati. Ini harus bekerja bahkan ketika PPID = 1. Ini biasanya dikirim oleh kernel, tetapi dapat dikirim juga ke induk melalui kill (kill -17 di Linux, periksa halaman manual di * nix lain). Penggunaan membunuh ini tidak akan benar-benar "membunuh" orang tua, tetapi (re) memberitahukan bahwa seorang anak telah meninggal dan perlu dibersihkan. Perhatikan bahwa sigchld harus dikirim ke induk zombie, bukan zombie itu sendiri.
Stephanie
10

Proses init kebal terhadap SIGKILL.

Ini juga berlaku untuk utas kernel, yaitu "proses" dengan PPID sama dengan 0.

Jlliagre
sumber
1
Tugas kernel juga bisa kebal terhadap SIGKILL. Ini cukup sering terjadi pada Btrfs.
Tobu
9

Seperti yang disebutkan orang lain, proses tidur tanpa gangguan tidak dapat langsung dibunuh (atau, dalam beberapa kasus, sama sekali). Perlu dicatat bahwa keadaan proses lain, TASK_KILLABLE, ditambahkan untuk menyelesaikan masalah ini dalam skenario tertentu, terutama kasus umum di mana proses menunggu di NFS. Lihat http://lwn.net/Articles/288056/

Sayangnya saya tidak percaya ini digunakan di mana pun di kernel kecuali NFS.


sumber
Saya mengalami masalah dalam menghentikan lsproses mengakses sebuah sshfsmount, ketika server jauh tidak dapat diakses. Apakah ada solusi untuk FUSE atau sshfs, yang dapat saya gunakan di masa depan untuk menghindari situasi seperti itu? 2.6.30 kernel
imz - Ivan Zakharyaschev
@imz Ada saran dari Gilles (untuk membunuh sshfs) - unix.stackexchange.com/a/5648/4319 .
imz - Ivan Zakharyaschev
6

Membuat naskah kecil yang banyak membantu saya memeriksanya!

Anda dapat menggunakannya untuk membunuh proses apa pun dengan nama yang diberikan di jalurnya (perhatikan ini !!) Atau Anda dapat membunuh proses apa pun dari pengguna yang diberikan menggunakan parameter "-u nama pengguna".

#!/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
pengguna36035
sumber
4
Alih-alih hanya menautkannya, bisakah Anda memposting kode di sini.
tshepang
3
Tambahkan sedikit deskripsi dengan (atau setidaknya sebagai gantinya) dari kode ...
vonbrand
Yup tetapi "$ name" lebih mengagregasi ... itu akan mematikan semua proses dengan "$ name" di lintasan yang sedang berjalan. Bisa sangat berguna ketika Anda memiliki baris perintah besar ini dan Anda tidak tahu apa nama prosesnya.
user36035
5

Ada kasus di mana bahkan jika Anda mengirim kill -9 ke suatu proses, pid itu akan berhenti, tetapi proses restart secara otomatis (misalnya, jika Anda mencobanya gnome-panel, akan restart): mungkinkah itu terjadi di sini?

dag729
sumber
8
Ketika sesuatu seperti ini terjadi, PID sebenarnya berubah. Jadi saya akan perhatikan.
tshepang
2

dari sini awalnya :

periksa apakah strace menunjukkan sesuatu

strace -p <PID>

coba lampirkan ke proses dengan gdb

gdb <path to binary> <PID>

jika proses berinteraksi dengan perangkat yang dapat Anda lepas, lepaskan modul kernel untuk, atau putuskan secara fisik / cabut ... lalu coba itu.

nmz787
sumber
Bekerja untukku! (mencabut perangkat USB, yang menggantung teks-luhur)
nmz787
1

Saya punya masalah seperti ini. Ini adalah program yang saya luncurkan stracedan interupsi dengan Ctrl+ C. Itu berakhir dalam keadaan T(dilacak atau dihentikan). Saya tidak tahu bagaimana persisnya itu terjadi, tetapi itu tidak bisa dibunuh SIGKILL.

Singkat cerita, saya berhasil membunuhnya dengan gdb:

gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit
Christophe Drevet-Droguet
sumber
-1

Berdasarkan petunjuk dari jawaban gilles, saya memiliki proses bertanda "Z" di atas ( <defunct>dalam ps) yang menggunakan sumber daya sistem, bahkan memiliki port terbuka yang MENDENGARKAN dan Anda dapat terhubung ke port itu. Ini setelah mengeksekusi kill -9di atasnya. Induknya adalah "1" (yaitu init) sehingga secara teoritis ia harus diulang dan menghilang. Tapi tidak, itu tetap ada, meskipun tidak berlari, dan "tidak sekarat"

Jadi dalam kasus saya itu adalah zombie tetapi masih memakan sumber daya ... FWIW.

Dan itu tidak killable oleh sejumlah kill -9's

Dan orang tuanya adalah inittetapi tidak menuai (dibersihkan). Yaitu initmemiliki anak zombie.

Dan reboot tidak perlu untuk memperbaiki masalah. Meskipun reboot "akan berhasil" di sekitar masalah / membuatnya lebih cepat mati. Hanya tidak anggun, yang masih memungkinkan.

Dan itu adalah port DENGARKAN yang dimiliki oleh proses zombie (dan beberapa port lain juga seperti status CLOSE_WAIT menghubungkan localhost ke localhost). Dan itu bahkan masih menerima koneksi. Bahkan sebagai zombie. Saya kira itu belum sempat untuk membersihkan port sehingga koneksi masuk masih ditambahkan ke backlog mendengarkan port tcp, meskipun mereka tidak memiliki kesempatan untuk diterima.

Banyak hal di atas dinyatakan sebagai "mustahil" di berbagai tempat dalam jalinan.

Ternyata saya memiliki utas internal di dalamnya yang menjalankan "system call" (ioctl dalam contoh ini) yang memerlukan beberapa jam untuk kembali (ini adalah perilaku yang diharapkan). Rupanya sistem tidak dapat mematikan proses "sepanjang jalan" sampai ia kembali dari ioctlpanggilan, kira itu memasuki tanah kernel. Setelah beberapa jam kembali, semuanya beres dan soket semua secara otomatis ditutup, dll seperti yang diharapkan. Itu beberapa waktu mendekam di hukuman mati! Kernel dengan sabar menunggu untuk membunuhnya.

Jadi untuk menjawab OP, terkadang Anda harus menunggu. Waktu yang lama. Maka akhirnya membunuh akan mengambil.

Periksa juga dmesg untuk melihat apakah ada kepanikan kernel (mis. Bug kernel).

rogerdpack
sumber
Ini sepertinya Anda menggambarkan skenario spesifik Anda sendiri dan bukan jawaban atas pertanyaan. Dalam kasus Anda, proses memperbaiki sendiri karena operasi yang berjalan lama, sesuatu yang tidak disebutkan dalam pertanyaan. Namun Anda dipersilakan untuk mengajukan pertanyaan baru dan memberikan jawabannya juga. Meskipun saya khawatir pertanyaan itu akan ditutup sebagai "tidak dapat direproduksi", karena hasilnya khusus untuk implementasi Anda.
Centimane
Benar, saya menambahkan bagaimana ini menjawab OP, karena itu ... bisa, dalam beberapa kasus.
rogerdpack