Отладка ядра windows что. Принцип работы отладчика ядра операционной системы

Отладчики режима ядра находятся между CPU и операционной системой. Это означает, что, когда вы останавливаете отладчик режима ядра, операционная система также полностью останавливается. Нетрудно сообразить, что переход операционной системы к резкому останову полезен, когда вы работаете с таймером и над проблемами синхронизации. Все-таки, за исключением одного отладчика, о котором будет рассказано ниже (в разделе "Отладчик SoftlCE" данной главы), нельзя отлаживать код пользовательского режима с помощью отладчиков режима ядра.

Отладчиков режима ядра не так много. Вот некоторые из них: Windows 80386 Debugger (WDEB386), Kernel Debugger (1386KD), WinDBG и SoftlCE. Каждый из этих отладчиков кратко описан в следующих разделах.

Отладчик WDEB386

WDEB386 - это отладчик режима ядра Windows 98, распространяемый в составе Platform SDK. Этот отладчик полезен только для разработчиков, пишущих драйверы виртуальных устройств Windows 98 (VxD). Подобно большинству отладчиков режима ядра для операционных систем Windows, отладчик WDEB386 требует для работы две машины и нуль-модемный кабель. Две машины необходимы потому, что часть отладчика, которая выполняется на целевой машине, имеет ограниченный доступ к ее аппаратным средствам, так что он посылает свой вывод и получает команды от другой машины.

Отладчик WDEB386 имеет интересную историю. Он начинался как внутренний фоновый инструмент Microsoft в эпоху Windows 3.0. Его было трудно использовать, и он не имел достаточной поддержки для отладки исходного кода и других приятных свойств, которыми нас испортили отладчики Visual C++ и Visual Basic.

"Точечные" (DOT) команды - наиболее важная особенность WDEB386. Через прерывание INT 41 можно расширять WDEB386 с целью добавления команд. Эта расширяемость позволяет авторам VxD-драйверов создавать заказные отладочные команды, которые дают им свободный доступ к информации в их виртуальных устройствах. Отладочная версия Windows 98 поддерживает множество DOT-команд, которые позволяют наблюдать точное состояние операционной системы в любой точке процесса отладки.

Отладчик I386KD

Windows 2000 отличается от Windows 98 тем, что реально действующая часть отладчика режима ядра является частьюNTOSKRNL. EXE - файла главного ядра операционной системы Windows 2000. Этот отладчик доступен как в свободных (выпускных), так и в проверенных (отладочных) конфигурациях операционной системы. Чтобы включить отладку в режиме ядра, установите параметр загрузчика /DEBUG в BOOT. INI и, дополнительно, опцию загрузчика /DEBUGPORT, если необходимо установить значение коммуникационного порта отладчика режима ядра, отличающееся от умалчиваемого (СОМ1). I386KD выполняется на своей собственной машине и сообщается с машиной Windows 2000 через кабель нуль-модема.

Отладчик режима ядра NTOSKRNL. EXE делает только то, что достаточно для управления CPU, так чтобы операционная система могла быть отлажена. Большая часть отладочной работы - обработка символов, расширенные точки прерывания и дизассемблирование - выполняется на стороне 1386KD. Одно время Windows NT 4 Device Driver Kit (DDK) документировал протокол, используемый в кабеле нуль-модема. Однако Microsoft больше его не документирует.

Мощь 1386KD очевидна, если посмотреть на все команды, которые он предлагает для доступа к внутреннему состоянию Windows 2000. Знание механизма работы драйверов устройств в Windows 2000 поможет программисту следить за выводом многих команд. Не смотря на всю свою мощь, i386KD почти никогда не применяется, потому что это консольное приложение, которое очень утомительно использовать для отладок исходного уровня.

Для проведения отладки ядра необходимо подключиться к компьютеру с помощью нуль-модемного кабеля или модемного соединения. Компьютер, выполняющий отладку, будет называться “Host”, а название “Target” получит проблемный компьютер.

Оба компьютера должны работать под управлением одной и той же версии Windows, а символьные файлы для компьютера Target должны быть установлены на компьютере Host. Символьные файлы предоставляются на установочном компакт-диске Windows в каталоге Support\Debug.

Для включения отладки необходимо внести изменения в файл BOOT.INI на компьютере Target.

1. Поменяйте атрибуты файла BOOT.INI:

attrib c:\boot.ini – r – s

2. Отредактируйте этот файл и в строку запуска Windows добавьте параметр /debug (для того, чтобы сообщить системе о необходимости загрузки в оперативную память отладчика ядра при загрузке Windows). Дополнительными параметрами являются /Debugport, сообщающий системе, какой порт COM необходимо использовать (по умолчанию COM2) и /Baudrate - для указания скорости передачи данных (по умолчанию указана скорость 19200 бод, но лучше использовать 9600). Например:


multi(0)disk(0)rdisk(0)partition(0)\WINDOWS="Windows NT" /debug /debugport=com2 /baudrate=9600

3. Сохраните файл.

4. Установите предыдущие атрибуты файла BOOT.INI:

attrib c:\boot.ini +r +s

В данном примере компьютер Target разрешил соединение через порт COM2 со скоростью 9600 бит/с.

