Когда система зависает, диск отваливается или после обновления ядра пропадает звук, первым делом смотрят в сообщения ядра. dmesg и журнал systemd хранят следы сбоя, но обилие строк и незнакомые термины отпугивают. Разберём, как читать эти сообщения, что означает kernel oops и какие данные собрать, чтобы понять причину.

Откуда берутся сообщения ядра

Ядро пишет диагностику в кольцевой буфер через printk. У каждой строки есть уровень важности от 0 (emerg) до 7 (debug), время в секундах с момента загрузки и имя подсистемы. Буфер ограничен, старые записи вытесняются; размер задаётся параметром log_buf_len. systemd-journald дополнительно забирает сообщения из /dev/kmsg и хранит их в журнале, поэтому после перезагрузки история обычно доступна.

На консоль попадают не все строки: порог задаёт параметр loglevel и файл /proc/sys/kernel/printk. Значение 4 означает, что в терминал выводятся только ошибки и выше, хотя в буфер по-прежнему пишется всё. Поэтому отсутствие сообщения на экране не значит, что его нет в dmesg.

Базовые команды

Утилита dmesg показывает буфер, а флаги делают его читаемым. Без прав root вывод может быть пуст, если включён kernel.dmesg_restrict=1.

sudo dmesg -T -l err,warn
sudo dmesg --since "1 hour ago" --time-format=iso
sudo dmesg -wH
journalctl -k -b -1 --no-pager

Флаг -T переводит секунды в человеческое время, но после смены часов или гибернации метка может смещаться. -w следит за новыми строками, -H добавляет цвета и удобное время. journalctl -k показывает только сообщения ядра, -b -1 — предыдущую загрузку.

Уровни важности и фильтры

Уровни помогают отсеять шум: err и warn дают ошибки и предупреждения, crit — критические события. Не игнорируйте строки с ACPI, PCIe, ata и nvme: именно там появляются ранние признаки отказа оборудования.

sudo dmesg -l emerg,alert,crit,err
journalctl -k -p warning --since today
journalctl -k --grep="Out of memory"

Как читать kernel oops

Oops — это неожиданное исключение в коде ядра. Типичная запись начинается с BUG: unable to handle page fault, затем идут причина, режим доступа и адрес. Строка RIP указывает функцию и смещение, Call Trace показывает стек вызовов, а Code — машинные инструкции вокруг сбоя.

BUG: unable to handle page fault for address: 0000000000000018
#PF: supervisor read access in kernel mode
RIP: 0010:example_driver_read+0x1c/0x80 [example_driver]
Call Trace:
 __x64_sys_read+0x1a/0x20
 do_syscall_64+0x5c/0x90
Tainted: P           OE

Смещение после плюса помогает найти строку в исходниках, если известна версия ядра и конфигурация. Tainted перечисляет флаги, влияющие на доверие к отчёту. Если в стеке участвует сторонний модуль, первым подозреваемым становится он.

Флаги tainted

Ядро помечает себя грязным, когда условия отличаются от эталонных. P означает проприетарный модуль, O — модуль вне дерева, E — неподписанный модуль, W — уже было предупреждение, D — ядро погибло после oops, M — аппаратная ошибка. Полный список есть в Documentation/admin-guide/tainted-kernels.rst.

cat /proc/sys/kernel/tainted
sudo dmesg -T -l warn | grep -i tainted
modinfo example_driver | head -20

Числовое значение tainted — битовая маска. Если флаг появился после установки драйвера, начните с его удаления или обновления.

Что делать при oops

  1. Сохраните полный вывод dmesg и journalctl за текущую и предыдущую загрузку.
  2. Запишите версию ядра, дистрибутив и список модулей.
  3. Определите модуль из RIP и Call Trace, проверьте его происхождение.
  4. Попробуйте воспроизвести сценарий без подозрительного модуля.
  5. Проверьте память и диск: memtest86+ и smartctl исключают железо.
uname -a
lsmod | sort
sudo smartctl -a /dev/nvme0
sudo memtester 1G 1

Если oops повторяется на штатном ядре без сторонних модулей, это повод для отчёта разработчикам. Приложите полный лог, а не одну строку, и укажите шаги воспроизведения. Проверьте также, не совпадает ли сбой с моментом подключения конкретного устройства или запуска определённой программы.

Аппаратные ошибки

Строки Machine Check Exception, PCIe Bus Error и nvme timeout говорят о железе или прошивке. Для сбора MCE используйте rasdaemon, для PCIe — вывод lspci -vv и строки AER в журнале. Ошибки nvme часто сопровождаются сбросом контроллера.

sudo ras-mc-ctl --summary
sudo lspci -vv | grep -A5 "Advanced Error"
sudo nvme smart-log /dev/nvme0
sudo dmesg -T | grep -iE "mce|aer|nvme|ata error"

Не игнорируйте единичные corrected-ошибки: их рост предшествует отказу. Сохраните SMART-атрибуты и сравните через неделю. Полезно разделить события по времени: если ошибка появляется только под нагрузкой, проверяйте питание и охлаждение; если сразу после старта — прошивку и совместимость. Единичный сбой после обновления ядра чаще связан с драйвером, а серия одинаковых адресов указывает на память.

Записывайте, что менялось перед сбоем: ядро, модуль, firmware, настройки UEFI. Эта хронология часто важнее самого текста oops.

Зависания и нехватка памяти

Soft lockup означает, что процессор слишком долго не отдавал управление; hung task — что задача ждала более hung_task_timeout_secs. OOM killer пишет, какой процесс убит и сколько памяти было доступно. Во всех трёх случаях важен контекст: нагрузка, свободная память, состояние диска.

journalctl -k --grep="soft lockup"
journalctl -k --grep="blocked for more than"
free -h
vmstat 1 5

Сохранение лога после падения

При полном зависании обычный журнал не успевает сохраниться. Помогает pstore: настройте ramoops или EFI-переменные, и ядро сохранит хвост лога в /sys/fs/pstore. Для серьёзной диагностики настраивают kdump: резервируют память параметром crashkernel и загружают второе ядро, которое снимает дамп через /proc/vmcore.

ls -l /sys/fs/pstore
cat /proc/cmdline
sudo sysctl kernel.panic_on_oops=1
sudo sysctl kernel.panic=10

panic_on_oops полезен на серверах с kdump: система сразу перезагружается и сохраняет дамп, вместо того чтобы работать в неопределённом состоянии. На рабочей машине это может быть неудобно.

Чек-лист сбора данных

  • полный dmesg текущей загрузки и journalctl -k -b -1;
  • версия ядра, дистрибутив, список модулей;
  • флаги tainted и подозрительный модуль;
  • вывод smartctl и результаты теста памяти;
  • шаги воспроизведения и время сбоя;
  • наличие pstore или kdump-дампа.

Итог

dmesg — не страшный поток текста, а структурированный отчёт: уровень, подсистема, функция, стек. Научитесь находить RIP, Call Trace и tainted, отделяйте программную ошибку от аппаратной и всегда сохраняйте полный лог. Это экономит часы догадок и делает разговор с разработчиками предметным, а не эмоциональным.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте