Ya 'öldür -9' işe yaramazsa?


467

Öldüremediğim bir süreç var kill -9 <pid>. Böyle bir durumda sorun ne, özellikle de bu sürecin sahibi olduğum için. Bu killseçeneğin hiçbir şeyinden kaçabileceğini düşünmemiştim .

Yanıtlar:


561

kill -9( SIGKILL ) süreci öldürme izniniz olması kaydıyla her zaman çalışır. Temel olarak, ya süreç sizin tarafınızdan başlatılmalı ve hileli veya hükümsüz olmamalıdır, ya da kök olmalısınız. Bir istisna var: Kök bile PID 1'e ( initişlem) önemli bir sinyal gönderemiyor .

Ancak derhalkill -9 çalışması garanti edilmez . SIGKILL dahil tüm sinyaller asenkron olarak iletilir: çekirdeğin bunları iletmesi zaman alabilir. Genellikle, bir sinyalin iletilmesi, hedefin bir zaman dilimi alması için geçen süre kadar birkaç mikrosaniyeyi alır. Ancak, hedef sinyali bloke etmişse, hedef engeli kaldırıncaya kadar sinyal kuyruğa alınır.

Normalde, işlemler SIGKILL'i engelleyemez. Ancak çekirdek kodu sistem çağrıları çağırdığında çekirdek kodunu çalıştırabilir ve işler . Çekirdek kodu, sistem çağrısına ara verirken tüm sinyalleri engeller, çekirdeğin herhangi bir yerinde veya daha genel olarak bazı çekirdek değişmezlerinin ihlal edilmesine neden olan kötü oluşturulmuş bir veri yapısına neden olur. Bu nedenle (bir hata veya yanlış tasarım nedeniyle) bir sistem çağrısı süresiz olarak engellerse, süreci öldürmenin etkili bir yolu olmayabilir. (Ama süreç olacak hiç sistem çağrısı tamamlarsa öldürülebilir.)