Компьютер Host должен быть настроен с использованием параметров, необходимых для проведения отладки. Кроме того, должны быть установлены символьные файлы. Для их установки перейдите в каталог \support\debug на установочном компакт-диске и введите следующую команду:

expndsym : <целевой диск и каталог>

Например:

expndsym f: d:\symbols

Установка может занять некоторое время. Помните, что если на компьютер Target были установлены пакеты обновлений, символьные файлы этих пакетов также следует установить на компьютер Host. Символьные файлы для пакетов обновлений можно загрузить с сайтега компании Microsoft.

Следующей стадией является настройка переменных окружения, необходимых для отладки, например, переменных, указывающих расположение символьных файлов и т.д. Далее представлено описание этих переменных.

Описание системных переменных

Определение этих переменных можно разместить в командном файле для того, чтобы избежать ввода соответствующих команд при каждой загрузке:

echo off
set _nt_debug_port=com2
set _nt_debug_baud_rate=9600
set _nt_symbol_path=d:\symbols\i386
set _nt_log_file_open=d:\debug\logs\debug.log

Теперь необходимо скопировать программное обеспечение отладки ядра, которое расположено в каталоге support\debug\<процессор> на установочном компакт-диске (support\debug\I386). Проще всего скопировать весь каталог полностью, поскольку он имеет небольшой размер (около 2,5 Мбайт). Для платформы I386 используется отладчик, который поставляется в виде файла I386KD.EXE. Отладчик запускается с помощью команды I386KD. Для ввода команды нажмите комбинацию клавиш и подождите, пока появится приглашение командной строки kd>.

Достойных отладчиков ядерного уровня и под Windows немного, а в Linux их можно пересчитать по пальцам одной руки, да и те большей частью сырые, недоделанные или же заброшенные и мхом заросшие… Сегодня мы поговорим о самом популярном и наиболее интересном из них -
Linice .

Введение

Как уже можно догадаться по названию, Linice – это неофициальный «порт» легендарного
SoftICE под Linux , сохранивший интерфейс, систему команд и большинство возможностей последнего: всплытие по горячей клавишеLinice это ); установка аппаратных точек останова на все функции и системные вызовы; просмотр GDT/LDT/IDT, физических страниц памяти; возможности, позаимствованные из GDB (вызов произвольной функции командой CALL, сохранение/восстановление контекста регистров, внутренние переменные и т.д.).

В отличие от большинства других отладчиков, работающих через нереентерабельный и легко обнаруживаемый защитами механизм ptrace (Windows-аналогом которого является DEBUG_PROCESS, используемый прикладными отладчиками), Linice использует нативную трассировку, такую же, как в SoftICE, что позволяет обоим отладчикам отлаживать круто защищенные программы, с которыми другие уже не справляются.

На самом деле, это никакой не порт (отсюда и кавычки), а независимый проект, написанный с нуля и распространяющийся в исходных текстах на бесплатной основе (от SoftICE там только вдохновение). Основная часть кода, предназначенная для ядра 2.4, была написана немецким хакером Гораном Девиком, однако поддержкой ядра 2.6 занимались уже совсем другие люди: Daniel Reznick, Peter K. и Carlos Manuel Duclos Vergara. А наш соотечественник - Олег Худаков - переписал ассемблерные файлы с nasm"а на
gcc.

Исходные тексты лежат на официальном сайте проекта -
Linice%0A.com">www.Linice.com , там же находится документация, короткий FAQ и ссылка на форум
Linice%0A">groups.google.com/group/Linice . Готовые бинарные сборки отсутствуют.
Создатели проекта открыли свой собственный аккаунт на SourceForge, но поленились выложить на него какие бы то ни было файлы, представив на обозрение всего лишь 3 screenshot"а весьма низкого качества:
.

Системные требования

Последняя версия Linice носит номер 2.6 и датируется 28 июлем 2005 года, полностью поддерживая ядро 2.4.x и консольный VGA-режим. С более новыми ядрами наблюдаются серьезные проблемы, и ядро 2.6.x поддерживается лишь в ограниченном режиме.
Отладчик разрабатывался и тестировался под Debian 2.6. Его совместимость с остальными дистрибутивами не гарантируется, что вынуждает нас прибегать к бубну, но в некоторых случаях не помогает и бубен. Вообще-то, держать на своей машине Debian только для того, чтобы работать с Linice , – это вполне нормально. Давным-давно, когда реализации SoftICE для NT еще не существовало, многие хакеры инсталлировали Win 9x только для того, чтобы ломать программы, хотя сами сидели под
NT. Поскольку охватить все тонкости установки Linice в рамках одной статьи практически не реально, я ограничусь описанием процесса компиляции и запуска Linice под одним конкретным дистрибутивом - Knoppix 3.7 с ядром 2.4.1 в консольном VGA-режиме.
Linice поддерживает ACPI и многопроцессорные машины, но плохо дружит с X"ми, особенно на видеокартах, отличных от nVidia. 24-битную глубину цветности он вообще не воспринимает, «переваривая» только 8, 16 и 32 бита, поэтому отладку X-приложений удобнее вести через удаленный терминал, подключенный через COM-порт по протоколу VT100. При этом локальная клавиатура также будет работать с
Linice !

Компиляция и конфигурирование Linice

