Страницы

Поиск по вопросам

воскресенье, 21 октября 2018 г.

Что означает “There is 1 zombie process” и что с ним делать?

Залогинился на удаленную машину. Вижу следующую строку в приветственном сообщении.
There is 1 zombie process.
Насколько я понял, это означает, что какой-то процесс завершил работу, но не закрылся и не освободил ресурсы. Хотелось бы лучше понять проблему:
Как можно его обнаружить? Сейчас я угадал, но нужен стабильный метод. Как можно узнать причины его появления? Есть какие-нибудь логи? Может, по имеющемуся процессу можно что-либо понять?
Если это важно, ubuntu 14.04, sudo есть.
Дополнение: меня не устраивает метод «просто подождать», т.к. есть сервис, который должен работать всегда — и подвис он или кто-то из его детей. Он подстрахован monit'ом, но тот не распознал зомбификацию и не перезагрузил.


Ответ

Зомби в операционных системах UNIX называют завершившиеся процессы, код завершения которых не забрал родительский процесс. Зомби не потребляют никаких ресурсов, память и файловые дескрипторы таких процессов уже освобождены. Остается только запись в таблице процессов, которая занимает несколько десятков байт памяти. Так что единичный зомби процесс на систему никак не влияет. НО он явный индикатор того, что у какого то процесса в системе что то пошло не так.
Поиск зомби:
ps -axho state,pid,ppid | grep Z | sed 's/./ps/' | sh
Данная команда покажет все зомби процессы и их родителей (тестировалась под linux, под другими *nix возможны другие ключи у команды ps).
Убить зомби можно только перезапуском родительского процесса. kill -9 самого процесса-зомби и чеснок обычно не помогают. Если появление зомби разовое явление, то возможно проще на факт его появления забить.
Что бы понять почему именно появился зомби надо смотреть исходники породившего его процесса и возможно самого зомби. Часто это одна и та же программа. Любой процесс, выполняющий fork, т.е. запускающий дочерние процессы должен уметь забирать код их завершения, делается это вызовом wait и/или waitpid. Для начала надо просмотреть исходники на наличие функций группы wait, а так же наличие функции-обработчика сигнала SIGCHLD (обработчик устанавливается вызовом signal и функций для работы с сигналами потоков). Если родитель не использует функции группы wait, то возможно при его нормальной работе завершение дочерних процессов разработчик вообще не ожидал. Если это так - то причина образования зомби - незапланированное завершение процесса потомка в следствие какой либо ошибки. Дать рекомендаций как это искать и лечить невозможно. Можно только посоветовать добавить в родительский поток обработку CHLD, забор кода завершения с помощью wait и логирование факта завершения потомка. И дальше запуск потомка под отладчик и т.п. ...
Вариант 2: родительский процесс использует wait, но зомби все равно появляются. Копать в сторону того, какая разновидность wait используется, если waitpid, которая проверяет завершение конкретных потомков, то смотреть откуда она берет проверяемые pid, возможно в процессе работы какие то pid потомков теряются и программа про них забывает. Может программа в какой то момент запрещает обработку сигналов и забывает восстановить обработку, после прохождения критического участка. Опять же - вариантов очень много, но сосредоточены они вокруг обработчика SIGCHLD и функций wait
Вариант 3: родительский процесс умеет обрабатывать и готов правильно обработать завершение своих потомков. Но зацикливается в другом месте программы или засыпает на системном вызове, например чтения с сетевого диска, который стал недоступен и при этом прерывание по SIGCHLD запрещено. В этом случае надо разбираться с причинами его зависания. Кстати, отсутствие доступа к каким либо ресурсам, типа сетевых дисков (или при выходе из строя физического диска) - довольно частая причина массового появления зомби.
Каких либо специальных логов в системе, где можно было бы увидеть хоть какую то информацию по появляющимся зомби не существует. Следы можно найти только в логах той программы, которая их порождает, при их наличии.

Комментариев нет:

Отправить комментарий