Есть ли способ определить, какой процесс превращается в процесс зомби

Один из серверов ubuntu имеет 82 зомби-процесса. Все процессы показывают «[sh] несуществующий» как команда процесса. Есть ли способ узнать, какой процесс становится зомбическим процессом?

Я попытался проверить каталог /proc/PID/ чтобы получить представление о процессе зомби, но все файлы пустые. Как найти, кто разрешает этот процесс как зомби … Есть ли другой способ узнать это?

Обновлено / Решено: Сделал вопрос яснее, и ответил на мой собственный вопрос, как было предложено andcoz.

Конечно вы можете. Есть много способов сделать это, наиболее распространенным является, вероятно, следующее:

 ps aux 

Вы можете добавить базовый | grep -w Z | grep -w Z и у вас будет короткий список ваших зомби. Если вам нужен только список зомби-процесса и их pids, вы можете сделать это, как указано на этой странице :

 ps aux | awk '{ print $8 " " $2 }' | grep -w Z 

Проверьте этот вопрос для получения дополнительной информации о информации о процессе.

Короткий ответ: вам все равно. Процесс зомби мертв. Все, что он потребляет, – это маленький бит памяти ядра, для этой записи в таблице процессов.

Поскольку все, что осталось от процесса, это запись в таблице процессов, у вас мало времени для продолжения. Процесс зомби – это мертвый процесс, который его родитель еще не получил; посмотрите PPID процесса, чтобы узнать, кто является родителем.

Одной из причин процесса Zombie является «родительский процесс», не ожидающий «дочерний процесс» – выполненный ps -l который показывает идентификатор родительского процесса, с помощью которого вы можете точно определить, какой процесс отвечает за зомби в машине.

Подсистема аудита ядра Linux может быть очень полезна, чтобы выяснить, какие процессы становятся зомбическими процессами. У меня была следующая ситуация:

 server ~ # ps -ef --forest [...] root 16385 1 0 17:04 ? 00:00:00 /usr/sbin/apache2 -k start root 16388 16385 0 17:04 ? 00:00:00 \_ /usr/bin/perl -T -CSDAL /usr/lib/iserv/apache_user root 16389 16385 0 17:04 ? 00:00:00 \_ /usr/bin/perl -T -CSDAL /usr/lib/iserv/apache_user www-data 16415 16385 0 17:04 ? 00:00:00 \_ /usr/sbin/apache2 -k start www-data 18254 16415 0 17:23 ? 00:00:00 | \_ [sh] <defunct> www-data 18347 16415 0 17:23 ? 00:00:00 | \_ [sh] <defunct> www-data 22966 16415 0 18:18 ? 00:00:00 | \_ [sh] <defunct> www-data 16583 16385 0 17:05 ? 00:00:01 \_ /usr/sbin/apache2 -k start www-data 18306 16583 0 17:23 ? 00:00:00 | \_ [sh] <defunct> www-data 18344 16583 0 17:23 ? 00:00:00 | \_ [sh] <defunct> www-data 17561 16385 0 17:12 ? 00:00:00 \_ /usr/sbin/apache2 -k start www-data 22983 17561 0 18:18 ? 00:00:00 | \_ [sh] <defunct> www-data 18318 16385 0 17:23 ? 00:00:00 \_ /usr/sbin/apache2 -k start www-data 19725 16385 0 17:43 ? 00:00:01 \_ /usr/sbin/apache2 -k start www-data 22638 16385 0 18:13 ? 00:00:00 \_ /usr/sbin/apache2 -k start www-data 22659 16385 0 18:14 ? 00:00:00 \_ /usr/sbin/apache2 -k start www-data 25102 16385 0 18:41 ? 00:00:00 \_ /usr/sbin/apache2 -k start www-data 25175 16385 0 18:42 ? 00:00:00 \_ /usr/sbin/apache2 -k start www-data 25272 16385 0 18:44 ? 00:00:00 \_ /usr/sbin/apache2 -k start 

Причиной для этих процессов зомби является, скорее всего, PHP-скрипт, но поскольку эти дочерние процессы Apache обрабатывают множество HTTP-запросов и множество разных PHP-скриптов, очень сложно понять, какой из них может быть ответственен. Linux также уже освободил важную информацию об этих процессах зомби, поэтому у нас даже нет /proc/<pid>/cmdline чтобы выяснить, какой сценарий или -c command /bin/sh может быть запущен:

 server ~ # cat /proc/18254/cmdline server ~ # 