Скачиваем gzip-архив исходных текстов www.Linice .devic.us/Linice -2.6.tar.gz, занимающий чуть меньше мегабайта, распаковываем его на диск, заходим в каталог./docs и из файла readme узнаем, что сборка отладчика под ядро 2.4 осуществляется так:

# cd build
# ./make_bin-2.4
# cd ../bin
# make clean; mak e

Однако перед запуском make необходимо открыть файл./bin-2.4/Makefile и отредактировать строку «TARGET» в соответствии с конфигурацией и архитектурой целевой платформы. В частности, на ACPI-машинах с многоядерными или HyperThreading-процессорами она будет выглядеть так:

TARGET = -DSMP -DIO_APIC

После завершения компиляции в каталоге./bin появится множество файлов и каталогов, но значимыми из них являются только:

linsym – загрузочный модуль отладчика;
linince.dat – файл конфигурации;
xice – поддержка X"ов, при работе в текстовом режиме его можно удалить;
./Linice_2.4.27/Linice.o – загружаемый модуль ядра, содержащий непосредственно сам отладчик.

Процесс сборки Linice

Собрав минимально работающий комплект, неплохо бы получить и все остальное - демонстрационные отладочные примеры, находящиеся в каталоге./test и компилируемые скриптом compile, а также модуль расширения (по-нашему, плагин), лежащий в каталоге./ext, собираемый командой make и загружаемый командой insmod. Никакой пользы от него нет, но, изучив исходный текст, мы сможем писать свои собственные модули, расширяющие функциональность
Linice .

При загрузке Knoppix"а в нижней строке экрана появляется приглашение «boot:» где необходимо ввести «knoppix 2 vga=normal». Cheat-код «knoppix» выбирает ядро 2.4 (автоматически загружаемое по умолчанию, поэтому «knoppix» можно опустить), «2» блокирует загрузку X"ов, а «vga=normal» устанавливает стандартный vga-режим с разрешением 80x25.

Дождавшись завершения загрузки, говорим «su», затем «passwd» и вводим новый пароль для root"a, под которым тут же заходим в систему, воспользовавшись командой login. Если этого не сделать, попытка запуска Linice закончится сокрушительным провалом с воплем «segmentation fault».

При загрузке Knoppix"а с жесткого диска (на который его можно установить командой «sudo knoppix-installer», набранной в окне терминала из-под LiveCD-сессии) появится стартовое меню со списком доступных ядер. Выбираем Linux(2.4)-1 и нажимаем для задания параметров загрузки - «2 vga=normal». Слово «knoppix» писать не нужно, поскольку ядро уже и так выбрано. После завершения загрузки даем команду login и входим в систему под root"ом (предполагается, что аккаунт был создан ранее).

Запуск отладчика осуществляется командой./linsym –i, после чего тот немедленно появляется на экране. Если же этого не происходит, попробуй указать ключ "--verbose 3" для вывода диагностических сообщений.
Одной из причин отказа в загрузке может быть отсутствие файла /boot/System.map, содержащего адреса ядерных функций. Загрузка провалится и в том случае, если содержимое System.map не соответствует текущему ядру, что может произойти, например, при его рекомпиляции. Некоторые составители дистрибутивов либо вообще не включают System.map (полагая, что это усилит безопасность системы, так как rootkit"ам будет сложнее осуществить перехват syscall"ов), либо помещают сюда что-то совершенно левое и вообще непонятно откуда взявшееся. В таких случаях достаточно просто перекомпилировать ядро, указав отладчику путь к файлу System.map с помощью ключа "-m", если он расположен не в /boot, а где-нибудь в другом месте. Таким образом, и безопасность не пострадает, и Linice сможет работать!
Возврат из отладчика в систему происходит по или с помощью команды «x ». Комбинация вызывает отладчик из любой программы. Однако вовсе не факт, что мы очутимся в ее контексте, ведь Linux - многозадачная система, переключающая процессы один за другим, а команды ADDR (переключающей контексты) в «лексиконе» Linice все еще не существует, и когда она появится - неизвестно. Поэтому приходится хитрить, устанавливая точки останова на системные вызовы, используемые конкретной программой, или врываясь в процесс по методу INT 03h, о чем мы сейчас и поговорим.

За выгрузку отладчика (если его действительно хочется выгрузить) отвечает ключ "-x", переданный все тому же linsym"у.

Основы работы с Linice

Для тех, кто уже работал с SoftICE, освоение Linice не представит никакой проблемы. Здесь используются все те же команды: D – дамп памяти, E – редактирование памяти, T – пошаговая трассировка, P – трассировка без захода в функции, R – просмотр/модификация регистров, BPM/BPX – установка точки останова на доступ/исполнение памяти и т.д. Полный перечень команд содержится как во встроенной справке, вызываемой по HELP (кстати, «HELP имя_команды» выдает дополнительную информацию по команде), так и в штатной документации.

Давай нажмем и пороемся в списке процессов, выводимых на экран командой PROC, причем текущий процесс выделяется голубым цветом:

:PROC

