Frequently Asked Questions по FreeBSD 2.X : Только для серьёзных FreeBSD хакеров : Что делать при аварийном остановах системы
Previous: Альтернативный метод размещения каталогов
Next: Наши благодарности

13.13. Что делать при аварийном остановах системы

[Этот раздел был вырезан из письма, написанного Биллом Полом (Bill Paul) в список рассылки список рассылки freebsd-current Дэгом-Элингом Коиданом Смёгравом (Dag-Erling Coïdan Smørgrav), который исправил несколько опечаток и добавил комментарии в квадратных скобках]

From: Bill Paul <wpaul@skynet.ctr.columbia.edu>
Subject: Re: the fs fun never stops
To: ben@rosengart.com
Date: Sun, 20 Sep 1998 15:22:50 -0400 (EDT)
Cc: current@FreeBSD.ORG
      

[<ben@rosengart.com> отправил письмо, содержащее следующее аварийное сообщение системы]

> Fatal trap 12: page fault while in kernel mode
> fault virtual address   = 0x40
> fault code              = supervisor read, page not present
> instruction pointer     = 0x8:0xf014a7e5
                                ^^^^^^^^^^
> stack pointer           = 0x10:0xf4ed6f24
> frame pointer           = 0x10:0xf4ed6f28
> code segment            = base 0x0, limit 0xfffff, type 0x1b
>                         = DPL 0, pres 1, def32 1, gran 1
> processor eflags        = interrupt enabled, resume, IOPL = 0
> current process         = 80 (mount)
> interrupt mask          =
> trap number             = 12
> panic: page fault
      

[Если] вы увидите такое сообщение, просто его воспроизвести и послать нам не достаточно. Указатель инструкций, выделенный мною, важен, к сожалению, его значение зависит от конфигурации ядра. Другими словами, его значение меняется в зависимости от конкретного ядра, которое вы используете. Если вы используете ядро GENERIC одного из снэпшотов, то кто-то ещё может отследить функцию, вызвавшую ошибку, но если вы работаете со специально отконфигурированным ядром, то только вы можете сказать нам, где случилась ошибка.

Вот что вы должны сделать:

Зачастую люди приводят подобные аварийные сообщения, на редко кто утруждается привести соотвествие указателя инструкций с функцией в таблице символов ядра.

Лучшим способом выяснить причину, вызвавшую аварийный останов, является создание аварийного дампа системы, а затем использование gdb(1) для трассировки вызовов. Конечно, это зависит от корректности работы gdb(1) с -current, что я гарантировать не могу (помнится, кто-то говорил, что новый ELF gdb(1) некорректно работает с аварийными дампами ядра: необходимо проверить это до выхода 3.0, иначе не избежать краски стыда на наших лицах после выпуска CD).

Во всяком случае, обычно я использую такой способ:

[Замечание: в настоящий момент, в 3.0-BETA, вы должны использовать команду strip -aout -d вместо strip -d]

Заметьте, что ВАМ НЕ НУЖНО ЗАГРУЖАТЬ ЯДРО С ОТЛАДОЧНОЙ ИНФОРМАЦИЕЙ. Ядро, откомпилированное с ключом -g, может занимать порядка 10МБ. Вам не нужно загружать этот огромный образ: он вам пригодится позже для gdb(1)gdb(1) требует таблицу имён). Вместо этого просто сохраните полный образ и создайте ещё один, удалив отладочную информацию командой strip -d. Именно этот образ вам и нужен для загрузки.

Чтобы включить сброс аварийного дампа, вам нужно отредактировать файла /etc/rc.conf, чтобы dumpdev указывало на раздел подкачки. В этом случае скрипты rc(8) будут вызывать команду dumpon(8) для включения создания аварийных дампов. Вы можете запустить команду dumpon(8) вручную. После аварийной остановки аварийный дамп может быть получен с помощью программы savecore(8); если значение переменной dumpdev было установлено в /etc/rc.conf, скрипты rc(8) запустят savecore(8) автоматически и поместят аварийный дамп в каталог /var/crash.

ЗАМЕЧАНИЕ: аварийные дампы FreeBSD обычно имеют размер, равный физическому объёму оперативной памяти вашей машины. Так что если у вас 64МБ ОЗУ, вы получите дамп размером 64МБ. Поэтому вы должны удостовериться, что в каталоге /var/crash достаточно места для хранения дампа. Либо вы можете вручную запустить savecore(8) и создать аварийный дамп в другом каталоге, где достаточно места. Размер аварийного дампа можно уменьшить, указав в конфигурации ядра options MAXMEM=(размер) подходящее значение для объёма памяти, которое будет использоваться ядром. Например, если у вас 128 МБ ОЗУ, вы можете ограничить использование памяти ядром 16 мегабайтами, так что размер аварийного дампа будет равен 16МБ, а не 128.

Как только вы получили аварийный дамп, вы можете выполнить трассировку вызовов с помощью gdb(1) таким образом:

% gdb -k /sys/compile/KERNELCONFIG/kernel.debug /var/crash/vmcore.0
(gdb) where
      

Заметьте, что при этом может быть выведено несколько экранов информации; в идеале вы должны использовать script(1) для их перехвата. При использовании необработанного образа ядра со всей отладочной информацией может быть найдена конкретная строка исходного текста ядра, при достижении которой случилась аварийная остановка. Для выяснения последовательности событий, приведших к аварийному останову, обычно читается трассировка стека снизу вверх. Вы можете также использовать gdb(1) для вывода значений различных переменных или структур, чтобы выяснить состояние системы во время аварии.

Теперь, если вы в самом деле душевнобольной и у вас есть второй компьютер, то можете настроить gdb(1) для удалённой отладки, так, что сможете использовать gdb(1) на одном компьютере, чтобы отладить ядро на другом, включая использование точек останова, пошагового прохода по коду ядра, всё как с обычной прикладной программой. Я пока с этим не игрался, так как не часто имею возможность поставить две машины одну напротив другой для отладки.

[Билл (Bill) добавил: "Я забыл обратить ваше внимание на одну вещь: если у вас включена поддержка DDB и ядро переходит в режим отладки, вы можете намеренно вызвать аварийный останов (и создание аварийного дампа), набрав 'panic' в командной строке ddb. Этот процесс может снова вызвать отладчик. В этом случае наберите 'continue' и процесс будет завершён созданием аварийного дампа."]


Frequently Asked Questions по FreeBSD 2.X : Только для серьёзных FreeBSD хакеров : Что делать при аварийном остановах системы
Previous: Альтернативный метод размещения каталогов
Next: Наши благодарности