Чтобы понять это, я установил auditd : https://linux-audit.com/configuring-and-auditing-linux-systems-with-audit-daemon/

Я создал следующие правила аудита:

 auditctl -a always,exit -F arch=b32 -S execve -F path=/bin/dash auditctl -a always,exit -F arch=b64 -S execve -F path=/bin/dash 

Эти правила проверяют все создания процесса двоичного /bin/dash . /bin/sh не работает здесь, потому что это символическая ссылка, и аудита, по-видимому, видит только имя целевого файла:

 server ~ # ls -l /bin/sh lrwxrwxrwx 1 root root 4 Nov 8 2014 /bin/sh -> dash* 

Простой тест теперь должен создавать журналы аудита в /var/log/audit/audit.log (я взял на себя смелость и добавил много разрывов строк, чтобы улучшить читаемость):

 server ~ # sh -c 'echo test' test server ~ # tail -f /var/log/audit/audit.log [...] type=SYSCALL msg=audit(1488219335.976:43871): arch=40000003 syscall=11 \ success=yes exit=0 a0=ffdca3ec a1=f7760e58 a2=ffdd399c a3=ffdca068 items=2 \ ppid=27771 pid=27800 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 \ fsgid=0 tty=pts7 ses=7532 comm="sh" exe="/bin/dash" key=(null) type=EXECVE msg=audit(1488219335.976:43871): argc=3 a0="sh" a1="-c" \ a2=6563686F2074657374 type=CWD msg=audit(1488219335.976:43871): \ cwd="/var/lib/iserv/remote-support/iserv-martin.von.wittich" type=PATH msg=audit(1488219335.976:43871): item=0 name="/bin/sh" inode=10403900 \ dev=08:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL type=PATH msg=audit(1488219335.976:43871): item=1 name=(null) inode=5345368 \ dev=08:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL type=PROCTITLE msg=audit(1488219335.976:43871): \ proctitle=7368002D63006563686F2074657374 

Большая часть информации кодируется, но ausearch может перевести ее с помощью -i :

 server ~ # ausearch -i -x /bin/dash | tail [...] ---- type=PROCTITLE msg=audit(27.02.2017 19:15:35.976:43871) : proctitle=sh type=PATH msg=audit(27.02.2017 19:15:35.976:43871) : item=1 name=(null) \ inode=5345368 dev=08:01 mode=file,755 ouid=root ogid=root rdev=00:00 \ nametype=NORMAL type=PATH msg=audit(27.02.2017 19:15:35.976:43871) : item=0 name=/bin/sh \ inode=10403900 dev=08:01 mode=file,755 ouid=root ogid=root rdev=00:00 \ nametype=NORMAL type=CWD msg=audit(27.02.2017 19:15:35.976:43871) : \ cwd=/var/lib/iserv/remote-support/iserv-martin.von.wittich type=EXECVE msg=audit(27.02.2017 19:15:35.976:43871) : argc=3 a0=sh a1=-c \ a2=echo test type=SYSCALL msg=audit(27.02.2017 19:15:35.976:43871) : arch=i386 \ syscall=execve success=yes exit=0 a0=0xffdca3ec a1=0xf7760e58 a2=0xffdd399c \ a3=0xffdca068 items=2 ppid=27771 pid=27800 auid=root uid=root gid=root \ euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts7 \ ses=7532 comm=sh exe=/bin/dash key=(null) ---- 

Если вы не хотите ограничивать фильтрацию ausearch /bin/dash , вы также можете использовать ausearch -i -m ALL для перевода полного журнала. Другим хорошим фильтром будет ausearch -i -p <PID of a zombie process> , в этом случае ausearch -i -p 27800 .

Просто оставьте эти правила на месте, пока не появятся новые процессы зомби, а затем выполните поиск процесса создания PID зомби:

 ausearch -i -p <PID> 

Это должно быть очень полезно для определения основной причины процессов зомби. В моем случае это был скрипт PHP, который использовал proc_open для создания скрипта Perl, не закрывая дескриптор proc_close .

 ps auxf | grep --color -5 ' Z ' 

показать иерархию процессов, включая зомби и их родителей. Идентификация имени сценария зомби сложна, поскольку «sh defunct» – это только вы видите