1 0000 C1C3E000 SLEEPING 0 0 init
2 0000 F7EE8000 SLEEPING 0 0 keventd
3 0000 F7EE2000 SLEEPING 0 0 ksoftirqd_CPU0
4 0000 F7EE0000 SLEEPING 0 0 ksoftirqd_CPU1
5 0000 F7ED0000 SLEEPING 0 0 kswapd
6 0000 F7EAA000 SLEEPING 0 0 bdflush
7 0000 F7EA8000 SLEEPING 0 0 kupdated
56 0000 F6A36000 SLEEPING 0 0 kjournald
1006 0000 F7A34000 RUNNING 0 0 automount
1013 0000 F68E6000 SLEEPING 0 0 cupsd
...
1105 0000 F6DDE000 SLEEPING 0 0 mc
1106 0000 F6DD4000 SLEEPING 0 0 cons.saver

Процессы - это, конечно, хорошо, но как же все-таки нам отлаживать программы? Самое простое – воткнуть в точку входа машинную команду CCh, соответствующую инструкции INT 03h, предварительно записав содержимое оригинального байта. Это можно сделать любым hex-редактором, например, неоднократно упоминаемым мной
HTE.

Загрузив файл в редактор, нажимаем (mode), выбираем elf/image, подгоняем курсор к «entrypoint:», давим (edit) и изменяем первый байт на CCh, сохраняем изменения по (save) и выходим. При запуске пропатченной программы Linice немедленно всплывает, потревоженный исключением, сгенерированным CCh, после которого EIP указывает на конец
CCh.

Состояние программы c пропатченной точкой входа в момент всплытия отладчика

0023:080482C0 CC int 3
0023:080482C1 ED in eax, dx
0023:080482C2 5E pop esi
0023:080482C3 89E1 mov ecx, esp

Курсор указывает на инструкцию in eax,dx (EDh), представляющую собой осколок от пропатченной команды xor ebp,ebp (31h EDh). Теперь (по идее) мы должны восстановить оригинальный байт, поменяв CCh на 31h, уменьшить регистр EIP на единицу и продолжить трассировку в обычном режиме.

Да вот не тут-то было! Linice - это, конечно, порт, но только очень сырой, и модифицировать память страничного имиджа он не умеет, даже если предварительно открыть кодовый сегмент на запись. Ни E (редактирование), ни F (заполнение), ни M (копирование памяти) не работают! Зато работает запись в стек, и нам, хакерам, этого вполне достаточно.

Запоминаем текущее значение регистра EIP; копируем пропатченную машинную команду на вершину стека; восстанавливаем там байт CCh; передаем на нее управление, меняя значение EIP; выполняем ее, совершив единичный акт трассировки; и возвращаем EIP на место, то есть на следующую машинную команду:

Восстановление оригинального байта, замененного инструкцией INT 03h

; Смотрим, что находится на вершине стека (из чистого любопытства).
:d esp-10
0018:BFFFEFC0 C0 82 04 08 00 00 00 00 5D 0C 00 40 DC EF FF BF

; Копируем пропатченную машинную команду на вершину стека.
; Число 10h - максимально возможный размер машинной команды на x86.
:m eip-1 L 10 esp-10

; Смотрим, как изменился стек.
:d esp-10
0018:BFFFEFC0 CC ED 5E 89 E1 83 E4 F0 50 54 52 68 F0 85 04 08

; Ага! Стек действительно изменился, самое время исправлять CCh на 31h.
:e esp-10 31
Edit immediate data not implemented yet.

; Упс! Непосредственное присвоение данных в Linice не реализовано,
; но мы можем отредактировать дамп в интерактивном режиме (так же,
; как в SoftICE) или дать команду F esp-10 L 1 31, только учти,
; что, в отличие от SoftICE, отладчик Linice не обновляет окно дампа,
; поэтому после выполнения команды F может показаться, что
; результата нет; на самом деле, это не так, стоит только обновить
; дамп командой D esp-10, и все встанет на свои места.

; Передаем управление на команду, скопированную в стек,
; запоминаем значение регистра EIP.
:r eip (esp-10)
reg: eip = BFFFEFC0

; Совершаем единичный акт трассировки.
:t
0023:BFFFEFC2 5E pop esi

; Как мы видим, регистр EIP увеличился на 2 (BFFFEFC2h - BFFFEFC0h) = 02h,
; следовательно, адрес следующей команды равен: 080482C1h - 01h + 02h = 080482C2h,
; где 080482C1h - начальное значение EIP при входе в программу, а 01h - размер INT 03h.

; Устанавливаем EIP на команду, следующую за пропатченной инструкцией.
:r eip 80482C2
reg: eip = 80482C2

Вот такие пляски с бубном приходится устраивать. А что поделать? Так, с загрузкой программ в отладчик мы разобрались, теперь растерзаем точки останова на системные вызовы и ядерные функции.

Команда exp выводит имена, экспортируемые ядром, любое из которых может фигурировать в выражениях, например, «bpx do_bkr» эквивалентно «bpx C012C9E8».

Вывод имен, экспортируемых ядром

:exp
kernel
C0320364 mmu_cr4_features
C02AC3A4 acpi_disabled
C02AC8A0 i8253_lock
...
C012BDA8 do_mmap_pgoff
C012C764 do_munmap
C012C9E8 do_brk
C011E990 exit_mm
C011E69C exit_files

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

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

Таблица системных вызовов

; Переводим отладчик в режим отображения двойных слов.
:dd

; Выводим таблицу на экран.
:d sys_call_table
0018:C02AB6A8 C0126ACC F8932650 F89326A0 C013DC10
0018:C02AB6B8 C013DD18 C013D5C8 C013D724 C011F3BC
0018:C02AB6C8 C013D664 C014A8E0 C014A3B4 F893020C

