it-swarm-tr.com

Ya 'öldür -9' çalışmazsa?

kill -9 <pid> İle öldüremediğim bir süreç var. Böyle bir durumda sorun ne, özellikle bu sürecin sahibi olduğum için. Hiçbir şeyin kill seçeneğinden kaçamayacağını düşündüm.

491
tshepang

kill -9 ( SIGKILL ) süreci öldürme izniniz varsa her zaman çalışır. Temel olarak, işlem sizin tarafınızdan başlatılmalı ve setuid veya setgid olmamalı veya root olmalısınız. Bir istisna vardır: Kök bile PID 1'e (init işlemi) ölümcül bir sinyal gönderemez.

Ancak kill -9'nin çalışması garanti edilmez hemen. SIGKILL dahil olmak üzere tüm sinyaller eşzamansız olarak gönderilir: çekirdek bunları iletmek için zaman alabilir. Genellikle, bir sinyalin iletilmesi en fazla birkaç mikrosaniye sürer, sadece hedefin bir zaman dilimi elde etmesi için geçen süre. Ancak, hedef sinyali engelledi ise, hedef engellemesini kaldırana kadar sinyal kuyruğa alınır.

Normalde işlemler SIGKILL'i engelleyemez. Ancak çekirdek kodu, sistem çağrıları çağrıldığında işlemler çekirdek kodunu yürütebilir. Çekirdek kodu, sistem çağrısını kesintiye uğrattığında tüm sinyalleri engeller, çekirdeğin bir yerinde kötü şekillendirilmiş veri yapısına veya daha genel olarak bazı çekirdek değişmezlerinin ihlal edilmesine neden olur. Bu nedenle (bir hata veya yanlış tasarım nedeniyle) bir sistem çağrısı süresiz olarak engellenirse, süreci öldürmenin etkili bir yolu olmayabilir. (Ancak sistem çağrısını tamamlarsa will işlemi öldürülür.)

