Как это возможно, что kill -9 для процесса в Linux не имеет никакого эффекта?
Я пишу плагин для автоматического выделения текстовых строк при посещении веб-сайта. Это похоже на результаты поиска highlight, но автоматически и для многих слов; он может быть использован для людей с аллергией, чтобы слова действительно выделялись, например, когда они просматривают сайт продуктов питания.
но у меня есть проблема. Когда я пытаюсь закрыть пустое, свежее окно FF, оно каким-то образом блокирует весь процесс. Когда я убиваю процесс, все окна исчезают, но процесс Firefox остается живым (Родительский PID равен 1, не слушает никаких сигналов, имеет много открытых ресурсов, все еще ест процессор, но не сдвинется с места).
два вопроса:
как вообще возможно, чтобы процесс не слушал kill -9 (ни как пользователь, ни как root)?
есть ли что-нибудь, что я могу сделать, кроме перезагрузки?
[EDIT] это оскорбительный процесс:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
digulla 16688 4.3 4.2 784476 345464 pts/14 D Mar28 75:02 /opt/firefox-3.0/firefox-bin
то же самое с ps -ef | grep firefox
UID PID PPID C STIME TTY TIME CMD
digulla 16688 1 4 Mar28 pts/14 01:15:02 /opt/firefox-3.0/firefox-bin
это единственный процесс. Как вы можете видеть, это не зомби, он работает! Он не слушает kill -9, независимо от того, убиваю ли я PID или имя! Если я попытаюсь связаться с strace, потом strace также зависает и не может быть убит. Выхода тоже нет. Я предполагаю, что FF зависает в какой-то рутине ядра, но какой?
[EDIT2] на основе обратной связи от sigjuice:
ps axopid,comm,wchan
может показать вам, в какой рутине ядра процесс зависает. В моем дело в том, что оскорбительным плагином был индексатор Beagle (openSUSE 11.1). После отключения плагина FF снова был быстрым и счастливым лисом.
7 ответов:
как отмечено в комментариях к ОП, состояние процесса (
STAT) ofDуказывает, что процесс находится в состоянии "бесперебойного сна". В реальных условиях это обычно означает, что он ждет ввода - вывода и не может/не будет ничего делать, включая смерть, пока эта операция ввода - вывода не завершится.процессы
Dсостояние обычно будет там только за долю секунды до завершения операции, и они возвращаются кR/S. По моему опыту, если процесс застревает вD, чаще всего он пытается связаться с недостижимой NFS или другой удаленной файловой системой, пытается получить доступ к неисправному жесткому диску или использовать какое-либо аппаратное обеспечение с помощью драйвера устройства flaky. В таких случаях единственный способ восстановить и позволить процессу умереть - либо получить резервную копию fs/drive/hardware, чтобы I/O мог завершить или отказаться и перезагрузить систему. В конкретном случае NFS, крепление также может в конечном итоге тайм-аут и возврат из операции ввода-вывода (с кодом сбоя), но это зависит от параметров монтирования, и очень часто для монтирования NFS устанавливается вечное ожидание.это отличается от процесса зомби, который будет иметь статус
Z.
дважды проверьте, что parent-id действительно 1. Если нет, то и это
firefoxсначала попробоватьsudo killall -9 firefox-bin. После этого попробуйте убить конкретные идентификаторы процессов индивидуально с помощьюsudo killall -9 [process-id].как вообще возможно, чтобы процесс не слушал kill -9 (neiter как пользователь или как root)?
если процесс зашел
<defunct>а потом становится зомби с родителем 1, Вы не можете убить его вручную; толькоinitможет. Зомби процессы уже мертвы и ушли - они потеряли возможность быть убитыми, поскольку они больше не являются процессами, а только запись таблицы процессов и связанный с ней код выхода, ожидающий сбора. Вам нужно убить родителя, и вы не можете убитьinitпо понятным причинам.но вижу здесь для получения более общей информации. Перезагрузка убьет все, естественно.
возможно ли, что этот процесс перезапускается (например, init) только в то время, когда вы его убиваете?
вы можете проверить это легко. Если PID-это то же самое после
kill -9 PIDтогда процесс не был убит, но если он изменился, процесс был перезапущен.
Я в последнее время попадаю в ловушку Двойная Вилка и приземлился на эту страницу, прежде чем, наконец, найти мой ответ. Симптомы идентичны, даже если проблема не в этом:
- WYKINWYT: то, что вы убиваете, это не то, что вы думали
минимальный тестовый код показан ниже на основе примера для демона SNMP
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> int main(int argc, char* argv[]) { //We omit the -f option (do not Fork) to reproduce the problem char * options[]={"/usr/local/sbin/snmpd",/*"-f","*/-d","--master=agentx", "-Dagentx","--agentXSocket=tcp:localhost:1706", "udp:10161", (char*) NULL}; pid_t pid = fork(); if ( 0 > pid ) return -1; switch(pid) { case 0: { //Child launches SNMP daemon execv(options[0],options); exit(-2); break; } default: { sleep(10); //Simulate "long" activity kill(pid,SIGTERM);//kill what should be child, //i.e the SNMP daemon I assume printf("Signal sent to %d\n",pid); sleep(10); //Simulate "long" operation before closing waitpid(pid); printf("SNMP should be now down\n"); getchar();//Blocking (for observation only) break; } } printf("Bye!\n"); }на первом этапе основной процесс (7699) запускает демон SNMP (7700), но мы можем смотрите, что это сейчас Како/Зомби. Рядом мы видим другой процесс (7702) с указанными нами опциями
[nils@localhost ~]$ ps -ef | tail root 7439 2 0 23:00 ? 00:00:00 [kworker/1:0] root 7494 2 0 23:03 ? 00:00:00 [kworker/0:1] root 7544 2 0 23:08 ? 00:00:00 [kworker/0:2] root 7605 2 0 23:10 ? 00:00:00 [kworker/1:2] root 7698 729 0 23:11 ? 00:00:00 sleep 60 nils 7699 2832 0 23:11 pts/0 00:00:00 ./main nils 7700 7699 0 23:11 pts/0 00:00:00 [snmpd] <defunct> nils 7702 1 0 23:11 ? 00:00:00 /usr/local/sbin/snmpd -Lo -d --master=agentx -Dagentx --agentXSocket=tcp:localhost:1706 udp:10161 nils 7727 3706 0 23:11 pts/1 00:00:00 ps -ef nils 7728 3706 0 23:11 pts/1 00:00:00 tailпосле моделирования 10 сек мы попытаемся убить единственный процесс, который мы знаем (7700). То, что нам наконец удалось с waitpid (). Но процесс 7702 все еще здесь
[nils@localhost ~]$ ps -ef | tail root 7431 2 0 23:00 ? 00:00:00 [kworker/u256:1] root 7439 2 0 23:00 ? 00:00:00 [kworker/1:0] root 7494 2 0 23:03 ? 00:00:00 [kworker/0:1] root 7544 2 0 23:08 ? 00:00:00 [kworker/0:2] root 7605 2 0 23:10 ? 00:00:00 [kworker/1:2] root 7698 729 0 23:11 ? 00:00:00 sleep 60 nils 7699 2832 0 23:11 pts/0 00:00:00 ./main nils 7702 1 0 23:11 ? 00:00:00 /usr/local/sbin/snmpd -Lo -d --master=agentx -Dagentx --agentXSocket=tcp:localhost:1706 udp:10161 nils 7751 3706 0 23:12 pts/1 00:00:00 ps -ef nils 7752 3706 0 23:12 pts/1 00:00:00 tailпосле предоставления символа функции getchar() наш основной процесс завершается, но демон SNMP с pid 7002 все еще здесь
[nils@localhost ~]$ ps -ef | tail postfix 7399 1511 0 22:58 ? 00:00:00 pickup -l -t unix -u root 7431 2 0 23:00 ? 00:00:00 [kworker/u256:1] root 7439 2 0 23:00 ? 00:00:00 [kworker/1:0] root 7494 2 0 23:03 ? 00:00:00 [kworker/0:1] root 7544 2 0 23:08 ? 00:00:00 [kworker/0:2] root 7605 2 0 23:10 ? 00:00:00 [kworker/1:2] root 7698 729 0 23:11 ? 00:00:00 sleep 60 nils 7702 1 0 23:11 ? 00:00:00 /usr/local/sbin/snmpd -Lo -d --master=agentx -Dagentx --agentXSocket=tcp:localhost:1706 udp:10161 nils 7765 3706 0 23:12 pts/1 00:00:00 ps -ef nils 7766 3706 0 23:12 pts/1 00:00:00 tailвывод
тот факт, что мы проигнорировали двойная вилка механизм заставил нас думать, что убить действие не удалось. Но на самом деле мы просто убили неправильный процесс !!
добавить - f опция (не (двойная) вилка ) все идет так, как ожидалось
вы также можете сделать pstree и убить родителей. Это гарантирует, что вы получите все оскорбительное дерево процесса, а не только лист.
Comments