Що робити, якщо "убити -9" не працює?


467

У мене є процес, з яким я не можу вбити kill -9 <pid>. У чому проблема в такому випадку, тим більше, що я є власником цього процесу. Я думав, що нічого не може ухилитися від цього killваріанту.

Відповіді:


561

kill -9( SIGKILL ) завжди працює, якщо у вас є дозвіл на вбивство процесу. По суті, або процес повинен бути запущений вами, і не бути налаштованим або налаштованим, або ви повинні мати root. Є один виняток: навіть root не може надіслати фатальний сигнал PID 1 ( initпроцес).

Однак kill -9не гарантовано працювати негайно . Усі сигнали, включаючи SIGKILL, подаються асинхронно: ядро ​​може зайняти час для їх доставки. Зазвичай подача сигналу займає максимум кілька мікросекунд, саме час, який потрібен цілі, щоб отримати відрізок часу. Однак якщо ціль заблокувала сигнал , сигнал буде в черзі, поки ціль не розблокує його.

Зазвичай процеси не можуть блокувати SIGKILL. Але код ядра може і процеси виконувати код ядра під час виклику системних викликів . Код ядра блокує всі сигнали, коли переривання системного виклику призведе до погано сформованої структури даних десь у ядрі, або, загалом, до порушення інваріанта ядра. Отже, якщо (через помилку чи неправильне проектування) системний виклик блокується на невизначений термін, фактично неможливо вбити спосіб. (Але процес буде вбито, якщо він коли-небудь завершить системний виклик.)

Процес, заблокований у системному дзвінку, знаходиться у режимі безперебійного сну . Команда psor top(на більшості уніцій) показує її у стані D( я думаю, що спочатку для " d isk").

Класичним випадком тривалого безперебійного сну є процеси доступу до файлів через NFS, коли сервер не відповідає; сучасні реалізації, як правило, не накладають режиму безперебійного сну (наприклад, в Linux, intrопція кріплення дозволяє сигналу перервати доступ до файлів NFS).

Іноді ви можете бачити записи, позначені Z(або Hпід Linux, я не знаю, що це відмінність) у вихідному psчи topвихідному. Це технічно не процеси, це процеси зомбі, які є не що інше, як запис у таблиці процесів, що зберігається навколо, щоб батьківський процес міг повідомити про смерть своєї дитини. Вони відійдуть, коли батьківський процес зверне увагу (або помре).


92
Ваша відповідь виглядає суперечливо. Ви починаєте говорити, що SIGKILL завжди працює, але закінчується посиланням на випадок безперебійного сну, де SIGKILL ніколи не може працювати поза вимкненням ядра. Також є два випадки, коли SIGKILL не працює. З зомбі, очевидно, як ви не можете вбити вже мертві процеси та з init, який задумом ігнорує сигнали SIGKILL.
jlliagre

41
@jlliagre: Вбивство зомбі не має сенсу, для початку це не живе. І вбивство процесу в режимі переривання сну справді спрацьовує, це просто (як і в інших сигналах) асинхронно. Я намагався уточнити це у своїй редакції.
Жиль

3
Я теж писав, що вбивати зомбі не має сенсу, але це не заважає багатьом людям спробувати це і скаржитися. Вбивство процесу в режимі непереривного сну справді працює задумом, але я говорив про вбивство в режимі безперебійного сну, який може вийти з ладу, якщо системний виклик ніколи не прокинеться.
jlliagre

11
man 5 nfs: "Параметр intr/ nointrmount припинено після ядра 2.6.25. Тільки SIGKILL може перервати очікувані операції NFS на цих ядрах, і якщо зазначено, цей параметр монтажу ігнорується, щоб забезпечити зворотну сумісність зі старими ядрами."
Мартін Шредер

4
@ imz - ІванЗахарящев Не те, про що я знаю (але, можливо, не знаю). З sshfs в крайньому випадку ви можете вбити sshfsпроцес (і так само, як і з будь-якою іншою файловою системою FUSE: ви завжди можете примусово відключити цей спосіб).
Жиль

