LINUX.ORG.RU

Способы убить зомби-процессы

 , ,


5

1

Какие ещё есть способы закапывания зомби-процессов, кроме убийства их родителей? Выдача гугла говорит, что убийство родителя — это самый простой способ, но какие есть способы более сложные? Киньте ссылку на годный материал о зомби-процессах, где разжёвываются все тонкости и нюансы работы с ними.

Нету тонкостей работы с зомби. Убить их нельзя, они уже мертвы.

Зомби-процесс это просто запись в таблице процессов. Таким образом ядро сохраняет pid и exit status «умершего» процесса, а нужно это для того, чтобы родитель мог получить exit status (код завершения) своего потомка. Пока родитель не спросит ядро код завершения потомка, в списке процессов будет зомби. Если родитель написан не правильно, то зомби и существуют пока существует родитель.

mky ★★★★★
()
Ответ на: комментарий от mky

Ок, тогда можно ли как-нибудь защититься от переполнения таблицы процессов записями зомби? Без правки исходников родителя, разумеется.

wintrolls ☆☆
() автор топика
Ответ на: комментарий от wintrolls

Насколько я знаю, переполнение будет неизбежно. Можно поднять допустимое кол-во процессов, но это только увеличит время.

Если исходники родителя поправить нельзя, можно или поправить исходники ядра, или через LD_PRELOAD загрузить что-нибудь в родителя, допустим обёртку над exec(), которая бы делала не только exec(), но и wait().

mky ★★★★★
()
Ответ на: комментарий от anonymous

D state == «Uninterruptible sleep». Ничего с ним сделать нельзя, когда процесс выйдет из этого состояния, он сразу получит все отправленные ему сигналы и, скорее всего, умрёт. Сделано это для корректной работы драйверов в ядре. Через системный вызов процесс выполнятся в режиме ядра, и может блочит ресурсы внутрия ядра (lock/unlock). Если он в этот момент завершится (exit()), то с ядреными блокировками может быть не всё в порядке, поэтому его и делают «неуявзвимым».

Вроде как сейчас в ядре вместоTASK_UNINTERRUPTIBLE может быть состояние процесса TASK_KILLABLE и если драйвер написан правильно, то он должен позволять убить (SIGKILL) процесс.

Если процесс ушёл в «D» при работе по NFS, то это так и задумано, иначе это бага драйвера или бага железа, не известная драйверу. По идее можно сделать

echo w > /proc/sysrq-trigger

и получить список процессов и системных вызовов, на которых они «заснули», чтобы бы понять куда слать баг-репорт.

mky ★★★★★
()
Ответ на: комментарий от mky

Респект тебе, спасибо, объяснил. Не NFS, - тв-тюнер.

anonymous
()
Ответ на: комментарий от mky

Вроде как сейчас в ядре вместоTASK_UNINTERRUPTIBLE может быть состояние процесса TASK_KILLABLE и если драйвер написан правильно, то он должен позволять убить (SIGKILL) процесс.

Мне всегда казалось, что D-state - просто костыль для говномодулеписателей, не могущих обработать блокировки в случае убиения процесса.

anonymous
()
Ответ на: комментарий от anonymous

Мне всегда казалось, что D-state - просто костыль для говномодулеписателей, не могущих обработать блокировки в случае убиения процесса.

+1

Тот же пример с тюнером: если почти одновременно запустить 2 tvtime, то второй завершится, а первый ничего не покажет, и будет вечно в D-state.
Ещё выдергивание вебкамеры у меня запросто оставляло mplayer в D-state
Отвал NFS, и винтов тоже часто приводит к тому же.

lyset ★★★
()
Ответ на: комментарий от lyset

Анонимус пишет про убиение процесса, а вы приводите примеры ошибок в драйверах, когда без всяких sigkill всё плохо: «выдергивание вебкамеры у меня запросто оставляло mplayer в D-state». В случае кривого драйвера, зависание mplayer'а не в D-state ничем жизнь бы не улучшило. Ну получил бы mplayer сигнал, ну «умер» бы, драйвер то всё одно уже в неадекватном состоянии, явно бы от него остались в ядре не освобождённые ресурсы.

В случае с NFS так и задумано, D-state — это остановка процесса пока снова не появится связь с серером (с файловой системой). В остальных случаях, ИМХО, драйвер должен хотя бы по таймауту определять проблему с железом и завершать syscall с ошибкой. Если драйвер от проблем с железом впадает в кому, скорее всего в нём ошибка, или он просто не дописан (нет времени у автора или тестера).

Если я правильно понял, то TASK_KILLABLE полностью не отменяет TASK_UNINTERRUPTIBLE, в определённые моменты драйверу всё одно не нужны прерывания в виде sigkill, но при правльном подходе TASK_KILLABLE позволяет избежать длительного нахождения в TASK_UNINTERRUPTIBLE.

mky ★★★★★
()

Выстрели себе в ногу.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.