Sistem çağrısında engellenen bir işlem kesintisiz uyku modundadır . psVeya topkomut (en Unix'lerde) devlet bunu gösterecektir D(başlangıçta “için d ISK” Bence).

Klasik kesintisiz uzun uyku durumu , sunucu yanıt vermediğinde dosyalara NFS üzerinden erişen süreçlerdir ; Modern uygulamalar kesintisiz bir uyku empoze etme eğilimindedir (örneğin Linux altında, intrmount seçeneği bir sinyalin NFS dosya erişimini kesmesine izin verir).

Bazen veya çıktıda işaretli Z(veya HLinux altında, ayrımın ne olduğunu bilmiyorum) girişleri görebilirsiniz . Bunlar teknik olarak süreç değil, süreç tablosuna girmekten başka bir şey olmayan zombi süreçleridir, böylece ebeveyn sürecin çocuğunun ölümünden haberdar olması sağlanır. Ana süreç dikkat ettiği zaman (veya öldüğü zaman) ortadan kalkarlar.pstop


92
Yor cevap kendini çelişkili görünüyor. SIGKILL'in her zaman işe yaradığını söylemeye başlarsınız, ancak SIGKILL'in çekirdeği kapatmanın dışında asla çalışamayacağı kesintisiz uyku durumundan bahsedersiniz. SIGKILL'in çalışmadığı iki durum var. Belli ki zombilerde zaten ölü süreçleri ve init ile öldüremezsiniz, ki bu da tasarım olarak SIGKILL sinyallerini görmezden geliyor.
jlliagre

41
@jlliagre: Bir zombi öldürmek anlam ifade etmiyor, başlamak için canlı değil. Ve interruptible uykusunda bir süreç öldürme yapar o asenkron (diğer sinyaller olduğu gibi) sadece, işi. Düzenlememde bunu açıklığa kavuşturmaya çalıştım.
Gilles

3
Bir zombi öldürmenin de bir anlam ifade etmiyor, ancak bu birçok insanın denemesini ve şikayet etmesini engellemiyor. Kesintisiz uykuda bir işlemi öldürmek gerçekten de tasarım gereğidir, ancak kesintisiz bir uykuda bir işlemi öldürmekten bahsediyordum, sistem çağrısı hiç uyanmazsa başarısız olabilen başarısız bir süreç.
jlliagre

11
man 5 nfs: " intr/ nointrMount seçeneği, 2.6.25 çekirdeğinden sonra kullanımdan kaldırıldı. Yalnızca SIGKILL, bu çekirdeklerde bekleyen bir NFS işlemini durdurabilir ve belirtilirse, eski sürümlerle geriye dönük uyumluluk sağlamak için bu mount seçeneği yoksayılır."
Martin Schröder

4
@ imz - IvanZakharyaschev Bildiğimden değil (ama bilmeyeceğim). Sshfs ile, son çare olarak, sshfssüreci öldürebilirsiniz (ve benzer şekilde herhangi bir diğer FUSE dosya sistemiyle de: bu şekilde her zaman zorla kaldırabilirsiniz).
Gilles

100

Bazen bir süreç var ve aşağıdakiler nedeniyle öldürülemiyor:

  • zombi olmak. Yani hangi ebeveynin çıkış durumunu okumadığı işlenir. Bu işlem, PID girişi dışında herhangi bir kaynak tüketmez. İçinde topZ sinyali var
  • hatalı kesintisiz uyku. Olmaması gerekir, ancak bazen yapılan buggy çekirdek kodu ve / veya buggy donanımı ile birlikte. Tek yöntem yeniden başlatmak veya beklemektir. İçinde topD ile sinyal verilir.

2
Zombie kaynak tüketmiyor mu?
Luc M

7
@ Luc M: AFAIK hayır (en azından Linux'ta) - işlem tablosuna giriş hariç (örneğin, sahip, çıkış durumu vb. Bilgilerle birlikte PID). Sadece sona erdirildiği tarafın onayını bekleyen süreçtir.
Maciej Piechotka

18
@ xenoterracide: Sonunda evet, ancak ebeveyn süreci hala devam ederse (örneğin gnome seansı veya benzer bir rolü yerine getiren bir şey) hala zombilere sahip olabilirsiniz. Teknik olarak temizlik üst işin üstesinden gelir ancak zombi yetim kaldıktan sonra temizler (terminoloji, unix sınıflarının kapalı kapılarla yapılmasının nedenidir - öksüzler, zombiler ve bir cümleyi öldüren herkesin yanlış ifadesi olabilir).
Maciej Piechotka

5
“... tek yöntem yeniden başlatmak veya beklemektir.” Ne kadar bekleyin? Beş ay geçti ve zombilerim hala orada.
DarenW

3
@ Ebeveyni çocukların ölümünü kabul edene kadar Dur. Detaylar için lütfen programın yazarına danışın.
Maciej Piechotka

32

Bir zombi sürecin varmış gibi geliyor . Bu zararsızdır: Bir zombi işleminin tükettiği tek kaynak, işlem tablosuna bir giriştir. Ebeveyn süreci öldüğünde veya çocuğunun ölümüne tepki gösterdiğinde ortadan kalkar.

topAşağıdaki komutu kullanarak işlemin bir zombi olup olmadığını görebilirsiniz :

ps aux | awk '$8=="Z" {print $2}'

13
Bu tür "zor" alan adlarını hep beğenmedim ps. İstenilen alanın her zamanps Tüm Unice'lerin uygulamalarıyla 8. sırada olacağından kim emin olabilir ?
syntaxerror

26

Herhangi bir ipucu için sizin /var/log/kern.logve /var/log/dmesg(veya eşdeğerleriniz) olup olmadığını kontrol edin . Tecrübelerime göre bu bana ancak bir NFS montajının ağ bağlantısı aniden düştüğünde ya da bir aygıt sürücüsü kilitlendiğinde başıma geldi. Sanırım bir sabit disk de çökerse meydana gelebilir.

lsofİşlemin hangi cihaz dosyalarını açtığını görmek için kullanabilirsiniz .


6
NFS'den bahsetmek için +1. Birkaç yıl önce bu bana birkaç ayda bir başıma geldi - eğer NFS sunucusu çökerse, tüm (yamalı) RHEL kutularındaki NFS müşterileri askıda kalacaktı. kill -9genellikle 60 dakika bekledikten sonra bile işe yaramadı. Tek çözüm yeniden başlatmaktı.
Stefan Lasiewski

17

@ Maciej 'in ve @ Gilles ' nun cevabı probleminizi çözmezse ve süreci tanımıyorsanız (ve dağıtımınızla ne olduğunu sormak cevap vermez). Rootkit en ve oldum başka işaretler edin olunan . Bir rootkit, süreci öldürmenizi engellemekten daha fazlasını sağlar. Aslında birçoğu onları görmenizi engelleyebilir. Ancak 1 küçük programı değiştirmeyi unuturlarsa, farkedilebilirler (örneğin, değiştirdiler topama değil htop). Büyük olasılıkla durum bu değil, üzgünümden daha güvenli.


Sanırım birçok rootkit, işleri daha basit hale getirmek için kendilerini çekirdeğe sokuyor (kullanıcının neye sahip olduğunu tahmin etmeye gerek yok ve MB yamalı programları indirmeye gerek yok). Ancak yine de kontrol etmeye değer (++ oy).
Maciej Piechotka

11

Öldürmek aslında bir sinyal yollamak demektir. gönderebileceğiniz birden fazla sinyal var. kill -9 özel bir sinyaldir.

Bir sinyal gönderirken uygulama bununla ilgilenir. eğer çekirdek bununla uğraşmazsa. Böylece uygulamanızdaki bir sinyali yakalayabilirsiniz.

Ama öldür -9'un özel olduğunu söyledim. Uygulamanın alamadığı özel bir şey. doğruca çekirdeğe gider ve daha sonra ilk fırsatta uygulamayı gerçekten öldürür. başka bir deyişle, onu öldürür

kill -15, SİNYAL TERMİNAT'ın anlamına gelen SIGTERM sinyalini gönderir, başka bir deyişle, uygulamanın bırakmasını söyler. Bu, bir uygulamanın kapanma zamanının geldiğini söylemenin kolay yoludur. Ancak uygulama yanıt vermiyorsa kill -9 onu öldürür.

öldür -9 işe yaramazsa, muhtemelen çekirdeğiniz tükenir demektir. bir yeniden başlatma sırası var. Bunun olduğunu asla hatırlayamıyorum.


5
15 SIGTERM'dir (dostça öldürme), SIGHUP değil. YÜKSELTME, kontrol terminalinin kapanması veya iletişim kanalının kaybolması içindir
JoelFan

11

İlk önce, bunun bir Zombie işlemi olup olmadığını kontrol edin (ki bu çok mümkün):

ps -Al

Gibi bir şey göreceksiniz:

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

(Soldaki "Z" yi not edin)

5. sütun 1 değilse, bunun bir üst süreci olduğu anlamına gelir. Bu ana işlem kimliğini öldürmeyi deneyin .

Eğer PPID = 1 ise, ÖLMEYİN! Başka hangi cihazların veya işlemlerin onunla ilişkili olabileceğini düşünün.

Örneğin, monte edilmiş bir cihaz veya samba kullanıyorsanız, bağlantısını kesmeyi deneyin. Bu Zombie işlemini serbest bırakabilir.

NOT : ps -Al(veya top) "Z" yerine "D" gösteriyorsa, uzaktan montajla (NFS gibi) ilgili olabilir. Tecrübelerime göre, yeniden başlatma oraya gitmek için tek yol, ancak bu durumu kapsayan diğer cevapları daha ayrıntılı olarak kontrol edebilirsiniz.


1
SIGCHLD’nin ebeveyn sürecine gönderilmesi, ebeveynin işlemin öldüğünü fark etmesine neden olabilir. Bu, PPID = 1 olsa bile çalışmalıdır. Bu normalde çekirdek tarafından gönderilir, ancak ebeveynle birlikte kill yoluyla da gönderilebilir (Linux'ta -17'yi öldür, diğer sayfalardaki man sayfalarını kontrol et). Bu öldürme kullanımı aslında ebeveyni “öldürmez”, fakat bunun yerine (yeniden) çocuğun öldüğünü ve temizlenmesi gerektiğini bildirir. Sigchld'in zombinin kendisine değil zombinin ebeveyne gönderilmesi gerektiğine dikkat edin.
Stephanie

10

İnit işlemi SIGKILL'e karşı bağışıklık kazanmıştır.

Bu aynı zamanda çekirdek dişleri için de geçerlidir, yani 0'a eşit bir PPID ile "işlemler".


1
Çekirdek görevleri de SIGKILL'e karşı bağışık olabilir. Bu, Btrfs ile yeterince sık olur.
Tobu,

9

Diğerlerinin de belirttiği gibi, kesintisiz uykudaki bir süreç hemen (veya bazı durumlarda hiç) öldürülemez. Bu sorunu belirli senaryolarda, özellikle sürecin NFS'de beklediği genel durum için çözmek için TASK_KILLABLE adlı başka bir işlem durumunun eklendiğini belirtmekte fayda var. Bkz http://lwn.net/Articles/288056/

Ne yazık ki, bunun çekirdeğin herhangi bir yerinde kullanıldığına inanmıyorum ama NFS.


Uzak sunucuya erişilemediğinde, bir bağa lserişen bir işlemi öldürme sorunlarım vardı sshfs. Bu tür durumlardan kaçınmak için gelecekte kullanabileceğim FUSE veya sshfs için bir çözüm var mı? 2.6.30 çekirdek
imz - Ivan Zakharyaschev

@ imz Gilles'dan (sshfs'i öldürmek için) bir tavsiye var - unix.stackexchange.com/a/5648/4319 .
imz - Ivan Zakharyaschev 30:13

6

Bana bir göz atmam için çok yardımcı olan küçük bir senaryo yaptım!

Belirli bir isimdeki herhangi bir işlemi yolunda öldürmek için kullanabilirsiniz (buna dikkat edin !!) Veya "-u username" parametresini kullanarak belirli bir kullanıcının herhangi bir işlemini öldürebilirsiniz.

#!/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

4
Sadece link vermek yerine, kodu buraya postalayabilirsiniz.
tshepang

3

Evet ama "$ name" daha fazla toplayıcıdır ... "$ name" ile çalışan yolunda herhangi bir işlemi öldürür. Bu büyük komut satırlarına sahip olduğunuzda ve işlem adının ne olduğunu bilmiyorsanız çok yararlı olabilir.
user36035

5

Bir sürece bir öldür -9 gönderseniz bile, bu ödemenin durduğu, ancak işlemin otomatik olarak yeniden başlatıldığı durumlar var (örneğin, denerseniz gnome-panel, yeniden başlatılacak): bu durumda olabilir mi?


8
Böyle bir şey olduğunda, PID aslında değişir. Böylece fark ederdim.
tshepang

2

dan aslen burada :

Strace bir şey gösterip göstermediğini kontrol et

strace -p <PID>

gdb ile işleme eklemeyi deneyin

gdb <path to binary> <PID>

İşlem, sökebildiğiniz bir cihazla etkileşime giriyorsa, çekirdek modülünü çıkarın veya fiziksel olarak bağlantısını kesin / çıkarın ... sonra bunu deneyin.


Benim için çalıştı! (yüce metni asılı olan USB aygıtını
çıkarma

1

Bu konuda bir sorunum vardı. Bu + straceile başlattığım ve ara verdiğim bir programdı . Sonunda (izlendi veya durdu) bir duruma geldi. Tam olarak nasıl olduğunu bilmiyorum, ama katlanılabilir değildi .CtrlCTSIGKILL

Uzun lafın kısası, onu öldürmeyi başardım gdb:

gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit

-1

Gilles'in cevabından gelen bir ipucuna dayanarak, <defunct>sistem kaynaklarını kullanan üstte ( ps cinsinden) "Z" işaretli bir işlem vardı, LISTEN'ing olan bir bağlantı noktası açık bile oldu ve o bağlantı noktasına bağlanabiliyordunuz. Bu, kill -9üzerinde bir çalıştırdıktan sonra oldu . Onun ebeveyn "1" (yani init) öyleydi, bu yüzden teorik olarak sadece tekrarlanmalı ve kaybolmalı. Ama değildi, etrafta dolaşıyordu, koşmasa da "ölmüyordu"

Yani benim durumumda zombi ama yine de kaynakları tüketiyordu ... FWIW.

Ve herhangi sayısına göre killable değildi kill -9's

Ve onun ebeveyni vardı, initancak ulaşılmıyordu (temizlendi). Yani initbir zombi çocuğu vardı.

Ve sorunu çözmek için yeniden başlatma gerekli değildi. Bir yeniden başlatma sorunu etrafında "işe yaramazdı" olsa da / bunu daha hızlı kapatmayı başardı. Sadece zarif değil, yine de mümkündü.

Ve bir zombi işlemine ait bir LISTEN limanıydı (ve ayrıca, localhost'u localhost'a bağlı CLOSE_WAIT statüsüne benzeyen birkaç başka liman). Ve hala bağlantıları bile kabul ediyordu. Bir zombi olarak bile. Sanırım limanları temizlemek için etrafta dolaşmadı, bu yüzden kabul edilme şansı olmamasına rağmen, tcp dinleme portunun backlog'una gelen bağlantılar hala eklendi.

Yukarıdakilerin çoğu interweblerde çeşitli yerlerde "imkansız" olarak belirtilmiştir.

İçinde, bir "sistem çağrısı" (bu örnekte ioctl) yürüten ve bu işlemin geri dönüşünün birkaç saat sürdüğü (bu beklenen davranıştı) içsel bir iş parçacığım olduğu anlaşılıyor. Görünüşe göre sistem ioctlçağrıdan geri dönene kadar süreci "tamamen" öldüremiyor , sanırım çekirdek toprağa giriyor. Birkaç saat sonra geri döndü, işler düzeldi ve yuvalar beklendiği gibi otomatik olarak kapatıldı. Ölüm sırasındaki biraz sıkıcı zaman! Çekirdek sabırla onu öldürmeyi bekliyordu.

Yani OP'ye cevap vermek için bazen beklemek zorundasın. Uzun zaman. O zaman öldürme sonunda alacak.

Ayrıca bir çekirdek paniği olup olmadığını görmek için dmesg'i kontrol edin (örn. Çekirdek böceği).


Bu, sorunun cevabını değil kendi senaryoyu tarif ediyor gibisin. Sizin durumunuzda, süreç uzun süren bir işlem nedeniyle kendi başına düzeltti, soruda bahsedilmeyen bir şey. Bununla birlikte, yeni bir soru sormak ve bu sorunun cevabını sağlamak için bekliyoruz. Her ne kadar sonuç uygulamanıza özel olduğundan, bu sorunun "tekrarlanamaz" şeklinde kapanmasından korktuğum halde.
Centimane

Doğru, bazı durumlarda OP'nin nasıl yanıt verdiğini ... ekleyebiliyorum.
rogerdpack
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.