Каждый элемент таблицы соответствует своему системному вызову, а каждый вызов имеет свой номер, который можно узнать, заглянув в файл /usr/include/sys/syscall.h, но лучше это делать не под Linux, где никаких непосредственных номеров нет, а позаимствовать тот же самый файл из BSD – все равно номера основных системных вызовов на всех системах совпадают. В частности, системный вызов open проходит под номером 5.

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

Установка точки останова на системный вызов open

; Устанавливаем точку останова на системный вызов open,
:bpx C013D5C8
; выходим из отладчика,
:x
...
# открываем какой-нибудь файл,
...
; отладчик тут же всплывает, сообщая нам об этом,
:Breakpoint due to BPX 01

; даем команду proc, чтобы убедиться, что мы вклинились в свой процесс.
:proс
PID TSS Task state uid gid name
1049 0000 F6364000 SLEEPING 0 0 getty
1145 0000 F61CC000 SLEEPING 0 0 mc
1146 0000 F614A000 SLEEPING 0 0 cons.saver

Таким путем легко вклиниваться в уже запущенные процессы, устанавливая точки останова на используемые ими системные вызовы, а также совершать множество других вещей, жизненно важных для взлома.

Заключение

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

Иногда у меня возникает ситуация, когда Windows ожидает время загрузки для отладчика ядра. Вы видите текст «Windows start», но не логотип.

Если я присоединяю отладчик сейчас, воспроизводится анимация логотипа Windows 7. После этого логотип начинает пульсировать. На этом этапе процесс загрузки больше не продвигается. Загрузка процессора снижается до минимума. Я жду обычно несколько минут, но ничего не происходит.

Это происходит не всегда. Однако, если это произойдет, сброс VM не поможет. Для устранения этой проблемы мне нужно использовать ремонт при запуске. К сожалению, это длится вечно.

Любые идеи, что я могу сделать, кроме запуска ремонта при запуске?

Заранее спасибо!

3

2 ответы

Чтобы устранить проблему, с которой вы столкнулись, достаточно просто нажать F10 во время загрузки. И удалить/отладить и связанные параметры. Затем нажмите enter.

Предложение: Не используйте параметр/debug для параметра меню загрузки по умолчанию. Скопируйте конфигурацию загрузки в новую запись. Затем установите его в режим отладки. Windows не знает, когда вы будете использовать отладчик. Поэтому он должен ждать.

чПФ ОЕЛПФПТЩЕ ХЛБЪБОЙС РП ТБВПФЕ У ПФМБДЛПК СДТБ У БЧБТЙКОЩНЙ ДБНРБНЙ РБНСФЙ. лБЛ РТБЧЙМП, ЧБН ОХЦОП ВХДЕФ ЪБДБФШ ПДОП ЙЪ ХУФТПКУФЧ РПДЛБЮЛЙ, РЕТЕЮЙУМЕООЩИ Ч ЖБКМЕ /etc/fstab . уВТПУ ПВТБЪПЧ РБНСФЙ ОБ ХУФТПКУФЧБ, ОЕ СЧМСАЭЙЕУС ХУФТПКУФЧБНЙ РПДЛБЮЛЙ, ОБРТЙНЕТ, МЕОФЩ, Ч ДБООЩК НПНЕОФ ОЕ РПДДЕТЦЙЧБАФУС.

Note: йУРПМШЪХКФЕ ЛПНБОДХ dumpon (8) ДМС ХЛБЪБОЙС СДТХ НЕУФБ, ЗДЕ ОХЦОП УПИТБОСФШ БЧБТЙКОЩЕ ДБНРЩ. рПУМЕ ОБУФТПКЛЙ РП ЛПНБОДЕ swapon (8) ТБЪДЕМБ РПДЛБЮЛЙ ДПМЦОБ ВЩФШ ЧЩЪЧБОБ РТПЗТБННБ dumpon . пВЩЮОП ЬФП ЧЩРПМОСЕФУС ЪБДБОЙЕН РЕТЕНЕООПК dumpdev Ч ЖБКМЕ rc.conf (5) . еУМЙ ЪБДБОБ ЬФБ РЕТЕНЕООБС, ФП РПУМЕ УВПС РТЙ РЕТЧПК НОПЗПРПМШЪПЧБФЕМШУЛПК РЕТЕЪБЗТХЪЛЕ ВХДЕФ БЧФПНБФЙЮЕУЛЙ ЪБРХЭЕОБ РТПЗТБННБ savecore (8) . пОБ УПИТБОЙФ БЧБТЙКОЩК ДБНР СДТБ Ч ЛБФБМПЗ, ЪБДБООЩК Ч РЕТЕНЕООПК dumpdir ЖБКМБ rc.conf . рП ХНПМЮБОЙА ЛБФБМПЗПН ДМС БЧБТЙКОЩИ ДБНРПЧ СЧМСЕФУС /var/crash .

