Подтвердить что ты не робот

Как читать, понимать, анализировать и отлаживать панику ядра 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?
  • Как интерпретировать содержимое паники?
4b9b3361

Ответ 1

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

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 - это символ + смещение/длина, там больше информации об этом в Понимание ядра Oops и то, как вы можете отлаживать ядро ​​oops. Также есть этот отличный учебник по Отладка ядра

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

addr2line -e vmlinux_with_debug_info 0019594c(+offset)

Ответ 2

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

Использовать objdump:

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

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

Использовать gdb:

IMO, еще более элегантным вариантом является использование только одного gdb. Предполагая, что у вас есть подходящая инструментальная цепочка на вашей главной машине:

  • Запустите gdb <path-to-vmlinux>.
  • Выполнить в приглашении gdb: list *(unwind_backtrace+0x10).

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

Ответ 3

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

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

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