Главная » Ядро Linux » Сообщения Oops

0

Сообщения oops — обычный для  ядра  способ сообщить пользователю, что произошло  что-то  нехорошее. Так  как  ядро  управляет всей  системой, то  оно  не  может  само себя  исправить, или  завершить, как  это  возможно для  программ пространства пользователя,  когда  они  делают  что-то   не  так.  Вместо  этого,  ядро  выводит сообщение oops . Такое  сообщение включает вывод  информации об  ошибке на  консоль, вывод дампа  содержимого всех  регистров и вывод  обратной трассировки вызовов функций (back  trace).  Сбои  в работе  ядра  трудно  обработать, поэтому ядро  должно "пролезть” через  многие дыры,  чтобы  вывести сообщение oop s  и  выполнить за  собой   все  необходимые действия по  очистке.  Часто   после   выдачи   сообщения  oop s  ядро  находится  в несогласованном состоянии. Например, в момент возникновения  ситуации, в  которой  выдается сообщение  oops , ядро  может  находится в  процессе обработки важных  данных. В  этот  момент может  удерживаться блокировка,  или  выполняться сеанс   взаимодействия  с  оборудованием.  Ядро  должно аккуратно  отойти от текущего состояния и  попытаться восстановить контроль над  системой. Во  многих  случаях это  невозможно. Если  ситуация, в которой выдается сообщение oops , возникает в контексте прерывания,  то  ядро  не  может  продолжать работу  и  переходит в  состояние  паники. Состояние паники проявляется в полной остановке системы. Если oop s  возникает в  холостой задаче   (idle  task,  идентификатор pi d  равен   нулю),  или при  выполнении процесса ini t  (идентификатор pi d равен  единице), то ядро  также переходит в состояние паники,  потому  что  ядро  не  может  продолжать выполнение

без  этих  важных  процессов.  Однако,  если  oop s  возникает при  выполнении любого другого  процесса, то  ядро  завершает этот  процесс и  продолжает работу.

Сообщение oops  может  выдаваться по  многим причинам,  включая недопустимый доступ  к  памяти  (memory access  violation)  и  выполнение  недопустимой машинной команды.  Как  разработчику ядра,  вам  придется иметь  дело  с  сообщениями oop s  и далее, несомненно, быть  причиной их появления.

Ниже  показано сообщение oops  для  машины аппаратной платформы РРС,  которое  возникло и  обработчике таймера для  сетевого интерфейсного адаптера tulip.

Oops: Exception in kernel mode, sig: 4

Unable to handle kernel NULL pointer dereference at virtual address 00000001

NIP: C013A7F0 LR: C013A7F0SP:C0685E00 REGS: c0905dl0 TRAP: 0700

Nottainted

MSR: 00089037 ЕЕ: 1 PR: 0 FP: 0 ME: 1 IR/DR: 11

TASK = c0712530[0] swapper Last syscall: 120

GPROO: C013A7C0 C0295E00 C0231530 0000002F 00000001 C0380CB8 C0291B80 C02D0000

GPR08: 000012AO 00000000 00000000 C0292AA0 4020A088 00000000 00000000 00000000

GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

GPR24: 00000000 00000005 00000000 00001032 C3F7C000 00000032 FFFFFFFFC3F7C1C0

Call trace:

[c013ab30] tulip_timer+0xl28/0xlc4 [c0020744] run_timer_softirq+0xl0c/0xl64

[c001b864] do_softirq+0x88/0xl04 [c0007e80] timer_mterrupt+0x284/0x298 [c00033c4] ret_from_except+0x0/0x34 [c0007b84] default_idle+0x20/0x60 [c0007bf8] cpu_idle+0x34/0x38 [c0003ae8] rest_init+0x24/0x34

У пользователей  ПК  может  вызвать  удивление количество  регистров процессора (32  огромное число!).  Сообщение oop s для  аппаратной  платформы  х86, которые возможно вам  более  знакомы, имеют  несколько более  простой вид.  Тем  не  менее, важная информация идентична для  всех аппаратных платформ: содержимое всех регистров  и  обратная трассировка.