мЙВП ЧЩ НПЦЕФЕ ЪБДБФШ ХУФТПКУФЧП ДМС УВТПУБ ПВТБЪБ РБНСФЙ СЧОП ЮЕТЕЪ РБТБНЕФТ dump Ч УФТПЛЕ config ЛПОЖЙЗХТБГЙПООПЗП ЖБКМБ ЧБЫЕЗП СДТБ. фБЛПК УРПУПВ ЙУРПМШЪПЧБФШ ОЕ ТЕЛПНЕОДХЕФУС Й ПО ДПМЦЕО ЙУРПМШЪПЧБФШУС, ФПМШЛП ЕУМЙ ЧЩ ИПФЙФЕ РПМХЮБФШ БЧБТЙКОЩЕ ПВТБЪЩ РБНСФЙ СДТБ, ЛПФПТПЕ БЧБТЙКОП ЪБЧЕТЫБЕФ УЧПА ТБВПФХ РТЙ ЪБЗТХЪЛЕ.

Note: дБМЕЕ ФЕТНЙО gdb ПЪОБЮБЕФ ПФМБДЮЙЛ gdb , ЪБРХЭЕООЩК Ч ``ТЕЦЙНЕ ПФМБДЛЙ СДТБ"". рЕТЕИПД Ч ЬФПФ ТЕЦЙН ДПУФЙЗБЕФУС ЪБРХУЛПН gdb У РБТБНЕФТПН -k . ч ТЕЦЙНЕ ПФМБДЛЙ СДТБ gdb ЙЪНЕОСЕФ УЧПЈ РТЙЗМБЫЕОЙЕ ОБ (kgdb) .

Tip: еУМЙ ЧЩ ЙУРПМШЪХЕФЕ FreeBSD ЧЕТУЙЙ 3 ЙМЙ ВПМЕЕ ТБООАА, ЧЩ ДПМЦОЩ ЧЩРПМОЙФШ ХУЕЮЕОЙЕ ПФМБДПЮОПЗП СДТБ ЛПНБОДПК strip, Б ОЕ ХУФБОБЧМЙЧБФШ ВПМШЫПЕ ПФМБДПЮОПЕ СДТП:

# cp kernel kernel.debug # strip -g kernel

ьФПФ ЫБЗ ОЕ ФБЛ ХЦ Й ОЕПВИПДЙН, ОП ТЕЛПНЕОДХЕН. (чП FreeBSD 4 Й ВПМЕЕ РПЪДОЙИ ТЕМЙЪБИ ЬФПФ ЫБЗ ЧЩРПМОСЕФУС БЧФПНБФЙЮЕУЛЙ Ч ЛПОГЕ РТПГЕУУБ РПУФТПЕОЙС СДТБ make .) лПЗДБ СДТП ХУЕЮЕОП, БЧФПНБФЙЮЕУЛЙ ЙМЙ РТЙ РПНПЭЙ ЛПНБОД ЧЩЫЕ, ЧЩ НПЦЕФЕ ХУФБОПЧЙФШ ЕЗП ПВЩЮОЩН ПВТБЪПН, ОБВТБЧ make install .

ъБНЕФШФЕ, ЮФП Ч УФБТЩИ ЧЕТУЙСИ FreeBSD (ДП 3.1, ОЕ ЧЛМАЮБС ЬФПФ ТЕМЙЪ), ЙУРПМШЪХЕФУС СДТБ Ч ЖПТНБФЕ a.out, РПЬФПНХ ЙИ ФБВМЙГЩ УЙНЧПМПЧ ДПМЦОЩ ТБУРПМБЗБФШУС РПУФПСООП Ч РБНСФЙ. у ВПМШЫПК ФБВМЙГЕК УЙНЧПМПЧ Ч ОЕ ХУЕЮЕООПН ПФМБДПЮОПН СДТЕ ЬФП ЙЪМЙЫОСС ФТБФБ. рПУМЕДОЙЕ ТЕМЙЪЩ FreeBSD ЙУРПМШЪХАФ СДТБ Ч ЖПТНБФЕ ELF, ЗДЕ ЬФП ОЕ СЧМСЕФУС РТПВМЕНПК.

еУМЙ ЧЩ ФЕУФЙТХЕФЕ ОПЧПЕ СДТП, УЛБЦЕН, ОБВЙТБС ЙНС ОПЧПЗП СДТБ Ч РТЙЗМБЫЕОЙЙ ЪБЗТХЪЮЙЛБ, ОП ЧБН ОХЦОП ЪБЗТХЦБФШ Й ТБВПФБФШ У ДТХЗЙН СДТПН, ЮФПВЩ УОПЧБ ЧЕТОХФШУС Л ОПТНБМШОПНХ ЖХОЛГЙПОЙТПЧБОЙА, ЪБЗТХЦБКФЕ ЕЗП ФПМШЛП Ч ПДОПРПМШЪПЧБФЕМШУЛПН ТЕЦЙНЕ РТЙ РПНПЭЙ ЖМБЗБ -s , ХЛБЪЩЧБЕНПЗП РТЙ ЪБЗТХЪЛЕ, Б ЪБФЕН ЧЩРПМОЙФЕ ФБЛЙЕ ЫБЗЙ:

# fsck -p # mount -a -t ufs # so your filesystem for /var/crash is writable # savecore -N /kernel.panicked /var/crash # exit # ...to multi-user

