Как читать, понимать, анализировать и отлаживать панику ядра Linux?

Рассмотрим следующую трассировку стека дампов ядра Linux. Вы можете вызвать панику из исходного кода ядра, вызвав panic("debugging a linux kernel panic");:

[<001360ac>] (unwind_backtrace+0x0/0xf8) from [<00147b7c>] (warn_slowpath_common+0x50/0x60)
[<00147b7c>] (warn_slowpath_common+0x50/0x60) from [<00147c40>] (warn_slowpath_null+0x1c/0x24)
[<00147c40>] (warn_slowpath_null+0x1c/0x24) from [<0014de44>] (local_bh_enable_ip+0xa0/0xac)
[<0014de44>] (local_bh_enable_ip+0xa0/0xac) from [<0019594c>] (bdi_register+0xec/0x150)
  • В unwind_backtrace+0x0/0xf8 что за +0x0/0xf8 обозначает?
  • Как я могу увидеть код C unwind_backtrace+0x0/0xf8?
  • Как интерпретировать содержание паники?

3 ответа

Решение

Это просто обычная обратная трассировка, эти функции вызываются в обратном порядке (первая вызванная была вызвана предыдущей и т. Д.):

unwind_backtrace+0x0/0xf8
warn_slowpath_common+0x50/0x60
warn_slowpath_null+0x1c/0x24
ocal_bh_enable_ip+0xa0/0xac
bdi_register+0xec/0x150

bdi_register+0xec/0x150 это символ + смещение / длина, есть больше информации об этом в Понимании опций ядра и о том, как вы можете отлаживать опы ядра. Также есть этот превосходный учебник по отладке ядра

Примечание: как предложено ниже Евгением, вы можете сначала попробовать addr2line, хотя ему все еще нужно изображение с символами отладки, например,

addr2line -e vmlinux_with_debug_info 0019594c(+offset)

Вот 2 альтернативы для addr2line, Предполагая, что у вас есть подходящий набор инструментов для цели, вы можете выполнить одно из следующих действий:

использование objdump :

  1. найдите свой vmlinux или .ko файл в корневом каталоге ядра, затем разберите объектный файл:

    objdump -dS vmlinux > /tmp/kernel.s
    
  2. Откройте созданный файл сборки, /tmp/kernel.s, с помощью текстового редактора, такого как vim, Идти к unwind_backtrace+0x0/0xf8 поиск по адресу unwind_backtrace + offset, Наконец, вы нашли проблемную часть в вашем исходном коде.

использование gdb :

ИМО, еще более элегантный вариант - использовать один-единственный gdb, Предполагая, что у вас есть подходящий набор инструментов на вашем хост-компьютере:

  1. Бежать gdb <path-to-vmlinux>,
  2. Выполните в приглашении GDB: list *(unwind_backtrace+0x10),

Для получения дополнительной информации вы можете проверить следующее:

  1. Уловки отладки ядра.
  2. Отладка ядра Linux с помощью Gdb

В unwind_backtrace+0x0/0xf8 что за +0x0/0xf8 обозначает?

Первый номер (+0x0) - смещение от начала функции (unwind_backtrace в этом случае). Второй номер (0xf8) - общая длина функции. Учитывая эти две части информации, если у вас уже есть догадка о том, где произошла ошибка, этого может быть достаточно для подтверждения вашего подозрения (вы можете сказать (приблизительно), как далеко вы продвинулись в функции).

Чтобы получить точную исходную строку соответствующей инструкции (обычно лучше, чем догадки), используйте addr2line или другие методы в других ответах.

Другие вопросы по тегам