Анализ зависшего процесса
# 2 года, 4 месяца назад (отредактировано 9 месяцев, 1 неделя назад)
Цель чисто ознакомительная — ознакомить с основными моментами и утилитами. Все это есть в интернете, но разбросано по разным статьям. Просто приходилось несколько раз этим заниматься, а потому имелись некоторые наброски, с которыми и решил поделиться.
Повторюсь, это небольшая часть, чтобы не теряться и иметь хоть какой то план действий для проведения анализа, что при желании всегда можно расширить, благо интернет пока работает.
Процесс — это объект, который состоит из адресного пространства памяти и набора структур данных. Процессы являются частью операционной системы.
Грубо говоря, процесс это запущенная программа или служба … но следует отметить, что работающая программа содержит один или более процессов.
Также следует отметить, что наряду с процессами есть понятие задача, которую выполняет командный процессор. Задача — это рабочая единица командного процессора. Задачи находятся на более высоком уровне, чем процессы, операционная система ничего о них не знает.
Обычно, если процесс в течение некоторого времени не отвечает на запросы, то принято это событие считать зависанием процесса.
Хотя, если быть точным, для процесса не существует понятия зависания, он не может зависнуть в понимаемом нами смысле. Вот что об этом пишут умные дяди, привожу без перевода, (буду приводить такие цитаты и в дальнейшем — отношение свое к этому высказывать не буду, пусть каждый решает сам)
Но мы также будем употреблять термин зависание процесса в его обычном понимании.
Как правило к зависанию процесса приводят следующие основные причины
— нехватка оперативной памяти
— использует 100% CPU
— уход в бесконечный цикл
— блокировки
— можно отнести и дисковые операции ввода/вывода
Команда, позволяющая определить зависание процесса отсутствует. А потому чтобы выяснить, что процесс завис, необходимо задействовать целый комплекс утилит, при условии, конечно, что есть доступ к терминал-эмулятору или консоли. И конечно в результе анализа необходимо будет установить — завис процесс или не завис и установить причину этого зависания.
Привожу опять цитату умных дядей
1. А потому начинать лучше с самого простого — узнать потребление памяти, нагрузку cpu.
Для этого можно использовать простую утилиту ps
— сортировка по памяти (1-ая команда) или сортировка по нагрузке cpu (2-ая команда)
PS — вместо head -5 можно применить grep
Но если причина в нехватке памяти, то будут тормоза как при открытии терминала, так и ввода команды, так и при ожидании ответа при выполнении команды. В этом случае рекомендую использовать прямую связь с ядром (использовать волшебные кнопки)
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
или сразу обратится к первоисточнику, из которого ps черпает эту информацию
cat /proc/
/status | grep State
2.2 Есть еще два интересных параметр voluntary_ctxt_switches и nonvoluntary_ctxt_switches (показывают сколько раз процессор получал кванты CPU и отдавал назад)
cat /proc/
/status | grep voluntary
Если с течением времени эти параметры не меняются, то это говорит о том, приложение зависло.
2.3 Можно узнать место в коде ядра, где зависло — узнать имя функции, которая привела процесс к состоянию спячки/ожидания.
Для этого можно использовать ту же утилиту ps, но добавив поле wchan
ps -eo pid,pcpu,pmem,comm,status,wchan | grep
или посмотреть параметр stack
cat /proc/
/stack
Верхняя функция (верхушка стэка) и покажет эту функцию. Что означает эта функция, можно нагуглить.
Есть и другие ядерные вещи, но, имхо, толку от них обычным юзерам мало, нам нужно узнать хотя бы причину, намек, виновника блокировки, если это блокировка.
А потому здесь нужны более серъезные утилиты.
PS 1 — уточнение для утилиты ps в части wchan — это адрес события, которого ожидает процесс. У активного процесса эта колонка пустая.
PS 2 — можно для нахождения значений wchan использовать и такую штуку
cat /proc/
/stat | ./procstat
Например, для активного нормального процесса palemoon
где procstat — небольшая програмка для распарсивания вывода cat /proc/
/stat (имеется исходник procstat.c, который нужно скомпилить).
3. Посмотрели и убедились, что приложение зависло, далее нужно использовать другие утилиты.
Привожу опять цитату умных дядей
Явный признак такого состояния — 0% CPU, что означает, что процесс находится в каком-то блокирующем системном вызове, который приводит к тому, что ядро усыпляет процесс.
3.1 В этом случае рекомендуют утилиту strace (приаттачится к процессу)
вообщем на любителя и описывать нюансы работы утилиты strace не буду (всего не опишешь).
Только отмечу один момент — блокировки — в конце вывода будет строка типа — flock(3, LOCK_EX, что говорит о том, что файл, имеющий дескриптор 3, заблокирован.
Нужно узнать что это за файл — ls /proc/
/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/
/stack можно также использовать и cat /proc/
/syscall , вывод которого покажет нам номер системного вызова — будет что то типа такого, где 7 (1-ая цифра) это номер системного вызова
и далее узнаем название системного вызова по его номеру
grep 7 /usr/include/asm/unistd_64.h
#define __NR_poll 7
В части определения зависшего дескриптора (при использование strace) вместо ls /proc/
/fd можно использовать readlink /proc/
И еще про волшебные кнопки — комбинация 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
Источник
Как выявить причину зависания?
xubuntu 14.04_64 Стабильно раз в сутки стал зависать намертво, только hard_reset. Где посмотреть лог и причину зависания? Как определить?
сначала исключи ОС. Лучше всего с помощью не другого линукс. Обычно висяки случаются от железа, но лучше не гадать, а применить метод исключения.
память проверить тем же memtest’ом не помешает.
что сенсоры в плане температуры показывают?
что сенсоры в плане температуры показывают?
С температурой все норм. Память попробую проверить.
сначала исключи ОС. Лучше всего с помощью не другого линукс. Обычно висяки случаются от железа, но лучше не гадать, а применить метод исключения.
Возможно, недавно систему переставил, до этого такого не наблюдалось.
если хочешь заниматься гаданием, то зачем совета искал? Сразу бы гадал. Давай вместе погадаем. А мож озу. А мож кондеры на матери. А мож кондеры в бп. А мож на матери что пробило. А мож просто из обвязки что то кривое. А мож модульный драйвер на что нибудь кривой. А мож сосед в электросеть гравицапу включает. А мож просто бп говно. А мож видяха глючит. А мож пыль кз дает. А мож контакт где звенит. А мож вирус страшный злобный. А мож котик приходит потереться.
Будем гадать или что?
Лучше всего с помощью не другого линукс.
Винду поставить что ли?
или винду или юникс. Надо исключить баг в ядре.
погляди в логи на предмет хардварных ошибок. я так внезапный беспричинный ребут отловил
/var/log/
тебя могут заинтересовать messages, dmesg и kern.log (или kernel.log, не знаю как в убунтах он называется)
Лучше всего будет полностью удалить вирусную прошивку под названием «Linux». И начать наконец пользоваться нормальными системами.
dmesg, df -h,/proc/config.gz, /proc/cpuinfo в студию
попробуй подключить mcelog
чтобы отфильтровать возможные проблемы — загрузись с livecd (vendor distro, SystemRescueCD) и оставь на пару суток
proc/config.gz не нашел, в proc/нету
/proc/cpuinfo пустой файл
[ 40.965901] ————[ cut here ]———— [ 40.965948] WARNING: CPU: 0 PID: 1712 at /build/linux-lts-vivid-LIqOuh/linux-lts-vivid-3.19.0/ubuntu/i915/intel_uncore.c:620 hsw_unclaimed_reg_debug.isra.14+0x80/0xa0 [i915_bpo]()
попробуй этот WARNING проверить
как его проверить?
скорее всего, файловая система крякнула и полетела
скорее всег, файловая система крякнула и полетела
Источник
Как узнать почему зависла ubuntu. Где лежат логи, и есть ли они?
Поставил я значит ubuntu 15.10, но она достаточно часто (раз в 1-2 дня точно) стала виснуть. Хотя на старой версии убунты этого не было.
Собственно вопрос, а можно ли узнать почему она зависает? Есть системные логи, где они лежат?
- Вопрос задан более трёх лет назад
- 3637 просмотров
Если система инициализации — systemd (а в этой версии убунты вроде она) — то можно сделать следующиее
1. добавить к параметрам ядра опцию для большего выхлопа
systemd.log_level=debug
2. При зависании, после перезагрузки использовать journalctl, чтобы просмотреть логи с предыдущей загрузки до выключения:
journalctl -p 0..3 -b 1
-p 0..3 это фильтр по приоритету записей в логах, от ошибок до АДСКИХ ошибок, список возможных вариантов: emerg(0), alert(1), crit(2), err(3), warning(4), notice(5), info(6), debug(7).
-b это диапазон загрузок, например -b 0 покажет только логи за текущую загрузку, -b 1 за предыдущую, -b 0..9 за десять последних.
Если хочется более подробных логов, то можно ещё добавить -o verbose, но тогда в них можно утонуть 😀
systemd делает огромную работу по собиранию и агрегации логов в одном месте, и даёт инструменты для работы с ними — глупо этим пренебрегать. Подробнее о том, как решать проблемы с systemd — тут например.
Источник
Что делать если зависла Ubuntu
Операционная система Linux намного стабильнее Windows. Но и здесь тоже иногда случаются зависания. Зависнуть может как отдельное приложение, полностью графическая оболочка или вся система. Важно знать, как правильно действовать в таких случаях, когда зависает ubuntu 16.04, чтобы не повредить данные и файловую систему, чтобы выйти из таких ситуаций с минимальными потерями.
В этой инструкции мы рассмотрим возможные причины зависания Ubuntu, что со всем этим делать, а также как попытаться спасти не сохраненные данные. Это, наверное, самый важный момент — выйти из ситуации без потери данных.
Зависла программа Ubuntu
Сама система, ядро или графическая оболочка зависают очень редко. Они уже множество раз протестированы, перепроверены и достаточно стабильны. А вот сторонние программы могут зависать довольно-таки часто, даже ни с того ни с сего.
Эти зависания не опасны для системы и очень просто решаются. В Ubuntu есть несколько графических утилит для завершения зависших приложений. Их мы рассмотрим чуть ниже. Но очень жаль несохраненных данных, которые остались, когда зависла программа Ubuntu. Если вы пользуетесь крупными редакторами, такими как Libreoffice или WPS office, то, скорее всего, редактируемый текст автоматически сохранился. Но в браузере и простых редакторах ситуация не такая безоблачная. Но даже те данные можно попытаться спасти, хотя работает этот способ не всегда.
Предположим, что завис Gedit. Сначала откройте терминал нажатием сочетания клавиш Ctrl+Alt+T. Теперь попробуем узнать PID процесса Gedit с помощью ps:
ps aux | grep gedit
Уже на этом этапе можно завершить программу. Но я вам покажу, как спасти редактируемый текст. Мы получим дамп памяти процесса и извлечем оттуда редактируемый текст. Для этого подключитесь к процессу Gedit с помощью отладчика gdb:
1493 — это PID зависшей программы, который мы узнали в предыдущей команде.
Дальше сохраним дамп памяти, выполнив в консоли Gdb:
Вот и все, отключаемся от процесса
Для выхода с отладчика нажмите q. Теперь у нас есть все данные сохраненные в памяти нашего приложения, и мы можем легко извлечь нужную информацию:
strings core.1493 | grep ‘my text’
С английским текстом работает на ура.
Самый простой способ закрыть зависшее приложение в Ubuntu — это Xkill. Нажмите Alt+F2 и наберите Xkill и нажмите Enter:
Теперь курсор превратился в крестик и достаточно кликнуть на любом окне, чтобы его закрыть.
Кроме того, в Ubuntu есть аналог диспетчера задач Windows — системный монитор. Чтобы его открыть наберите Системный или System в поиске Dash. Здесь отображаются все запущенные приложения, и любое из них можно завершить через контекстное меню, если зависла программа в Ubuntu, вы можете ее закрыть:
Также закрыть зависшее приложение ubuntu можно из терминала, например, с помощью команды kill:
1493 — это PID. Также можно не использовать PID а сразу завершить программу по имени:
Зависла графическая оболочка в Ubuntu
С зависанием приложений разобрались. Это было не очень страшно. Но что делать, если графическая оболочка Ubuntu зависла намертво, и вы не можете ни запустить системный монитор, ни XKill? Это может случиться по разным причинам, например, из-за неправильных драйверов или ошибке в системных программах. Но Linux тем отличается от Windows, что здесь кроме графической оболочки есть еще и режим терминала. Графическая оболочка зависла, но система все еще работает. Поэтому мы можем все исправить.
Сначала можно просто попытаться перезагрузить X сервер. Для этого используется специальная комбинация клавиш — Ctrl+Alt+Backspace.
Далее, если не помогло, переключаемся в один из терминалов. Всего в Linux по умолчанию создается 12 терминалов входа. И доступны они по сочетанию клавиш Ctrl+Alt+Fцифра.
Графический сервер, как правило, размещается по Ctrl+Alt+F7. Переключаемся в первый терминал Ctrl+Alt+F1, вводим там логин и пароль, затем перезагружаем графический сервер командой:
sudo service lightdm restart
Если в приложениях остались не сохраненные данные, их можно попытаться извлечь описанным выше способом. Но поскольку тут уже зависла Ubuntu, и работать нужно в терминале, все сделать будет немного сложнее хотя бы потому, что вы не сможете копировать команды.
Не хватает памяти
Если все сделать правильно — такой тип зависания даже менее опасный, чем предыдущий. Конечно, лучше таких моментов не допускать и настроить раздел подкачки или сжатие оперативной памяти с помощью zram, но если оно уже случилось и застало вас врасплох, можно попытаться что-то сделать.
Если вы еще можете переключиться в режим терминала, переключайтесь (Ctrl+Alt+F1), вводите логин и пароль. Причем будьте готовы к тому, что система будет работать очень медленно.
Отсортировать процессы по потреблению памяти можно командой:
Дальше остается завершить виновника одной из вышеописанных команд, например, pkill:
Посмотреть количество свободной памяти можно командой:
В современные ядра встроен механизм мониторинга памяти, таким образом, если памяти недостаточно, ядро смотрит какая программа потребляет больше всего и завершает ее, только в случае, если запущенно большое количество мелких программ этот процесс может занять много времени.
Если вы не хотите ждать и нет возможности перейти в режим терминала, можно попросить ядро завершить все процессы в текущем сеансе терминала сочинением клавиш Alt+PrintScreen+K. Завершит все запущенные вами программы в текущей терминальной сессии, в том числе графическую оболочку и ту программу, что использует много оперативной памяти.
Ubuntu зависла полностью
Хорошо, а что же делать, если Ubuntu зависла намертво, полностью? Если система уже ни на что не реагирует, но ядро, скорее всего, работает то можно попытаться выполнить безопасную перезагрузку. Ядро поддерживает несколько сочетаний клавиш, которыми можно ему напрямую отдавать команды.
Нажмите и удерживайте клавиши Alt+PrintScreen, и последовательно с интервалом 2-3 секунды нажимайте:
R E I S U B
- R — вернуть ядру управление над клавиатурой
- E — отправить сигнал SigTerm всем процессам
- I — отправить сигнал SigKill всем процессам
- U — Перемонтировать все файловые системы в режим только для чтения
- S — Сохранить все буфера файловых систем на жесткий диск
- B — Перезагрузить.
По сути, все эти действия происходят и при обычной перезагрузке. Но здесь мы выполняем их вручную.
Если же ubuntu зависает намертво и даже не работает последний метод, остается нажать кнопку Reset или на 6 секунд зажать кнопку выключения.
Не хватает энергии
Уже не первый раз сталкиваюсь с проблемой, что компьютеру не хватает энергии. Во время работы мышь и клавиатура неожиданно перестают работать. Складывается впечатление, что компьютер полностью завис, однако это не так. В данном случае, материнской плате не хватает тока, чтобы дать полноценное питание для мыши и клавиатуры. Убедится что у вас именно эта проблема можно отключив клавиатуру от компьютера, а мышь переставив в другой разъем. Если заработало — проблема здесь. Решить можно заменив мышь и клавиатуру на PS/2 или на беспроводный вариант. Также можно попытаться заменить блок питания на более мощный.
Выводы
Теперь мы рассмотрели все что нужно, чтобы привести свою систему в чувство, и вы знаете что делать если зависла Ubuntu и как закрыть зависшее приложение. Если у вас есть другие, более эффективные способы, напишите в комментариях!
Источник