ьФБ РПУМЕДПЧБФЕМШОПУФШ ХЛБЪЩЧБЕФ РТПЗТБННЕ savecore (8) ОБ ЙУРПМШЪПЧБОЙЕ ДТХЗПЗП СДТБ ДМС ЙЪЧМЕЮЕОЙС УЙНЧПМЙЮЕУЛЙИ ЙНЕО. йОБЮЕ ПОБ ВХДЕФ ЙУРПМШЪПЧБФШ СДТП, ТБВПФБАЭЕЕ Ч ДБООЩК НПНЕОФ Й, УЛПТЕЕ ЧУЕЗП, ОЙЮЕЗП ОЕ УДЕМБЕФ, РПФПНХ ЮФП БЧБТЙКОЩК ПВТБЪ РБНСФЙ Й УЙНЧПМЩ СДТБ ВХДХФ ПФМЙЮБФШУС.

б ФЕРЕТШ, РПУМЕ УВТПУБ БЧБТЙКОПЗП ДБНРБ, РЕТЕКДЙФЕ Ч ЛБФБМПЗ /sys/compile/WHATEVER Й ЪБРХУФЙФЕ ЛПНБОДХ gdb -k . йЪ РТПЗТБННЩ gdb УДЕМБКФЕ ЧПФ ЮФП:

Symbol-file kernel.debug exec-file /var/crash/kernel.0 core-file /var/crash/vmcore.0 Й ЧХБМС - ЧЩ НПЦЕФЕ ПФМБЦЙЧБФШ БЧБТЙКОЩК ДБНР, ЙУРПМШЪХС ЙУИПДОЩЕ ФЕЛУФЩ СДТБ ФПЮОП ФБЛЦЕ, ЛБЛ ЧЩ ЬФП ДЕМБЕФЕ У МАВПК ДТХЗПК РТПЗТБННПК.

чПФ ЦХТОБМ ЛПНБОД УЕБОУБ ТБВПФЩ gdb , ЙММАУФТЙТХАЭЙК ЬФХ РТПГЕДХТХ. дМЙООЩЕ УФТПЛЙ ВЩМЙ ТБЪПТЧБОЩ ДМС ХМХЮЫЕОЙС ЮЙФБВЕМШОПУФЙ Й ДМС ХДПВУФЧБ УФТПЛЙ ВЩМЙ РТПОХНЕТПЧБОЩ. чУЕ ПУФБМШОПЕ СЧМСЕФУС ФТБУУЙТПЧЛПК ПЫЙВЛЙ, ТЕБМШОП ЧПЪОЙЛОХЧЫЕК ЧП ЧТЕНС ТБВПФЩ ОБД ДТБКЧЕТПН ЛПОУПМЙ pcvt.

1:Script started on Fri Dec 30 23:15:22 1994 2: # cd /sys/compile/URIAH 3: # gdb -k kernel /var/crash/vmcore.1 4:Reading symbol data from /usr/src/sys/compile/URIAH/kernel ...done. 5:IdlePTD 1f3000 6:panic: because you said to! 7:current pcb at 1e3f70 8:Reading in symbols for ../../i386/i386/machdep.c...done. 9: (kgdb) where 10:#0 boot (arghowto=256) (../../i386/i386/machdep.c line 767) 11:#1 0xf0115159 in panic () 12:#2 0xf01955bd in diediedie () (../../i386/i386/machdep.c line 698) 13:#3 0xf010185e in db_fncall () 14:#4 0xf0101586 in db_command (-266509132, -266509516, -267381073) 15:#5 0xf0101711 in db_command_loop () 16:#6 0xf01040a0 in db_trap () 17:#7 0xf0192976 in kdb_trap (12, 0, -272630436, -266743723) 18:#8 0xf019d2eb in trap_fatal (...) 19:#9 0xf019ce60 in trap_pfault (...) 20:#10 0xf019cb2f in trap (...) 21:#11 0xf01932a1 in exception:calltrap () 22:#12 0xf0191503 in cnopen (...) 23:#13 0xf0132c34 in spec_open () 24:#14 0xf012d014 in vn_open () 25:#15 0xf012a183 in open () 26:#16 0xf019d4eb in syscall (...) 27: (kgdb) up 10 28:Reading in symbols for ../../i386/i386/trap.c...done. 29:#10 0xf019cb2f in trap (frame={tf_es = -260440048, tf_ds = 16, tf_\ 30:edi = 3072, tf_esi = -266445372, tf_ebp = -272630356, tf_isp = -27\ 31:2630396, tf_ebx = -266427884, tf_edx = 12, tf_ecx = -266427884, tf\ 32:_eax = 64772224, tf_trapno = 12, tf_err = -272695296, tf_eip = -26\ 33:6672343, tf_cs = -266469368, tf_eflags = 66066, tf_esp = 3072, tf_\ 34:ss = -266427884}) (../../i386/i386/trap.c line 283) 35:283 (void) trap_pfault(&frame, FALSE); 36: (kgdb) frame frame->tf_ebp frame->tf_eip 37:Reading in symbols for ../../i386/isa/pcvt/pcvt_drv.c...done. 38:#0 0xf01ae729 in pcopen (dev=3072, flag=3, mode=8192, p=(struct p\ 39:roc *) 0xf07c0c00) (../../i386/isa/pcvt/pcvt_drv.c line 403) 40:403 return ((*linesw.l_open)(dev, tp)); 41: (kgdb) list 42:398 43:399 tp->t_state |= TS_CARR_ON; 44:400 tp->t_cflag |= CLOCAL; /* cannot be a modem (:-) */ 45:401 46:402 #if PCVT_NETBSD || (PCVT_FREEBSD >= 200) 47:403 return ((*linesw.l_open)(dev, tp)); 48:404 #else 49:405 return ((*linesw.l_open)(dev, tp, flag)); 50:406 #endif /* PCVT_NETBSD || (PCVT_FREEBSD >= 200) */ 51:407 } 52: (kgdb) print tp 53:Reading in symbols for ../../i386/i386/cons.c...done. 54:$1 = (struct tty *) 0x1bae 55: (kgdb) print tp->t_line 56:$2 = 1767990816 57: (kgdb) up 58:#1 0xf0191503 in cnopen (dev=0x00000000, flag=3, mode=8192, p=(st\ 59:ruct proc *) 0xf07c0c00) (../../i386/i386/cons.c line 126) 60: return ((*cdevsw.d_open)(dev, flag, mode, p)); 61: (kgdb) up 62:#2 0xf0132c34 in spec_open () 63: (kgdb) up 64:#3 0xf012d014 in vn_open () 65: (kgdb) up 66:#4 0xf012a183 in open () 67: (kgdb) up 68:#5 0xf019d4eb in syscall (frame={tf_es = 39, tf_ds = 39, tf_edi =\ 69: 2158592, tf_esi = 0, tf_ebp = -272638436, tf_isp = -272629788, tf\ 70:_ebx = 7086, tf_edx = 1, tf_ecx = 0, tf_eax = 5, tf_trapno = 582, \ 71:tf_err = 582, tf_eip = 75749, tf_cs = 31, tf_eflags = 582, tf_esp \ 72:= -272638456, tf_ss = 39}) (../../i386/i386/trap.c line 673) 73:673 error = (*callp->sy_call)(p, args, rval); 74: (kgdb) up 75:Initial frame selected; you cannot go up. 76: (kgdb) quit 77: # exit 78:exit 79: 80:Script done on Fri Dec 30 23:18:04 1994

