Когда мы запускаем какую-либо команду, ядро создает процесс, который делает системный вызов fork и создает тем самым дочерний процесс.
В дочернем процессе вызывается системный вызов exec, который заменяет его код на код программы. Когда программа завершается, она посылает exit, после чего освобождает ресурсы, а именно память и файловые дескрипторы, но запись остается в таблице процессов. В свою очередь родительский процесс должен послать системный вызов wait, считать код завершение программы и удалить pid из таблицы процессов.
Промежуток времени после того, как дочерний процесс (программа) послала exit и родительский процесс еще не вызвал wait и есть состояние зомби.
Как завершить процесс руками? (без kill -9)
Находим pid процесса зомби
ps aux | grep <process_name>
Подключаемся с помощью gdb
gdb -p <pid>
Вызываем wait
(gdb) call wait()
Отключаемся
(gdb) detach
(gdb) quit