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

Как эффективно использовать трассировку стека (из ядра или ядра)?

Если вам повезет, когда ваш модуль ядра выйдет из строя, вы получите сообщение oops с журналом с большим количеством информации, например, значениями в регистрах и т.д. Одной из таких данных является трассировка стека (то же самое верно для основных дампов, но я изначально задал это для модулей ядра). Возьмите этот пример:

[<f97ade02>] ? skink_free_devices+0x32/0xb0 [skin_kernel]
[<f97aba45>] ? cleanup_module+0x1e5/0x550 [skin_kernel]
[<c017d0e7>] ? __stop_machine+0x57/0x70
[<c016dec0>] ? __try_stop_module+0x0/0x30
[<c016f069>] ? sys_delete_module+0x149/0x210
[<c0102f24>] ? sysenter_do_call+0x12/0x16

Я предполагаю, что +<number1>/<number2> имеет какое-то отношение к смещению от функции, в которой произошла ошибка. То есть, проверив это число, возможно, глядя на сборку, я должен узнать строку (еще лучше, инструкцию), в которой произошла эта ошибка. Это правильно?

Мой вопрос: что это за два числа? Как вы их используете?

4b9b3361

Ответ 1

skink_free_devices+0x32/0xb0

Это означает, что команда-нарушитель составляет 0x32 байт от начала функции skink_free_devices(), которая в целом равна 0xB0 байтам.

Если вы скомпилируете ядро ​​с включенным -g, вы можете получить номер строки внутри функций, где элемент управления подпрыгнул с помощью инструмента addr2line или нашего старого старого gdb

Что-то вроде этого

$ addr2line -e ./vmlinux 0xc01cf0d1
/mnt/linux-2.5.26/include/asm/bitops.h:244
or
$ gdb ./vmlinux
...
(gdb) l *0xc01cf0d1
0xc01cf0d1 is in read_chan (include/asm/bitops.h:244).
(...)
244     return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
(...)

Итак, просто укажите адрес, который вы хотите проверить, на addr2line или gdb, и они сообщают вам номер строки в исходном файле, где присутствует функция нарушения См. эту статью для полной информации

EDIT: vmlinux - это несжатая версия ядра, используемая для отладки и обычно найденная @ /lib/modules/$(uname -r)/build/vmlinux при условии, что вы создали свое ядро ​​из источников. vmlinuz, который вы находите в /boot, является сжатым ядром и может быть не столь полезным при отладке

Ответ 2

Для пользователей Emacs здесь является основным способом, который легко перемещается в трассировке стека (использует addr2line внутренне).

Отказ от ответственности: я написал это:)