100

Колись процес існує і його не можна вбити через:

  • будучи зомбі. Тобто процес, який з батьків не прочитав статус виходу. Такий процес не споживає жодних ресурсів, крім запису PID. У topньому сигналізується Z
  • помилковий безперебійний сон. Це не повинно відбуватися, але поєднання коду баггі ядра та / або програмного забезпечення баггі, яке це відбувається. Єдиний метод - перезавантажити або почекати. У topній сигналізується Д.

2
Zombie не споживає ресурс?
Люк М

7
@Luc M: AFAIK немає (принаймні для Linux) - за винятком запису в таблицю процесів (тобто PID разом з такою інформацією, як власник, статус виходу тощо). Це просто процес, який чекає підтвердження від партенту, що він припинився.
Maciej Piechotka

18
@xenoterracide: Врешті-решт так, але якщо батьківський процес все ще живе (наприклад, це gnome-сесія або щось, що виконує подібну роль), у вас все ще можуть бути зомбі. З технічної точки зору це прибирання батьків, але якщо зомбі осиротіло, то після нього очищається (термінологія - це причина, коли класи Unix проводяться із закритими дверима - кожен, хто чує про сиріт, зомбі та вбивство в одному реченні, може мати неправильні враження).
Maciej Piechotka

5
"... єдиний метод - перезавантажити або почекати." Зачекайте, як довго? Минуло п’ять місяців, і мої зомбі все ще є.
DarenW

3
@DarenW, поки батько не визнає смерть дітей. Для детальної інформації зверніться до автора програми.
Мацей П'єхотка

32

Це здається, що у вас може бути процес зомбі . Це нешкідливо: єдиний ресурс, який споживає процес зомбі, - це запис у таблиці процесів. Він піде, коли батьківський процес вмирає або реагує на смерть своєї дитини.

Ви можете побачити, чи є процес зомбі, скориставшись topцією командою:

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

13
Гм, мені завжди не подобаються такі «важкі» назви полів ps. Хто може бути впевнений, що обов'язкове поле завжди буде 8-м, з усіма реалізаціями psв усіх Unices?
синтаксисхор

26

Перевірте свої /var/log/kern.logта /var/log/dmesg(або їх еквіваленти) наявність будь-яких підказок. На мій досвід, це сталося зі мною лише тоді, коли раптово перепало мережеве з'єднання кріплення NFS або вийшов з ладу драйвер пристрою. Це може статися, якщо жорсткий диск також вийде з ладу, я вважаю.

Ви можете використовувати, lsofщоб побачити, які файли пристроїв відкрив процес.


6
+1 для згадки про NFS. Кілька років тому це траплялося зі мною кожні пару місяців-- якби сервер NFS вийшов з ладу, клієнти NFS на всіх (виправлених) коробках RHEL будуть висіти. kill -9зазвичай не працювали, навіть очікуючи 60 хвилин. Єдиним рішенням було перезавантаження.
Стефан Ласєвський

17

Якщо відповіді @ Maciej та @ Gilles не вирішують вашу проблему, і ви не розпізнаєте процес (а на запитання, що це з вашим дистрибутивом, не знайдете відповідей). Перевірте наявність у Rootkit та інших ознак, якими ви володіли . Руткіт більш ніж здатний запобігти вам убити процес. Насправді багато хто здатний заважати вам їх бачити. Але якщо вони забудуть змінити 1 невелику програму, вони можуть бути помічені (наприклад, вони змінили top, але ні htop). Швидше за все, це не так, але краще безпечно, ніж шкода.


Я думаю, що багато руткітів вставляють себе в ядро, щоб зробити їх простішими (не потрібно здогадуватися, що у користувача та завантажуючи МБ виправлених програм). Однак це все одно варто перевірити (++ голос).
Maciej Piechotka

11

Вбити насправді означає надіслати сигнал. Є кілька сигналів, які ви можете надіслати. kill -9 - це спеціальний сигнал.