Обратная трассировка  показывает  точную   последовательность  вызовов  функций,  которая привела к  проблеме. В данном случае  можно точно  определить, что случилось: машина выполняла холостое задание  холостой цикл:   вызов   функции   cpu_idle( )  , и з которой  циклически   вызывается  функция  default_idle() . Поступил о  прерывани е  от  системног о  таймера ,  в  которо м  вызываютс я  обработчик и  таймеров  ядра.   Среди   них  вызывается  обработчик таймера — функция tulip_timer() , в которой выполнено разыменование указателя со значением NULL. Можно даже  воспользоваться значением смещения  (числа   вроде   0х128/0х1с4, которые  указаны справа  от  имени функции) для  точного нахождения команды,  в  которой  возникла ошибка.

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

из переменных функции содержит не то значение. В ситуациях, похожих  на данную, скорее  всего  причина — конкуренция за ресурс   (race)   и  скорее  всего  между  таймером  и  другой  частью   сетевого адаптера.  Отладка состояний  конкуренции  за  ресурсы — всегда  серьезная задача.

Утилита ksymoops

Только что рассмотренное сообщение oops  имеет  так  называемый  декодированный вид, потому  что  адреса  памяти транслированы в имена  функций,  которые им  соответствуют.   Не  декодированный  вид  предыдущего  сообщения  выглядит следующим образом.

NIP: C013A7F0 LR: C013A7F0 SP: C0685E00 REGS: c0905dl0 TRAP: 0700

Nottainted

MSR: 00089037 ЕЕ: 1 PR: 0 FP: 0 ME 1 IR/DR: 11

TASK = c0712530[0] ‘swapper’ Last syscall: 120

GPROO: C013A7CO C0295E00 C0231530 0000002F 00000001 C0380CB8 C0291B80 C02D0000

GPR08: 000012AO 00000000 00000000 C0292AA0 4020A088 00000000 00000000 00000000

GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

GPR24: 00000000 00000005 00000000 00001032C3F7C00000000032 FFFFFFFF C3F7C1C0

Call trace: [c013ab30] [c0020744] [c001b864] [c0007e80] [c00061c4] [c0007b84][c0007bf8][c0003ae8]

Адреса  обратной  трассировки  должны  быть  переведены  в  символические  имена  функций. Это  можно сделать  с помощью команды ksymoops  при  наличии файла System.map , который сгенерирован во  время  компиляции  данного ядра.  Если  используются загружаемые  модули  ядра, то  необходима также  информация о  модулях. Утилита   ksymoops   пытается самостоятельно  определить всю  необходимую информацию, поэтому обычно ее  можно просто  вызывать следующим образом.

ksymoops saved_oops.txt

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

Программа ksymoops   включена в  большинство поставок операционной  системы

Linux.

Функция  kallsym s

К  счастью,  больше   нет  необходимости  использовать  программу  ksymoops .  Это очень  полезно, потому  что, хотя, у разработчиков обычно нет  проблем с ее использованием,  пользователи часто  указывают неправильный  файл   System.map , или  неправильно декодируют сообщение  oops .

В  разрабатываемой  серии   ядра  2.5  была  введено  новая   возможность  kallsyms , которая включается с помощью конфигурационного  параметра CONFIG_KALLSYMS. Эта  функция  включает в  исполняемый образ  ядра  информацию для  отображения адресов  памяти в  соответствующие имена  функций ядра, что  дает  возможность ядру

самостоятельно декодировать информацию обратной трассировки. Следовательно, декодирование сообщений oops больше  не требует файла  System.map, или утилиты kallsyms .  Как  недостаток такого  подхода  следует  отметить  некоторое увеличение объема  памяти, используемой ядром, так как  таблица перевода адресов  памяти в имена  функций загружается в постоянно отображаемую память  ядра.  На такое  увеличение объемов  используемой памяти стоит пойти, по крайней мере, на этапе  разработки ядра.

Источник: Лав,  Роберт. Разработка ядра  Linux, 2-е  издание. : Пер.  с англ.  — М.  : ООО  «И.Д.  Вильяме» 2006. — 448 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии