vasek |
|
Темы:
48
Сообщения:
11320
Участник с: 17 февраля 2013
|
Решил в кратце описать о зависшем процессе - как определить, что он зависший и при возможности найти причину. Нахождение причины самое сложное, однозначного совета нет и чтобы найти виновника нужно применять серъезные утилиты, работа с которыми требует определенных знаний и навыков. Цель чисто ознакомительная - ознакомить с основными моментами и утилитами. Все это есть в интернете, но разбросано по разным статьям. Просто приходилось несколько раз этим заниматься, а потому имелись некоторые наброски, с которыми и решил поделиться. Повторюсь, это небольшая часть, чтобы не теряться и иметь хоть какой то план действий для проведения анализа, что при желании всегда можно расширить, благо интернет пока работает. Процесс - это объект, который состоит из адресного пространства памяти и набора структур данных. Процессы являются частью операционной системы. Грубо говоря, процесс это запущенная программа или служба … но следует отметить, что работающая программа содержит один или более процессов. Также следует отметить, что наряду с процессами есть понятие задача, которую выполняет командный процессор. Задача - это рабочая единица командного процессора. Задачи находятся на более высоком уровне, чем процессы, операционная система ничего о них не знает. Обычно, если процесс в течение некоторого времени не отвечает на запросы, то принято это событие считать зависанием процесса. Хотя, если быть точным, для процесса не существует понятия зависания, он не может зависнуть в понимаемом нами смысле. Вот что об этом пишут умные дяди, привожу без перевода, (буду приводить такие цитаты и в дальнейшем - отношение свое к этому высказывать не буду, пусть каждый решает сам) Но мы также будем употреблять термин зависание процесса в его обычном понимании.Как правило к зависанию процесса приводят следующие основные причины - нехватка оперативной памяти - использует 100% CPU - уход в бесконечный цикл - блокировки - можно отнести и дисковые операции ввода/вывода Команда, позволяющая определить зависание процесса отсутствует. А потому чтобы выяснить, что процесс завис, необходимо задействовать целый комплекс утилит, при условии, конечно, что есть доступ к терминал-эмулятору или консоли. И конечно в результе анализа необходимо будет установить - завис процесс или не завис и установить причину этого зависания. Привожу опять цитату умных дядей 1. А потому начинать лучше с самого простого - узнать потребление памяти, нагрузку cpu.Для этого можно использовать простую утилиту ps - сортировка по памяти (1-ая команда) или сортировка по нагрузке cpu (2-ая команда) PS - вместо head -5 можно применить grep <PID>Но если причина в нехватке памяти, то будут тормоза как при открытии терминала, так и ввода команды, так и при ожидании ответа при выполнении команды. В этом случае рекомендую использовать прямую связь с ядром (использовать волшебные кнопки) ALT+SysRq+f - вызов oom_kill, чтобы убить самый жрущий процесс (действует не сразу, придется подождать несколько минут) PS 1 - не забывем, что значение /proc/sys/kernel/sysrq должно быть равно 1. PS 2 - рекомендую читать логи (обычно запускаю journalctl -f) - oom_kill работает хитро, если он считает, что памяти достаточно, то ни одно приложение убито не будет, просто выдаст сообщение. Привожу пример запуска в нормальном состоянии На любителя можно использовать top, htop, atop, vmstat и др., которые позволяют узнать нагрузки памяти и процессора (некоторые позволяют узать и нагрузку на дисковые операции ввода/вывода).2. Имеются простые способы узнать/оценить, находится процесс в зависшем состоянии или нет. Правда в поиске виновника это нам не поможет, но хотя бы прояснит немного ситуацию. 2.1 Посмотреть параметр state процесса можно добавить это в команду ps -eo pid,state,pcpu,pmem,comm | grep <PID> или сразу обратится к первоисточнику, из которого ps черпает эту информацию cat /proc/<PID>/status | grep State 2.2 Есть еще два интересных параметр voluntary_ctxt_switches и nonvoluntary_ctxt_switches (показывают сколько раз процессор получал кванты CPU и отдавал назад) cat /proc/<PID>/status | grep voluntary Если с течением времени эти параметры не меняются, то это говорит о том, приложение зависло. 2.3 Можно узнать место в коде ядра, где зависло - узнать имя функции, которая привела процесс к состоянию спячки/ожидания. Для этого можно использовать ту же утилиту ps, но добавив поле wchan ps -eo pid,pcpu,pmem,comm,status,wchan | grep <PID> или посмотреть параметр stack cat /proc/<PID>/stack Верхняя функция (верхушка стэка) и покажет эту функцию. Что означает эта функция, можно нагуглить. Есть и другие ядерные вещи, но, имхо, толку от них обычным юзерам мало, нам нужно узнать хотя бы причину, намек, виновника блокировки, если это блокировка. А потому здесь нужны более серъезные утилиты. PS 1 - уточнение для утилиты ps в части wchan - это адрес события, которого ожидает процесс. У активного процесса эта колонка пустая. PS 2 - можно для нахождения значений wchan использовать и такую штуку cat /proc/<PID>/stat | ./procstat Например, для активного нормального процесса palemoon где procstat - небольшая програмка для распарсивания вывода cat /proc/<PID>/stat (имеется исходник procstat.c, который нужно скомпилить).3. Посмотрели и убедились, что приложение зависло, далее нужно использовать другие утилиты. Привожу опять цитату умных дядей Явный признак такого состояния - 0% CPU, что означает, что процесс находится в каком-то блокирующем системном вызове, который приводит к тому, что ядро усыпляет процесс.3.1 В этом случае рекомендуют утилиту strace (приаттачится к процессу) вообщем на любителя и описывать нюансы работы утилиты strace не буду (всего не опишешь).Только отмечу один момент - блокировки - в конце вывода будет строка типа - flock(3, LOCK_EX, что говорит о том, что файл, имеющий дескриптор 3, заблокирован. Нужно узнать что это за файл - ls /proc/<PID>/fd , получим что то типа /tmp/file.lock и далее находим процесс, удерживающий этот файл - lsof | grep /tmp/file.lock 3.2 Можно использовать и утилиту gdb, но для получения информативности необходимо чтобы пакет исследуемого приложения был собран с отладочной информацией. Хотя если анализировать только стэк, то можно и без отладочной информации - как правило, если трассировка стека не меняется с течением времени (достаточно несколько проверок с периодичностью в несколько минут), то приложение висит. Также на вершине стэка увидим функцию, которая к этому привела. А вот чтобы выполнить отладку зависшего процесса, необходимо, во 1-ых, чтобы пакет был собран с отладочной информацией и, во 2-ых, иметь навык использования отладки с помощью gdb. 4. И напоследок - иногда наблюдается не зависание, как таковое, а небольшая задержка при выполнении/старте приложения (может доходить до нескольких секунд). В этом случае может помочь комбайн sysdig - описывать не буду, а даю ссылку на один из топиков, в котором был найден виновник, с использованием sysdig (там же можно найти и установку и ссылку на описание). EDIT 1 - и, конечно, у кого появится что то новенькое, уточняющее неплохо выкладывать здесь же - пусть все будет в одном месте. .................................................................................. Дополнение/уточнение от 05.06.2019 В части зависания можно придерживаться следующих правил (но не забывать, что бывают и исключения) Приложение скорее всего заблокировано и ничего не делает если cpu и mem не загружены. Приложение находится в бесконечном цикле - cpu под 100% и возможно загружена память. Приложению не хватает памяти - сильное торможение, долгий ответ на запросы, загружена память. ОЖИДАНИЕ - пассивное состояние процесса, процесс заблокирован (скорее всего на каком-то системном вызове), точнее, процесс не может выполняться, так как ожидает некоторого события, вероятнее всего завершения операции ввода-вывода и менее вероятно получения сообщения от другого процесса или освобождения какого-либо необходимого ему ресурса. И если процесс висит долго, то, как правило, убить процесс не удается, так как теряется связь ядра с процессом и не срабатывают даже волшебные клавиши. Но пробовать их всеравно нужно, чтобы уточнить наличие/отсутствие связи с ядром. Дополнение в части определения ядерного кода/функции/ или как говорят системного вызова на котором заввисли. Вместо cat /proc/<PID>/stack можно также использовать и cat /proc/<PID>/syscall , вывод которого покажет нам номер системного вызова - будет что то типа такого, где 7 (1-ая цифра) это номер системного вызова и далее узнаем название системного вызова по его номеруgrep 7 /usr/include/asm/unistd_64.h #define __NR_poll 7 В части определения зависшего дескриптора (при использование strace) вместо ls /proc/<PID>/fd можно использовать readlink /proc/<PID>/fd/3 И еще про волшебные кнопки - комбинация Alt+SysRq+t - выведет всю информацию о запущенных процессах и плюс стэк - будет слишком большой вывод, но возможно и пригодится (лучше использовать в паре с journalctl -f) PS - 't' - show-task-states. Will dump a list of current tasks and their information to your console. ....................................................................................................................................................................... Уточнение от 06.12.2020 Иногда проще получить информацию о зависании процесса, используя комбинации клавищ Alt+SysRq+KEY, где KEY=f|m|t|w Информация с большой вероятностью запишется в journal, где ее можно проанализировать при следующей загрузке.Но чтобы это задействовать, нужно сначала (заранее) установить значение kernel.sysrq=1, для чего прописать в файле /etc/sysctl.d/99-sysctl.conf строчку чтобы изменения вступили в силу в текущей загрузке, необходимо выполнить команду: sudo sysctl -p /etc/sysctl.d/99-sysctl.confПримерный анализ логов после применения комбинаций Alt+SysRq+KEY описал в этом топике
Ошибки не исчезают с опытом - они просто умнеют
|
ZeniaM |
|
Темы:
37
Сообщения:
299
Участник с: 20 сентября 2015
|
Спасибо. Полезная статья, всегда при проблемных ситуациях возникает главный вопрос <<С чего начать!>> И Ваши статьи большое подспорье в этом. |
vasek |
|
Темы:
48
Сообщения:
11320
Участник с: 17 февраля 2013
|
Сделал небольшое дополнение/уточнение
Ошибки не исчезают с опытом - они просто умнеют
|
vasek |
|
Темы:
48
Сообщения:
11320
Участник с: 17 февраля 2013
|
Сделал небольшое уточнение в части комбинаций клавиш с SysRq
Ошибки не исчезают с опытом - они просто умнеют
|