Системный программист
0,0
рейтинг
27 июля 2011 в 12:30

Администрирование → Алгоритм: Как оформить баг на ядро Linux из песочницы

Мой опыт в разработке и отладке 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
Вагин Андрей @avagin
карма
53,0
рейтинг 0,0
Системный программист
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Администрирование

Комментарии (14)

  • +11
    Правильная, хорошая статья. К сожалению — не для всех, т.к. подавляющее большинство «линуксоидов» просто кричит «у меня убунта падает, барахло все это!». К сожалению, каким-то боком я и сам… из этих.

    С другой стороны, таким пользователям о багах ядра писать и не обязательно ;)
    • 0
      У меня убунту падает из-за X-Freeze чаще всего, особенно при использовании Unity, а там говорят можете даже не открывать баги, пока точно не воспроизведете и в логах ничего особенного.
      Ядро как раз-таки стабильно.
    • НЛО прилетело и опубликовало эту надпись здесь
      • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Да и Dr Konqi из KDE так же работает.
  • НЛО прилетело и опубликовало эту надпись здесь
    • +2
      Нет, kdump фильтрует vmcore makedumpfile'ом. В зависимости от опций дамп можно сделать маленьким. Например на rhel6 по дефолту дампики с 8гб машины получаются в среднем по 50мб.
      • НЛО прилетело и опубликовало эту надпись здесь
  • +4
    а куда звонить багу-то слать?

    а то получается такой очень линукс-вей. пока собираешь всю информацию о баге, уже вобщемто сам его и чинить идешь…
    • +3
      Зависит от того чьё ядро вы используете. Если собрали из мейнстрима, то на bugzilla.kernel.org. Если используете ядро из дистрибутива, то в баг трекер дистрибутива или в службу поддержки.
  • 0
    Давно жду инструкции «как понять, баг это в ядре, в драйверах, в софте или это ты сам накосячил».
    • +1
      Если ядро в лог выдает Panic, BUG, WARNING, которые обычно сопровождаются бектрейсами и состоянием регистров, то это однозначно баг в ядре.
      Под драйверами, вы скорей всего понимаете модули, тогда это тоже ядро. В бектрейсе будет видно какому модулю принадлежит функция и можно будет догадаться на кого файлить баг. Если вы ошиблись, разработчики переведут баг на нужную компоненту.
      Сложнее когда, что-то не работает, а логах ничего нет. Тогда можно попробовать запустить программу под strace и попытаться понять, что идет не так. Так же стоит попробовать вспомнить, когда в последний раз эта функциональность работала, попытаться загрузить старое ядро и попробовать воспроизвести проблему. Если понять так и не удалось, то лучше зафайлить проблему на user space, просто по статистике в нем больше багов.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.