При надсиланні сигналу програма займається цим. якщо не ядро ​​займається цим. тож ви можете захопити сигнал у вашій програмі.

Але я сказав, що вбити -9 було особливим. Він особливий тим, що програма не отримує його. воно прямує до ядра, яке тоді справді вбиває додаток при першій можливій нагоді. іншими словами вбиває його мертвим

kill -15 посилає сигнал SIGTERM, який означає SIGNAL TERMINATE, інакше кажучи, повідомляє програмі вийти. Це дружній спосіб сказати програмі, що час відключення. але якщо додаток не відповідає kill -9 вб'є його.

якщо kill -9 не працює, це, ймовірно, означає, що ваше ядро ​​не працює. перезавантаження в порядку. Я не можу згадати, що коли-небудь траплялося.


5
15 - SIGTERM (дружнє вбивство), а не SIGHUP. SIGHUP - це закритий керуючий термінал або втрачається канал зв'язку
JoelFan

11

По-перше, перевірте, чи це процес Zombie (що дуже можливо):

ps -Al

Ви побачите щось на кшталт:

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

(Зверніть увагу на "Z" зліва)

Якщо 5-й стовпець не 1, значить, він має батьківський процес. Спробуйте вбити ідентифікатор батьківського процесу .

Якщо його PPID = 1, НЕ Вбивайте його !! , подумайте, які інші пристрої чи процеси можуть бути пов’язані з цим.

Наприклад, якщо ви використовували змонтований пристрій або самбу, спробуйте його відключити. Це може випустити процес зомбі.

ПРИМІТКА . Якщо ps -Al(або top) відображається "D" замість "Z", це може бути пов'язано з віддаленим кріпленням (наприклад, NFS). На мій досвід, перезавантаження - це єдиний спосіб поїхати туди, але ви можете перевірити інші відповіді, які висвітлюють цю справу більш детально.


1
Надсилання SIGCHLD до батьківського процесу може призвести до того, що батько визнає, що процес загинув. Це повинно працювати навіть тоді, коли PPID = 1. Це ядро, як правило, надсилається ядром, але може бути надіслане батькам також через kill (kill -17 в Linux, перевірте manpages на іншому * nix). Це використання вбивства насправді не «вбиває» батьків, а, скоріше, (повторно) повідомляє про те, що дитина померла і її потрібно прибрати. Зауважте, що sigchld має бути надіслано батькові зомбі, а не самому зомбі.
Стефанія

10

Процес init не застрахований від SIGKILL.

Це справедливо також для ниток ядра, тобто "процесів" з PPID, рівним 0.


1
Завдання з ядра також можуть бути захищені від SIGKILL. Це трапляється досить часто з Btrfs.
Тобу

9

Як уже згадували інші, процес безперебійного сну неможливо вбити негайно (або, в деяких випадках, зовсім). Варто зазначити, що для вирішення цієї проблеми в певних сценаріях було додано інший стан процесу, TASK_KILLABLE, особливо загальний випадок, коли процес очікується на NFS. Дивіться http://lwn.net/Articles/288056/

На жаль, я не вірю, що це використовується в будь-якому місці ядра, крім NFS.


У мене виникли проблеми із вбивством lsпроцесу доступу до sshfsверсії, коли віддалений сервер виявився недоступним. Чи є рішення для FUSE або sshfs, яке я можу використовувати в майбутньому, щоб уникнути подібних ситуацій? 2.6.30 ядро
imz - Іван Захарящев

@imz Порада від Gilles (вбивати sshfs) є - unix.stackexchange.com/a/5648/4319 .
imz - Іван Захарящев

6

Зробив невеликий сценарій, який мені дуже допоміг подивитися!

Ви можете використовувати його для вбивства будь-якого процесу із заданим іменем на його шляху (зверніть увагу на це !!) Або ви можете вбити будь-який процес певного користувача за допомогою параметра "-u ім'я користувача".

#!/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
Замість того, щоб просто посилатися на нього, чи можете ви надіслати тут код.
thepang

