Как это возможно, что kill -9 для процесса в Linux не имеет никакого эффекта?



Я пишу плагин для автоматического выделения текстовых строк при посещении веб-сайта. Это похоже на результаты поиска highlight, но автоматически и для многих слов; он может быть использован для людей с аллергией, чтобы слова действительно выделялись, например, когда они просматривают сайт продуктов питания.



но у меня есть проблема. Когда я пытаюсь закрыть пустое, свежее окно FF, оно каким-то образом блокирует весь процесс. Когда я убиваю процесс, все окна исчезают, но процесс Firefox остается живым (Родительский PID равен 1, не слушает никаких сигналов, имеет много открытых ресурсов, все еще ест процессор, но не сдвинется с места).



два вопроса:




  1. как вообще возможно, чтобы процесс не слушал kill -9 (ни как пользователь, ни как root)?


  2. есть ли что-нибудь, что я могу сделать, кроме перезагрузки?



[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 снова был быстрым и счастливым лисом.

567   7  

7 ответов:

как отмечено в комментариях к ОП, состояние процесса (STAT) of D указывает, что процесс находится в состоянии "бесперебойного сна". В реальных условиях это обычно означает, что он ждет ввода - вывода и не может/не будет ничего делать, включая смерть, пока эта операция ввода - вывода не завершится.

процессы 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 опция (не (двойная) вилка ) все идет так, как ожидалось

PS-ef | grep firefox; и вы можете увидеть 3 процесса, убить их всех.

sudo killall -9 firefox

должно работать

изменить: [PID] изменен на firefox

вы также можете сделать pstree и убить родителей. Это гарантирует, что вы получите все оскорбительное дерево процесса, а не только лист.

Comments

    Ничего не найдено.