Pull to refresh

Алгоритм: Как оформить баг на ядро Linux

Reading time4 min
Views2.3K
Мой опыт в разработке и отладке Parallels Virtuozzo Containers позволил обобщить и сформулировать список пожеланий к описанию проблемы пользователя, который позволяет существенно уменьшить время диагностирования и решения проблемы в ядре операционной системы Linux. Прошу отметить, что при всей очевидности некоторых рекомендаций многие участники open-source сообщества по-прежнему пренебрегают ими. Алгоритм представлен подкатом.

  1. Описание проблемы.
    Самое главное, что вы должны сделать, это точно описать проблему и действия, которые приводят к ней. Любая, даже самая мелкая деталь, может быть важна. К этому же пункту можно отнести вопрос: «Как часто баг воспроизводится?».
  2. Версия ядра.
    Лучше если вы приложите к багу вывод команды:
    # uname -a
  3. Где вы взяли ядро?
    Ядро linux распространяется как в бинарном виде, так и в исходных кодах. В баге важно указать точную версию ядра и кем оно было собрано. Если вы его собрали самостоятельно, нужно приложить конфиг и так же может понадобится vmlinux или модуль. При падениях разработчики нередко сопоставляют дизассемблированный код и код на С, чтобы определить точное место, где произошел баг.
  4. Логи ядра.
    Пожалуй для индивидуальных пользователей это самая сложная тема. Наиболее надежный способ сбора логов — последовательный порт и вторая машина. Дома такая возможность есть не у всех, да и последовательные порты стали редкостью.
    Следующим шагом была netconsole. С ней вам достаточно на одной машине настроить rsyslogd для сбора логов через сеть и прописать ее адрес на всех серверах. Этот способ может не работать, особенно если баг связан с сетью.
    Netconsole упростила настройку сбора логов с серверов, но проблема пользователей оставалась актуальна, и был придуман kdump. На данный момент это самый мощный и в то же время самый ненадежный механизм. В случае крэша системы на диск сохраняется образ памяти. В дальнейшем его можно открыть утилитой crash и узнать состояние всех процессов, логи ядра, значение памяти по заданному адресу и т п. Он чем-то похоже на core файл, который откладывают приложения в случае падения.
  5. Версия и название дистрибутива и приложений непосредственно связанных с проблемой.
    Это только кажется, что ядро лежит под пользовательскими приложениями, и их работа зависит от поведения ядра. Но часто бывает что и поведение ядра зависит от пользовательских приложений.
  6. Проблемы с сетью.
    Какие-то пакеты не доходят до адресатов или наоборот что-то лишнее просачивается через фильтры. В этом случае полезно приложить лог tcpdump-а с обоих сторон.
  7. Sysrq
    Это такая магическая комбинация клавиш. Зажимаем Alt и нажимаем последовательно Prt-Scr и букву. Если нажать H, то в логах ядра появится небольшая помощь.
    Самой распространенной ситуацией применения sysrq являются все возможные зависания. Для начала стоит нажать L, что распечатает информацию о том чем занят каждый процессор в данный момент. T — распечатывает состояние каждого процесса. Так же с помощью этих клавиш можно убить все процессы, кроме init-а, сбросить данные из памяти на диск, перезагрузить машину, отправить машину в panic, показать состояние таймеров и памяти и т д.
  8. Параметры загрузки
    O параметрах ядра можно прочитать в Documentation/kernel-parameters.txt. В случае возникновения бага я бы рекомендовал включить следующие:
    sysrq_always_enabled — включается магические клавиши sysrq
    debug — повышает уровень логирования ядра
    earlyprintk — печатать лог ядра на ранней стадии. Эту опцию стоит включить, если машина на загрузке ничего не выдает и зависает.
    Так же рекомендовал бы убрать опцию quiet, которая в некоторых дистрибутивах включена по умолчанию. С ней ядро не печатает часть логов.

Дополнительные средства отладки.


  1. Debug ядра.
    Вы наверное замечали, что в дистрибутивах чаще всего два ядра одной версии. Одно из них имеет префикс debug. Это ядро работает немного медленнее и содержит ряд дополнительных проверок. Например: оно заполняет освобожденную память специальным шаблоном, проверяет, чтоб ядро не засыпало с запрещенными прерываниями, отслеживает порядок взятия блокировок и т д.
    Если у вас баг воспроизводится стабильно, то будет нелишним попробовать воспроизвести его на debug ядре и предоставить логи именно с него.
  2. Tracer
    Этот пункт скорее для совсем продвинутых пользователей, которые хотят сами разобраться с проблемой.
    Интерфейс к этому механизму полностью реализован в debugfs:
    mount debugfs -t debugfs /debug
    cd /debug/tracing

    Есть два вида трейсеров. Первый — это события, разработчики явно в коде сообщают о них. И второй ftrace — это трейсер, который показывает, в каком порядке вызывались функции ядра. Все события от трейсеров могут фильтроваться, включаться и выключаться отдельно. В случае если события отключены, то они практически не влияют на производительность ядра.

И в заключение несколько полезных советов.


  1. Приложение работает некорректно или зависает. Попробуйте воспользоваться утилитой strace, она показывает все системные вызовы с аргументами и кодом возврата.
  2. Процесс находится в состоянии D «uninterruptible sleep”. Скореe всего процесс находится в ядре. Можно попытаться посмотреть в /proc/[PID]/stack и /proc/[PID]/status.
  3. Если у вас случился panic. Просмотрите лог с самого начала. Часто в конце лога находятся сообщения об ошибках, которые являются следствием предыдущих. Баг нужно забить на первую ошибку.
  4. Для того чтобы ядро откладывало дампы памяти на диск, нужно загрузить ядро с опцией crashkernel=128M, установить на машину kexec-tools и запустить сервис kdump. Дампы будут сохраняться в /var/crash
  5. Лог ядра можно достать из дампа ядра при помощи утилиты makedumpfile:
    makedumpfile —dump-dmesg vmcore log.txt

Ссылки


Documentation/kdump/kdump.txt
Documentation/kernel-parameters.txt
Documentation/networking/netconsole.txt
Documentation/trace/ftrace.txt
tcpdumpt at Wikipedia
strace at Wikipedia
Tags:
Hubs:
Total votes 95: ↑92 and ↓3+89
Comments14

Articles