3
Додайте трохи опису з (або принаймні замість) коду ...
vonbrand

Так, але "$ name" є більш агрегуючим ... це вб'є будь-який процес із "$ name" на його запущеному шляху. Може бути дуже корисним, якщо у вас є ці величезні командні рядки, і ви не знаєте, що таке процес.
user36035

5

Бувають випадки, коли навіть якщо ви надіслаєте процес kill -9, цей pid зупиняється, але процес перезапускається автоматично (наприклад, якщо ви спробуєте його gnome-panel, він перезапуститься): чи може це бути тут?


8
Коли щось подібне відбувається, PID фактично змінюється. Так я б помітив.
tshepang

2

з тут спочатку :

перевірте, чи щось показує страйк

strace -p <PID>

спробуйте приєднатися до процесу за допомогою gdb

gdb <path to binary> <PID>

якщо процес взаємодіяв із пристроєм, який ви можете відключити, видаліть модуль ядра або фізично відключіть / відключіть вилку від мережі ... тоді спробуйте це.


Працювали для мене! (відключення пристрою USB, на якому висів піднесений текст)
nmz787

1

У мене було таке питання. Це була програма, яку я запустив straceі перервав Ctrl+ C. Він опинився у T(простеженому чи зупиненому) стані. Я не знаю, як саме це сталося, але це було не під силу SIGKILL.

Якщо коротко розповісти, мені вдалося вбити це за допомогою gdb:

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

-1

Виходячи із підказки з відповіді gilles, у мене був процес, позначений "Z" вгорі ( <defunct>в ps), який використовував системні ресурси, у нього навіть був відкритий порт, який був LISTEN'ing, і ви можете підключитися до цього порту. Це було після виконання kill -9на ньому. Його батько був "1" (тобто init), тому теоретично його слід просто повторити і зникнути. Але це не було, воно стирчало, хоч і не бігало, і "не вмирало"

Тож у моєму випадку це було зомбі, але все-таки споживало ресурси ... FWIW.

І це не було вбивством жодної кількості kill -9російських

І його батько був, initале його не збирали (прибирали). Тобто initнародила зомбі.

І перезавантажувати проблему не потрібно було. Хоча перезавантаження "спрацювало б" навколо проблеми / пришвидшило її вимкнення. Просто не витончена, що все-таки було можливо.

І це був LISTEN-порт, який належить до зомбі-процесу (і кілька інших портів, схожий на статус CLOSE_WAIT, підключили localhost до localhost). І це навіть прийняло зв’язки. Навіть як зомбі. Я думаю, що не збирався очищати порти, але вхідні з'єднання все ще були додані до відставання порту прослуховування TCP, хоча вони не мали шансу прийняти.

Багато з перерахованого вище в різних місцях міжвузлів заявляються як "неможливі".

Виявляється, у мене в ній була внутрішня нитка, яка виконувала "системний виклик" (в даному випадку ioctl), щоб повернути на це потрібно кілька годин (така очікувана поведінка). Мабуть, система не може вбити процес «до кінця», поки він не повернеться з ioctlвиклику, здогадуйтесь, що він переходить у землю ядра. Через декілька годин він повернувся, все прояснилося, і розетки автоматично закривалися тощо, як очікувалося. Ось який час нудить у смертному карі! Ядро терпляче чекало, щоб його вбити.

Отже, щоб відповісти на ОП, іноді доводиться чекати. Довгий час. Тоді вбивство нарешті відбудеться.

Також перевірте dmesg, щоб побачити, чи не було паніки з ядром (тобто помилка ядра).


Це, здається, ви описуєте свій власний конкретний сценарій, а не відповідь на питання. У вашому випадку процес закріпився самостійно через тривалу роботу, що не згадується в питанні. Однак ви можете поставити нове запитання і надати відповідь на нього. Хоча я боюся, що питання може закритися як "не відтворюване", оскільки результат специфічний для вашої реалізації.
Centimane

Щоправда, я додав, як він відповідає на ОП, оскільки це ... може, в деяких випадках.
rogerdpack
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.