лПННЕОФБТЙЙ Л ЧЩЫЕРТЙЧЕДЕООПНХ ЦХТОБМХ:

УФТПЛБ 6:

ьФП ДБНР, ЧЪСФЩК РТЙ РПНПЭЙ DDB (УНПФТЙ ОЙЦЕ), РПЬФПНХ ЛПННЕОФБТЙК Л БЧБТЙКОПНХ ПУФБОПЧХ ЙНЕЕФ ЙНЕООП ЧЙД ``because you said to!"" Й ФТБУУЙТПЧЛБ УФЕЛБ ЗМХВПЛБ; ПДОБЛП ЙЪОБЮБМШОПК РТЙЮЙОПК РЕТЕИПДБ Ч DDB ВЩМБ БЧБТЙКОБС ПУФБОПЧЛБ РТЙ ЧПЪОЙЛОПЧЕОЙА ПЫЙВЛЙ УФТБОЙГЩ РБНСФЙ.

УФТПЛБ 20:

ьФП НЕУФПОБИПЦДЕОЙЕ ЖХОЛГЙЙ trap() Ч ФТБУУЙТПЧЛЕ УФЕЛБ.

УФТПЛБ 36:

рТЙОХДЙФЕМШОПЕ ЙУРПМШЪПЧБОЙЕ ОПЧПК ЗТБОЙГЩ УФЕЛБ; ФЕРЕТШ ЬФП ОЕ ОХЦОП. рТЕДРПМБЗБЕФУС, ЮФП ЗТБОЙГЩ УФЕЛБ ХЛБЪЩЧБАФ ОБ РТБЧЙМШОПЕ ТБУРПМПЦЕОЙЕ, ДБЦЕ Ч УМХЮБЕ БЧБТЙКОПЗП ПУФБОПЧБ. зМСДС ОБ УФТПЛХ ЙУИПДОПЗП ЛПДБ 403, НПЦОП УЛБЪБФШ, ЮФП ЧЕУШНБ ЧЕТПСФОП, ЮФП МЙВП ЧЙОПЧБФ ДПУФХР РП ХЛБЪБФЕМА ``tp"", МЙВП ВЩМ ЧЩИПД ЪБ ЗТБОЙГЩ НБУУЙЧБ.

УФТПЛБ 52:

рПИПЦЕ, ЮФП ЧЙОПЧБФ ХЛБЪБФЕМШ, ОП ПО СЧМСЕФУС ДПРХУФЙНЩН БДТЕУПН.

УФТПЛБ 56:

пДОБЛП, ПЮЕЧЙДОП, ЮФП ПО ХЛБЪЩЧБЕФ ОБ НХУПТ, ФБЛ ЮФП НЩ ОБЫМЙ ОБЫХ ПЫЙВЛХ! (дМС ФЕИ, ЛФП ОЕ ЪОБЛПН У ЬФПК ЮБУФША ЛПДБ: tp->t_line УМХЦЙФ ДМС ИТБОЕОЙС ТЕЦЙНБ ЛБОБМБ ЛПОУПМШОПЗП ХУФТПКУФЧБ, Й ЬФП ДПМЦОП ВЩФШ ДПУФБФПЮОП НБМЕОШЛПЕ ГЕМПЕ ЮЙУМП.)