Sistem çağrısında engellenen bir işlem kesintisiz uyk . ps veya top komutu (çoğu unice'de) D durumunda (başlangıçta “ d isk ”, sanırım).

Klasik kesintisiz uzun uyku durumu, sunucu yanıt vermediğinde dosyalara erişim işleminin NFS ; modern uygulamalar kesintisiz uyku empoze etmeme eğilimindedir (örneğin Linux altında intr mount seçeneği bir sinyalin NFS dosya erişimini kesmesine izin verir).

Z veya H çıktısında bazen Linux altında ps (veya top olarak işaretlenmiş girişler görebilirsiniz. Bunlar teknik olarak süreçler değildir, süreç tablosundaki bir girişten başka bir şey olmayan zombi süreçleridir, böylece ana süreç çocuğunun ölümünden haberdar edilebilir. Ana süreç dikkat (veya öldüğünde) ortadan kaybolacaktır.

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

  • zombi olmak. Yani hangi ebeveynin çıkış durumunu okumadığını gösterir. Bu süreç PID girişi dışında herhangi bir kaynak tüketmez. top 'da Z sinyali verilir
  • hatalı kesintisiz uyku. Bu olmamalı, ancak ara sıra çekirdek kodu ve/veya buggy donanımının bir kombinasyonu ile. Tek yöntem yeniden başlatmak veya beklemektir. top 'da D ile belirtilir.
101
Maciej Piechotka

Bir zombi süreci olabilir gibi görünüyor. Bu zararsızdır: bir zombi sürecinin tükettiği tek kaynak işlem tablosundaki bir girdidir. Ebeveyn süreci öldüğünde veya çocuğunun ölümüne tepki gösterdiğinde ortadan kaybolacaktır.

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

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

/var/log/kern.log ve /var/log/dmesg (veya eşdeğerleri). Deneyimlerime göre bu sadece bir NFS montajının ağ bağlantısı aniden düştüğünde veya bir aygıt sürücüsü çöktüğünde bana oldu. Bir sabit sürücü de çökerse gerçekleşebilir, inanıyorum.

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

26
LawrenceC

@ Maciej 's ve @ Gilles ' ın cevabı sorununuzu çözmezse ve işlemi tanımıyorsanız (ve dağıtımınızla ne olduğunu sormak istemiyorsanız) cevapları açmayın). Rootkit ve sahip olduğunuz diğer işaretleri kontrol edin . Bir rootkit, süreci öldürmenizi önlemekten daha fazlasıdır. Aslında birçoğu onları görmenizi engelleyebilir. Ancak 1 küçük programı değiştirmeyi unuturlarsa, tespit edilebilirler (örneğin, top değiştirdiler, ancak htop değiştirmediler). Büyük olasılıkla durum böyle değil ama üzülmekten daha güvenli.

17
xenoterracide

Kill aslında sinyal göndermek anlamına gelir. gönderebileceğiniz birden fazla sinyal var. kill -9 özel bir sinyaldir.

Bir sinyal gönderilirken uygulama bununla ilgilenir. değilse çekirdek onunla ilgilenir. böylece uygulamanızda bir sinyal yakalayabilirsiniz.

Ama öldürmek -9 özeldir dedim. Uygulama almıyor özeldir. doğrudan çekirdeğe gider ve bu da uygulamayı mümkün olan ilk fırsatta gerçekten öldürür. başka bir deyişle onu öldürüyor

kill -15, SİNYAL TERMİNAT anlamına gelen SIGTERM sinyalini gönderir; başka bir deyişle, uygulamanın sonlandırılmasını söyler. Bu, bir uygulamaya kapanmanın zamanı geldiğini söylemenin kolay yoludur. ancak uygulama yanıt vermiyorsa kill -9 onu öldürecektir.

eğer öldürmek -9 işe yaramazsa, muhtemelen çekirdeğinizin sıkışması demektir. yeniden başlatma sırası. Bunu hiç hatırlamıyorum.

11
DeveloperChris

İlk olarak, bir Zombi işlemi olup olmadığını kontrol edin (ki bu çok mümkündür):

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, üst işlemi olduğu anlamına gelir. Bu üst işlem kimliğini öldürmeyi deneyin.

PPID = 1, BUNU ÖLDÜRMEYİN !!, diğer aygıtların veya işlemlerin bununla ilgili olabileceğini düşünün.

Örneğin, takılı bir aygıt veya samba kullanıyorsanız, bağlantısını kesmeyi deneyin. Bu Zombi sürecini serbest bırakabilir.

NOT : Eğer ps -Al (veya top), "Z" yerine "D" gösterir, uzak bağlantıyla (NFS gibi) ilişkili olabilir. Deneyimlerime göre, yeniden başlatma oraya gitmenin tek yoludur, ancak bu konuyu kapsayan diğer cevapları daha ayrıntılı olarak kontrol edebilirsiniz.

11
lepe

Başlatma süreci SIGKILL'e karşı bağışıktır.

Bu, çekirdek iş parçacıkları için de geçerlidir, yani PPID değeri 0'a eşit olan "işlemler".

10
jlliagre

Diğerlerinin de belirttiği gibi, kesintisiz uykudaki bir süreç hemen öldürülemez (veya bazı durumlarda hiç). Bu sorunu belirli senaryolarda, özellikle de sürecin NFS'de beklediği yaygın durumda çözmek için başka bir işlem durumunun (TASK_KILLABLE) eklendiğini belirtmek gerekir. Bakınız http://lwn.net/Articles/288056/

Ne yazık ki bunun çekirdekte değil, NFS'de kullanıldığına inanmıyorum.

10
user36054

Bana çok yardımcı olan küçük bir senaryo hazırladım!

Yolunda belirli bir adla herhangi bir işlemi öldürmek için kullanabilirsiniz (buna dikkat edin !!) Veya "-u kullanıcı adı" 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
6
user36035

Bir işleme bir kill -9 gönderseniz bile, bu pid'in duracağı, ancak işlemin otomatik olarak yeniden başlatıldığı durumlar vardır (örneğin, gnome-panel, yeniden başlayacak): burada durum böyle olabilir mi?

5
dag729

burada başlangıçta :

strace'nin bir şey gösterip göstermediğini kontrol et

strace -p <PID>

gdb ile sürece eklemeyi deneyin

gdb <path to binary> <PID>

i̇şlem, bağlantısını kaldırabileceğiniz bir cihazla etkileşime giriyorsa, için çekirdek modülünü çıkarın veya fiziksel olarak bağlantısını kesin/çıkarın ... sonra bunu deneyin.

2
nmz787

Bu tür bir sorunum vardı. Bu, strace ile başlattığım ve Ctrl + C ile böldüğüm bir programdı. Bir T (izlendi veya durduruldu) durumunda sona erdi. Tam olarak nasıl olduğunu bilmiyorum, ama SIGKILL ile fırlanabilir değildi.

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

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

Solungaçların cevabından alınan bir ipucuna dayanarak, sistem kaynaklarını kullanan "Z" ("" olarak işaretlenmiş) bir süreç yaşadım, hatta DİNLENEN bir bağlantı noktası açıktı ve ona bağlanabilirsiniz. Bu bir kill -9 üstünde. Ebeveyni "1" (yani init) idi, bu yüzden teorik olarak ortadan kalkmalı. Ama öyle değildi, koşmamaya rağmen etrafta dolaşıyordu.

Benim durumumda zombi vardı ama hala kaynak tüketiyor ... FWIW.

Ve kill -9.

Üst öğesi init idi, ancak biçilmemişti (temizlenmemiş). Yani init'in bir zombi çocuğu vardı.

Ve sorunu çözmek için yeniden başlatma gerekli değildi. Rağmen bir yeniden başlatma "sorun" etrafında çalıştı/hızlı kapatma yaptı. Zarif değil, yine de mümkün oldu.

Ve bir zombi sürecinin sahip olduğu bir LISTEN portuydu (ve yerel ana makineye localhost'a bağlı CLOSE_WAIT durumu gibi birkaç bağlantı noktası). Ve hala bağlantıları bile kabul etti. Bir zombi olarak bile. Sanırım bağlantı noktalarını temizlemek için etrafta dolaşmamıştı, bu yüzden gelen bağlantılar hala kabul etme şansı olmasa da tcp dinleme bağlantı noktasının biriktirmesine eklenmişti.

İçinde bir "sistem çağrısı" (bu örnekte ioctl) yürüten bir iç iş parçacığı olduğu ortaya çıkıyor ki bu geri dönmek için birkaç saat sürdü (bu bekleniyordu). Görünüşe göre sistem, geri dönene kadar onu "tamamen" öldüremez. Birkaç saat sonra temizlendi ve soketler beklendiği gibi otomatik olarak kapatıldı. Bu biraz durgun ölüm zamanı!

Ayrıca bir çekirdek paniği (yani çekirdek hatası) olup olmadığını görmek için dmesg'i kontrol edin.

0
rogerdpack