Роль палача bsod в NT-системах играет функция KeBugCheckEx, экспортируемая ядром и вызываемая из сотен (если не тысяч!) мест с теми или иными параметрами.
Что это за параметры? Обратившись к NTDDK, мы узнаем, что функция KeBugCheckEx принимает пять аргументов, первый из которых (BugCheckCode) содержит код ошибки bsod, а четыре следующих параметра – места/время/обстоятельства ее возникновения.
Перечень BugCheck-кодов можно найти в том же NTDDK. Там же содержится описание четырех аргументов, специфичных для каждого BugCheck-кода, количество которых чуть меньше сотни. Чтобы не держать в голове кучу ненужной информации о bsod, рекомендуется распечатать документацию и всегда хранить ее под рукой.
BugCheck-коды можно разделить на две большие категории. Первая содержит адрес инструкции, вызвавшей исключение (например, 1Eh: KMODE_EXCEPTION_NOT_HANDLED, 0Ah: IRQL_NOT_LESS_OR_EQUAL, 24h: NTFS_FILE_SYSTEM).
Это позволяет «заглянуть» отладчиком непосредственно на место аварии, исправить пробоину и, выйдя из отладчика, продолжить плавание (естественно, для этого нужно не только знать ассемблер, но и разбираться в тонкостях драйверостроения, но это – в идеале).
Другая категория BugCheck-кодов в bsod не содержит адреса дефективной инструкции, поскольку ядро диагностирует аварийную ситуацию на поздней стадии. Найти виновника в этих случаях затруднительно. Взять хотя бы такой BugCheck-код, как C2h: BAD_POOL_CALLER. Он вызывается из функции распределения памяти, обнаружившей, что память на конкретной измене, но кто ее разрушил и когда – этого система сказать не может.
Поиск диверсанта зачастую отнимает несколько дней кропотливого ручного труда и, что самое неприятное, – исправить разрушенные структуры данных практически невозможно, а, значит, перезагрузки все равно не избежать. Хотя с риском для жизни еще можно вернуться на уровень прикладного режима, попробовав сохранить хотя бы часть данных.
Если нам повезет, то с разрушенным пулом (специальной областью ядерной памяти) можно проработать несколько минут, а иногда и дней. В исключительных ситуациях система держится на плаву целую неделю, однако никакого смысла в таком эксперименте нет. Риск разрушения дисковых томов очень велик и потому, сохранив все несохраненные данные, лучше все-таки перезагрузиться.
Также можно вывести на экран в ручном режиме BSOD:
Операционные системы семейства NT, начиная с Windows 2000, могут быть настроены таким образом, чтобы дать пользователю возможность вручную спровоцировать «синий экран смерти». Чтобы включить эту функцию на компьютере с клавиатурой PS/2, необходимо изменить определённые настройки в системном реестре:
- Запустите редактор реестра.
- Найдите следующий раздел реестра:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
- В меню Правка выберите команду Добавить параметр и создайте следующую запись реестра: Параметр: CrashOnCtrlScroll
Тип данных: REG_DWORD
Значение: 1
- Закройте редактор реестра и перезагрузите компьютер.
После этого по двойному нажатию клавиши SCROLL LOCK при удерживании правой клавиши CTRL система выдаст синий экран. Эта опция полезна, например, для получения дампа памяти компьютера в заданный момент или для экстренной остановки компьютера аналогично кнопке Reset. Иногда она используется при разрешении настоящих проблем работы операционной системы.
После появления bsod в Windows 9x/ME ОС в отдельных случаях спрашивает, следует ли продолжить работу. Во многих случаях возможно нормальное продолжение работы после bsod.
Проблемы с локализованными версиями Windows.
В локализованных версиях Windows сообщение об ошибке bsod выводится на языке локализации. Если в видеокарту не загружены символы алфавита языка, сообщение превращается в мешанину символов, так как загруженные драйверы локализации не используются при выводе BSOD.
Например, такое случается в русской версии Windows XP (в русской Windows XP Service Pack 2 и позже STOP-сообщения выдаются на английском языке).
При этом в качестве инструкции выдаются самые общие сведения, которые не могут помочь решению проблемы. Основную информацию несет номер (код) и название ошибки. Внизу может быть так же отображено имя драйвера или процесса, который вызвал ошибку (зачастую это не тот драйвер, который по-настоящему дал сбой).