Mam proces, którego nie mogę zabić kill -9 <pid>
. Jaki jest problem w takim przypadku, zwłaszcza że jestem właścicielem tego procesu. Myślałem, że nic nie może uniknąć tej kill
opcji.
kill -9
( SIGKILL ) zawsze działa, pod warunkiem, że masz pozwolenie na zabicie procesu. Zasadniczo albo proces musi zostać rozpoczęty przez ciebie, a nie być ustawiony jako setuid lub setgid, albo musisz być rootem. Jest jeden wyjątek: nawet root nie może wysłać fatalnego sygnału do PID 1 ( init
proces).
Nie kill -9
gwarantuje się jednak natychmiastowej pracy . Wszystkie sygnały, w tym SIGKILL, są dostarczane asynchronicznie: jądro może zająć trochę czasu, aby je dostarczyć. Zwykle dostarczenie sygnału zajmuje najwyżej kilka mikrosekund, tyle ile potrzeba, aby cel otrzymał przedział czasu. Jeśli jednak cel zablokował sygnał , sygnał będzie w kolejce, dopóki cel go nie odblokuje.
Zwykle procesy nie mogą blokować SIGKILL. Ale kod jądra może i procesy wykonują kod jądra, gdy wywołują wywołania systemowe . Kod jądra blokuje wszystkie sygnały, gdy przerwanie wywołania systemowego spowodowałoby źle sformułowaną strukturę danych gdzieś w jądrze, lub bardziej ogólnie, naruszenie niektórych niezmienników jądra. Więc jeśli (z powodu błędu lub błędnego zaprojektowania) wywołanie systemowe blokuje się w nieskończoność, może nie być skutecznie zabić tego procesu. (Ale proces zostanie zabity, jeśli kiedykolwiek zakończy wywołanie systemowe).
Proces zablokowany w wywołaniu systemowym znajduje się w nieprzerwanym trybie uśpienia . Polecenie ps
lub top
pokaże (w większości jednorożców) stan D
(pierwotnie jak sądzę dla „ d isk”).
Klasycznym przypadkiem długiego nieprzerwanego uśpienia są procesy uzyskiwania dostępu do plików przez NFS, gdy serwer nie odpowiada; nowoczesne implementacje zwykle nie narzucają nieprzerwanego uśpienia (np. w Linuksie intr
opcja montowania pozwala na sygnał przerywający dostęp do plików NFS).
Można czasem zobaczyć wpisy oznaczone Z
(lub H
pod Linuksem, nie wiem jaka jest różnica) w ps
lub top
wyjście. Nie są to technicznie procesy, są to procesy zombie, które są niczym więcej niż wpisem w tabeli procesów, przechowywanym tak, aby proces nadrzędny mógł zostać powiadomiony o śmierci swojego dziecka. Odejdą, gdy proces nadrzędny zwróci uwagę (lub umrze).
man 5 nfs
: „Opcjaintr
/nointr
mount jest przestarzała po jądrze 2.6.25. Tylko SIGKILL może przerwać oczekującą operację NFS na tych jądrach, a jeśli jest określona, ta opcja montowania jest ignorowana, aby zapewnić zgodność wsteczną ze starszymi jądrami.”sshfs
proces (i podobnie z dowolnym innym systemem plików FUSE: zawsze możesz wymusić odmontowanie w ten sposób).Czasami istnieje proces i nie można go zabić z powodu:
top
tym sygnalizowane jest Ztop
tym sygnalizuje D.źródło
Wygląda na to, że masz proces zombie . Jest to nieszkodliwe: jedynym zasobem zużywanym przez proces zombie jest wpis w tabeli procesów. Odejdzie, gdy proces rodzicielski umrze lub zareaguje na śmierć dziecka.
Możesz sprawdzić, czy proces jest zombie za pomocą
top
lub następującego polecenia:źródło
ps
. Kto może być pewien, że wymagane pole będzie zawsze ósme, ze wszystkimi implementacjamips
we wszystkich Uniksach?Sprawdź swoje
/var/log/kern.log
i/var/log/dmesg
(lub ich odpowiedniki) pod kątem jakichkolwiek wskazówek. Z mojego doświadczenia wynika, że zdarzyło mi się to tylko wtedy, gdy połączenie sieciowe uchwytu NFS nagle spadło lub nastąpił awaria sterownika urządzenia. Może się zdarzyć, jeśli dysk twardy również się zawiesi.Możesz użyć,
lsof
aby zobaczyć, jakie pliki urządzenia otworzył proces.źródło
kill -9
zwykle nie działało, nawet po odczekaniu 60 minut. Jedynym rozwiązaniem było ponowne uruchomienie.Jeśli odpowiedzi @ Macieja i @ Gillesa nie rozwiążą twojego problemu, a ty nie rozpoznajesz procesu (i pytanie, co to jest z twoją dystrybucją, nie pojawia się odpowiedzi). Sprawdź Rootkita i wszelkie inne znaki, które były Twoją własnością . Rootkit jest więcej niż w stanie zapobiec zabiciu tego procesu. W rzeczywistości wielu jest w stanie uniemożliwić ci ich zobaczenie. Ale jeśli zapomną zmodyfikować 1 mały program, mogą zostać zauważeni (np. Zmodyfikowali
top
, ale niehtop
). Najprawdopodobniej tak nie jest, ale lepiej zabezpieczyć niż przepraszać.źródło
Kill faktycznie oznacza wysłanie sygnału. istnieje wiele sygnałów, które możesz wysłać. kill -9 to specjalny sygnał.
Podczas wysyłania sygnału aplikacja się tym zajmuje. jeśli nie, jądro sobie z tym poradzi. dzięki czemu można złapać sygnał w aplikacji.
Ale powiedziałem, że kill -9 był wyjątkowy. Jest to wyjątkowe, ponieważ aplikacja go nie otrzymuje. idzie prosto do jądra, które następnie naprawdę zabija aplikację przy pierwszej możliwej okazji. innymi słowy zabija go martwego
kill -15 wysyła sygnał SIGTERM, który oznacza SIGNAL TERMINATE, innymi słowy, informuje aplikację o zakończeniu. Jest to przyjazny sposób na poinformowanie aplikacji, że czas zamknąć. ale jeśli aplikacja nie odpowiada, zabij -9.
jeśli kill -9 nie działa, prawdopodobnie oznacza to, że twoje jądro nie działa. ponowne uruchomienie jest w porządku. Nie pamiętam, żeby to się kiedykolwiek wydarzyło.
źródło
Najpierw sprawdź, czy jest to proces Zombie (co jest bardzo możliwe):
Zobaczysz coś takiego:
(Zwróć uwagę na „Z” po lewej)
Jeśli piąta kolumna nie jest 1, oznacza to, że ma proces nadrzędny. Spróbuj zabić ten identyfikator procesu nadrzędnego .
Jeśli jego PPID = 1, NIE ZABIJ GO !! , zastanów się, które inne urządzenia lub procesy mogą być z tym powiązane.
Na przykład, jeśli korzystasz z zamontowanego urządzenia lub samby, spróbuj odmontować. To może uwolnić proces Zombie.
UWAGA : Jeśli
ps -Al
(lubtop
) pokazuje „D” zamiast „Z”, może to być związane ze zdalnym montowaniem (jak NFS). Z mojego doświadczenia wynika, że ponowne uruchomienie jest jedyną drogą, aby się tam dostać, ale możesz sprawdzić inne odpowiedzi, które dotyczą tej sprawy bardziej szczegółowo.źródło
Proces inicjacji jest odporny na SIGKILL.
Dotyczy to również wątków jądra, tj. „Procesów” o PPID równym 0.
źródło
Jak wspomnieli inni, proces w nieprzerwanym śnie nie może zostać zabity natychmiast (lub w niektórych przypadkach w ogóle). Warto zauważyć, że inny stan procesu, TASK_KILLABLE, został dodany w celu rozwiązania tego problemu w niektórych scenariuszach, szczególnie w częstym przypadku, gdy proces oczekuje na NFS. Zobacz http://lwn.net/Articles/288056/
Niestety nie wierzę, że jest to używane gdziekolwiek w jądrze oprócz NFS.
źródło
ls
procesu uzyskującego dostęp dosshfs
montowania, gdy zdalny serwer był nieosiągalny. Czy istnieje rozwiązanie dla FUSE lub sshfs, którego mógłbym użyć w przyszłości, aby uniknąć takich sytuacji? Jądro 2.6.30Stworzyłem mały skrypt, który bardzo mi pomógł!
Możesz go użyć do zabicia dowolnego procesu o podanej nazwie na ścieżce (zwróć na to uwagę !!) Lub możesz zabić dowolny proces danego użytkownika za pomocą parametru „-u nazwa użytkownika”.
źródło
Są przypadki, w których nawet jeśli wyślesz zabicie -9 do procesu, ten pid zatrzyma się, ale proces uruchomi się ponownie automatycznie (na przykład, jeśli spróbujesz
gnome-panel
, uruchomi się ponownie): czy może tak być w tym przypadku?źródło
od tutaj pierwotnie :
sprawdź, czy strace coś pokazuje
spróbuj dołączyć do procesu za pomocą gdb
jeśli proces wchodził w interakcję z urządzeniem, które można odmontować, usuń moduł jądra lub fizycznie odłącz / odłącz ... wtedy spróbuj tego.
źródło
Miałem taki problem. Był to program, który uruchomiłem
strace
i przerwałemCtrl
+C
. Skończyło się naT
(śledzonym lub zatrzymanym) stanie. Nie wiem, jak to się dokładnie stało, ale z tym nie można było się zmobilizowaćSIGKILL
.Krótko mówiąc, udało mi się go zabić
gdb
:źródło
W oparciu o wskazówkę z odpowiedzi Gillesa miałem proces oznaczony „Z” u góry (
<defunct>
w ps), który zużywał zasoby systemowe, miał nawet otwarty port, który SŁUCHAŁO i można było się z nim połączyć. To było po wykonaniukill -9
na nim. Jego rodzicem było „1” (tj.init
), Więc teoretycznie powinno się je po prostu powtórzyć i zniknąć. Ale tak nie było, trzymał się, choć nie biegł i „nie umierał”Więc w moim przypadku był to zombie, ale wciąż zużywał zasoby ... FWIW.
I nie było usuwalne przez dowolną liczbę
kill -9
„sI jego rodzic był,
init
ale nie był zbierany (czyszczony). Czyliinit
miała dziecko zombie.Ponowne uruchomienie nie było konieczne, aby rozwiązać problem. Chociaż ponowne uruchomienie „zadziałałoby” w przypadku problemu / przyspieszyło jego zamknięcie. Po prostu nie był pełen wdzięku, co wciąż było możliwe.
Był to port LISTEN należący do procesu zombie (a także kilka innych portów, takich jak status CLOSE_WAIT połączonych localhost z localhost). I nawet zaakceptował połączenia. Nawet jako zombie. Wydaje mi się, że nie udało się jeszcze wyczyścić portów, więc połączenia przychodzące były nadal dodawane do zaległości portów nasłuchujących TCP, choć nie miały szans na akceptację.
Wiele z powyższych jest określanych jako „niemożliwe” w różnych miejscach w interwebach.
Okazuje się, że miałem w sobie wewnętrzny wątek, który wykonywał „wywołanie systemowe” (w tym przypadku ioctl), którego powrót zajął kilka godzin (było to oczekiwane zachowanie). Wygląda na to, że system nie może zabić całego procesu, dopóki nie wróci z
ioctl
wywołania, ale przypuszcza, że wkracza na ziemię jądra. Po kilku godzinach wrócił, wszystko się wyjaśniło, a gniazda zostały automatycznie zamknięte itp., Zgodnie z oczekiwaniami. To trochę marnuje czas w celi śmierci! Jądro cierpliwie czekało na jego zabicie.Aby odpowiedzieć na OP, czasami trzeba poczekać. Długi czas. W końcu zabije.
Sprawdź także dmesg, aby sprawdzić, czy wystąpiła panika jądra (tj. Błąd jądra).
źródło