BSOD - Синий экран смерти

Метки:  , , , , , , , , ,
Синий экран смерти (BSOD, Blue Screen of Death) - визуальное оповещение о фатальной (неустранимой) ошибке в операционной системе Windows.

Обработка исключительной ситуации и вывод "синего экрана смерти" (BSOD) - это последнее действие операционной системы, указывающее на обнаружение необрабатываемой ошибки, дальнейшее исполнение кода после возникновения которой не имеет смысла по целому ряду причин. Следствием события является внезапное завершение работы с остановом ("заморозкой") практически всех процессов и потерей не сохраненных оперативных данных. BSOD это своего рода (вы не поверите!) защитный механизм системы, позволяющий на раннем этапе остановить неверно функционирующий процесс ядра. Разработчики кода ядра операционной системы Windows не случайно ввели подобную логику обработки критических ошибок, поскольку она обусловлена следующими утверждениями:

  • функция аварийного завершения (в том числе вывод синего экрана смерти) вызывается по таким условиям/проверкам в коде ядра, несоблюдение которых делает дальнейшее исполнение участка кода (равно как и всей последующей функции) ядра бессмысленным, то есть система просто "не понимает", что делать дальше. Например, критический системный параметр, имеющий всего два состояния, может принять "невалидное" (третье) значение, при котором дальнейшая работа не имеет смысла, поскольку значение абсурдно и для него нет обработки. Или же могут отсутствовать необходимые входные данные функции вследствие возникновения ошибок доступа к аппаратному ресурсу;
  • функция аварийного завершения вызывается с целью недопущения более существенной потери данных (например: разрушения файловой системы);
  • функция аварийного завершения вызывается с целью недопущения непредсказуемого поведения системы, которое может привести к появлению бреши в безопасности;

То есть, основная причина завершения заключается в том, что если система продолжит функционирование при возникшей критической ошибке, то имеется очень большая вероятность привести систему к еще более плачевному состоянию, нежели то, в котором она пребывает в момент возникновения ошибки. Общей причиной BSOD является возбуждение низкоуровневой функцией режима ядра необрабатываемого исключения, в следствии которого код ядра (система) не в состоянии продолжить штатное функционирование. Дело в том, что в процессе функционирования операционной системы, низкоуровневые функции режима ядра время от времени возбуждают исключения в качестве реакции на периодически возникающие ошибки. В подобной ситуации диспетчер исключений проверяет, имеется ли в наличии процедура (фильтр) ядра, способная обработать возникшее исключение (обработчик), то есть сопоставленная с контекстом, в котором возникла ошибка. Очевидно, что необходимая процедура обработки представляет собой последнее средство сохранить систему "на плаву", поэтому ядро всегда находит обработчик. Если же обработчик исключения не в состоянии обработать возникшее исключение, то исключение остается необработанным. В этом случае система вызывает стандартный обработчик исключений в ядре, который уже полностью останавливает систему.
Дабы у читателя не сложилось неправильного представления, стоит подчеркнуть, что само ядро Windows 7 относительно надежно, так как его отладкой занимаются днем и ночью, и по причине "родного" кода самого ядра сбои возникают исключительно редко, к тому же, в ядре все же присутствует некоторое количество цепочек разрешения критических ошибок. Сбои, в большинстве своем, случаются по вине "сторонних" модулей/драйверов режима ядра, содержащих ошибки.

Тем не менее сам механизм обработки исключений ядра в ОС Windows далек от идеала, разработчики явно перестраховались и внедрили переходов на BSOD в коде ядра великое множество. По сути, даже при возникновении довольно несущественных ошибок, код ядра склонен "впадать в панику" и тут же уходить на BSOD, даже не дав пользователю возможности сохранить свои данные.

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

Синий экран смерти называют еще СТОП-ошибкой (STOP-error) или Контролем дефекта (BugCheck).

Само по себе появление на экране монитора BSOD - это лишь начальная стадия алгоритма, стартующего при возникновении фатальной ошибки, которая заключается в выводе на экран отладочной информации с целью облегчения дальнейшего поиска причины проблемы. Давайте посмотрим, как же выглядит та информация, которую видит пользователь на экране в случае возникновения исключительной ситуации? Ниже я привожу типовой вид BSOD для Windows 7:

bsod blue screen of death

Обычно BSOD выводится в текстовом режиме, символами белого цвета на синем фоне. Хотя, надо упомянуть, что внешний вид BSOD на протяжении всего времени развития Windows претерпевает изменения. Не во всех ОС BSOD выглядит подобным образом, к примеру, начиная с Windows 8/Windows 2012 количество выводимой информации существенно сокращено до названия ошибки, остальную информацию пользователь может найти в журнале событий системы.

Зачастую пользователь не видит самого экрана BSOD с информацией об ошибке! Происходит это потому, что по умолчанию система настроена на автоматическую перезагрузку в случае аварийного завершения. Для пользователя это выглядит как периодические самопроизвольные перезагрузки компьютера с последующим выводом сообщения о том, что система была восстановлена после серьёзной ошибки.

Общие причины возникновения BSOD

Причиной BSOD может быть один из источников, описанных ниже:

  1. Сторонний драйвер (~70% случаев). Различные проблемы в драйверах - самая вероятная и распространенная причина возникновения синего экрана смерти, которую можно подразделить на несколько частей.
    • Ошибка в драйвере. Образуется в следствии ошибки разработчика на стадии написания кода.
    • Неподходящий к оборудованию драйвер. Microsoft всячески пытается оградить пользователя от подобной ситуации, однако человеческий фактор тут главенствует.
    • Конфликт драйверов устройств. Драйверы различных устройств могут конфликтовать между собой.
    • Несовместимость драйвера с текущей версией операционной системы. Опять же, установщик Microsoft предупреждает о подобных ситуациях.
  2. Неполадки оборудования (~10% случаев):
    • Перегрев комплектующих. В следствии разгона, то есть аппаратной модификации компонента, неправильных настроек BIOS/UEFI, плохой вентиляции внутри корпуса.
    • Неисправность ОЗУ. Причиной является повреждение памяти на физическом уровне.
    • Конфликт устройств. На уровне портов, областей памяти и прч.
    • Несовместимости оборудования с операционной системой.
    • Некорректные настройки BIOS. Примером может служить завышенное/заниженное значение частоты/таймингов с целью разгона процессора либо оперативной памяти.
    • Неисправность жесткого диска. Недостаток свободного места на системном носителе (от даже как!).
  3. Программный сбой:
    • Собственный код разработчиков Windows (~5% случаев).
    • Использование "левых" сборок Windows.
    • Заражение вредоносными программами (трояны, вирусы). Встречает подобная ситуация довольно редко.
    • Поврежденный системный реестр;
  4. Ошибка загрузчика. В некоторых случаях BSOD может быть вызван ошибкой загрузчика (Boot loader). Происходит это в ситуации, когда загрузчик не может получить доступ к загрузочному разделу из-за несовместимых либо неустановленных драйверов дискового контроллера, повреждения файловой системы. Пример: STOP 0x0000007B (INACCESSIBLE_BOOT_DEVICE). В подобных ситуациях дамп памяти не создается.
  5. Невыявленные причины (~15% случаев): по причине серьезного повреждения данных дампа;

Как мы видим, довольно часто причиной BSOD являются драйвера устройств. Я думаю это послужило основной причиной введения Microsoft сертификации WHQL. Стоит заметить, что не все драйвера управляют физическими устройствами, а большинство так называемых Windows-драйверов представляют из себя обычные программы, которые не взаимодействуют ни с какими устройствами, но, при этом, им необходим доступ к структурам ядра, который невозможно получить из кода пользовательского режима через традиционный Win32 API.

Виды ошибок, приводящих к BSOD

А что же из себя представляет та самая "серьёзная ошибка", являющаяся причиной BSOD, на более низком уровне машинных инструкций? Ошибки, приводящие к BSOD, делятся на две основные категории. Попытаюсь их детализировать:

  • Необрабатываемое исключение:
    • Обращение к нулевому адресу (нулевые указатели, когда указатель по какой-то причине содержит значение 0);
    • Попытка записи в страницу памяти, доступную только для чтения;
    • Ошибка ввода/вывода при попытке подкачки страницы в ОП из файла подкачки;
    • Неверная ссылка на память. Причиной может являться драйвер, выполняющий операцию ввода/вывода в то время, как Асинхронные Вызовы Процедур (APCs) отключены.
  • Некорректная операция:
    • Повторное освобождение уже освобожденной памяти.

Пример №1 (из дампа ядра):

В общем то, ничем не примечательный код, ошибка здесь произошла в строке 5. Поскольку значение регистра EDX=00000000, была произведена попытка чтения двойного слова памяти по адресу 00000024, то есть из (зарезервированной) области, являющейся областью нулевых указателей. Возникло исключение "ошибка доступа к памяти". Остается открытым вопрос, почему же в памяти по адресу [ESI] оказалось значение 0?

Пример №2 (из дампа ядра):

Ошибка в строке 3. Поскольку значение в регистре EBP=a3c84bc0, и соответственно, SS:0010:a3c84bcc=00000000. Было возбуждено исключение "деление на ноль".

Пример №3 (из исходного кода ядра):

А вот этот пример уже из исходного кода ядра (файл ntoskrnl.exe и производные). Тут разработчики решили, что у переменной InitializationPhase не может быть значений кроме 0 и 1, оно и понятно, в ядре могут быть только две фазы инициализации. Соответственно, при всех остальных значениях дальнейшее выполнение кода ядра не имеет ни малейшего смысла и код уходит на вызов функции KeBugCheck2 с аргументом 33h (с преждевременным заталкиванием параметров в стек), что ведет, в конечном итоге, к выводу синего экрана смерти.

Алгоритм BSOD

После возникновения критической ошибки, когда код режима ядра классифицирует ошибку как фатальную (неустранимую), управление передается на:

  • системную функцию KeBugCheckEx -- является "оберткой" к функции KeBugCheck2;
  • системную функцию KeBugCheck2;

Именно функция KeBugCheck2 и выполняет определенную последовательность действий (сброс буферов, сохранение дампа, перезагрука). Тут я приведу пока лишь краткое описание функции, более же детальную информацию вы всегда сможете найти на сайте Microsoft. Данная функция экспортируются модулем исполнительной подсистемы ядра, который для разных систем может называться по-разному: ntoskrnl.exe, ntkrnlmp.exe, ntkrnlpa.exe, ntkrpamp.exe. Функция KeBugCheck2 имеет пять входных параметров (аргументов). Поскольку значение параметров сильно зависят от конкретной ошибки, в таблице я приведу лишь общие, возможные значения параметров.

Параметр Описание
BugCheckCode Код ошибки. Перечень возможных значений BugCheckCode, определенных Microsoft, можно найти в NTDDK, либо можно определить собственный код в своем драйвере. Делятся на две категории: с указанием адреса инструкции, вызвавшей исключение и без указания. Разрядность 32 бита.
BugCheckParameter1 Параметр 1. Зависит от кода ошибки (BugCheckCode). Может принимать значение кода исключения, адреса, идентификатора потока, специального поля потока, внутреннего параметра, уровня IRQL, указателя на объект, пула значений и прч. Разрядность 32/64 бита.
BugCheckParameter2 Параметр 2. Зависит от кода ошибки (BugCheckCode). Может принимать значение кода исключения, адреса, идентификатора потока, специального поля потока, внутреннего параметра, уровня IRQL, указателя на объект, пула значений и прч. Разрядность 32/64 бита.
BugCheckParameter3 Параметр 3. Зависит от кода ошибки (BugCheckCode). Может принимать значение кода исключения, адреса, идентификатора потока, специального поля потока, внутреннего параметра, уровня IRQL, указателя на объект, пула значений и прч. Разрядность 32/64 бита.
BugCheckParameter4 Параметр 4. Зависит от кода ошибки (BugCheckCode). Может принимать значение кода исключения, адреса, идентификатора потока, специального поля потока, внутреннего параметра, уровня IRQL, указателя на объект, пула значений и прч. Разрядность 32/64 бита.

Как Вы уже догадались, данные параметры введены разработчиками не случайно. Поговаривают, что гуру визуальной отладки :) могут лишь по коду ошибки и значениям этих дополнительных параметров достаточно точно определить причину сбоя. Ну а для нас, простых смертных, параметры эти однозначно указывают на дополнительные детали сбоя, которые способствуют более точной отладке в процессе выполнения анализа инцидента. Как уже говорилось, параметры могут использоваться и для поверхностного визуального анализа проблемы. Например, для ошибки STOP 0x000000ED, второй параметр, имеющий значение 0xC0000185 и носящий название STATUS_IO_DEVICE_ERROR, довольно часто указывает на то, что с нашим накопителем (жестким диском) творится что-то неладное, и при этом на аппаратном уровне.
В самом ядре Windows функция KeBugCheckEx вызывается из достаточно большого количества точек кода.
Алгоритм работы функции KeBugCheckEx следующий:

  1. Формируется текст BSOD и выводится на экран.
  2. Код ядра системы проверяет целостность карты блоков файла подкачки (либо пользовательского файла, указанного для сохранения дампа), ранее сохраненной в памяти.
  3. Код ядра проверяет работоспособность специализированного независимого дискового драйвера и целостность управляющих структур дискового драйвера.
  4. Код ядра записывает данные из памяти в блоки, указанные в карте блоков файла подкачки (либо пользовательского файла, указанного для сохранения дампа).
  5. Возможна передача управления отладчику.
  6. В зависимости от настроек выполняется или не выполняется автоматическая перезагрузка системы.
  7. В процессе следующей загрузки ОС, winlogon.exe переносит дамп памяти (полный/сокращенный) из временного файла в файл, указанный в настройках. Для сброса используется специализированная утилита.
  8. При следующей загрузке, в зависимости от настроек создается запись в журнале событий.

Поиск причины BSOD

Любой специалист рано или поздно сталкивается с задачей выявления виновника BSOD, то есть компонента, который и является, в конечном итоге, причиной падения операционной системы. От того, владеет ли специалист необходимой информацией, зависит выбор метода решения, от затрат всего нескольких минут на переустановку драйвера/устройства, до многочасовой переустановки и настройки операционной системы с нуля. Вы можете себе представить, сколько времени Вы потеряете, пойдя по ложному пути, с учетом того, что все эти действия могут и не решить проблемы (!) Только представьте, какие временные затраты мы получим бы при попытке, предположим, "перезалить" контроллер домена или сервер приложений? Поэтому, прислушайтесь к хорошему совету: во всех ситуациях, где только возможно, до последней захудалой зацепки пытайтесь определить источник проблемы и избежать переустановки ОС.
Имеется два основных варианта нахождения причины возникновения синего экрана смерти:

Визуальный анализ

Попытаться без использования специализированного ПО, по коду ошибки или имени драйвера, информация о которых представлена на экране или в логе события BSOD, выяснить причину. Если после сбоя удалось получить только лишь код STOP-ошибки, то это наименее точный и наименее быстрый метод определения источника проблемы, поскольку некоторые классы ошибок имеют множество потенциальных причин возникновения. Однако, если нам повезло и мы получили с экрана или из лога наименование сбойного драйвера, то метод превращается в достаточно точный и наиболее быстрый.
Описанная ранее функция KeBugCheckEx содержит в себе алгоритмы, которые собирают и выводят на экран максимально-возможный объем информации о состоянии определенных триггеров системы в момент сбоя. И такое поведение вполне объяснимо, поскольку специалисту может потребоваться вся доступная информация для последующего анализа возникшей проблемы. Бывают, однако, случаи, когда сообщение недостаточно информативно, то есть информации откровенно мало, но такие ситуации встречаются достаточно редко.
Давайте попробуем "расшифровать" BSOD и разберемся с данными, которые процедура выводит на экран. Для удобства понимания информации, представленной на синем экране смерти, я промаркировал основные блоки:

bsod символическое имя

Рассмотрим полученные с экрана блоки подробнее:

  1. Символическое имя ошибки (в нашем случае: BAD_SYSTEM_CONFIG_INFO). Может отсутствовать.
  2. Рекомендации по устранению общего характера.
  3. Код STOP-ошибки. (в нашем случае: 0x00000074).
  4. Четыре параметра, конкретизирующие ошибку, предназначенные для отладочного ПО (Значение параметров зависит от кода ошибки и кратко описывается в таблице выше).
  5. Необязательный параметр. На нашем скриншоте отсутствует. Имя программного модуля или драйвера ядра, в коде которого возникла ошибка. Адрес инструкции, вызвавшей останов, "база" драйвера. Время, дата. Если ошибка не относится к модулю/драйверу, либо ядро не смогло связать проблему с объектом, то данный параметр отсутствует.
    пример: gv3.sys – address F86B5A89 base at F86B5000, DateStamp 3dd991eb
BSOD-ошибки можно условно разделить на две категории. Первая категория содержит адрес инструкции, вызвавшей исключение (как в нашем примере, 00000074h: BAD_SYSTEM_CONFIG_INFO). Вторая категория BSOD-ошибок не содержит адреса проблемной инструкции, потому что ядро диагностирует аварийную ситуацию на поздней стадии.

Для последующей работы над проблемой нам потребуется как минимум один параметр от синего экрана смерти: код STOP-ошибки и/или (если имеется) имя программного модуля или драйвера ядра.
Запишите всю эту информацию и смело переходите к следующему разделу "Устранение BSOD".

Автоматизированный анализ

С помощью специализированного программного обеспечения проанализировать аварийный дамп памяти системы. Этот метод позволяет, в подавляющем большинстве случаев, достаточно точно определить источник проблемы. Практически всегда дает определенный результат, за исключением довольно редких случаев, когда ситуация остается неясной. Виновниками подобных исключительных сбоев является, как правило, оборудование (железо).
Для использования данного метода, нам необходимо будет сначала произвести настройку параметров аварийного дампа с целью получения полного дампа памяти системы.
После настройки необходимо вновь дождаться системного сбоя. Когда произойдет сбой, Вы получите в своё распоряжение дамп памяти (файл с расширением .dmp), и можете переходить непосредственно к анализу. Я приведу три основных способа изучения дампа памяти:

  1. Анализ дампа при помощи утилиты BlueScreenView.
  2. Анализ дампа при помощи скрипта kdfe.
  3. Анализ дампа при помощи отладчика WinDbg.
  4. Анализ дампа при помощи онлайн-анализатора OSR Instant Online Crash Analysis. Принимаются дампы размером до 40Мб.

Какой из методов выбрать, спросите Вы? Я бы на Вашем месте придерживался логики (поочередного) перебора методов до момента выявления причины, либо выполнения всех описанных методов для составления полной картины инцидента. В данном конкретном случае никакая информация лишней не будет!

Устранение (исправление) BSOD

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

  • Код ошибки. Если мы имеет только код STOP-ошибки, просто посмотрели списали его с BSOD и не стали заниматься анализом никаких там дампов, то в этом случае можно с помощью таблицы STOP-ошибок, имеющейся на официальном сайте, определить предполагаемого виновника. Можно не ограничивать себя только лишь официальным ресурсом, а просто поискать в Сети.
  • Сторонний драйвер. Если предполагаемым источником проблемы является драйвер устройства, то нам необходимо понять, к какому компоненту ОС он принадлежит. Для этого используем поисковик. Если недавно был установлен обновленный драйвер видеокарты, звуковой, материнской, сетевой - пробуем откатиться на старый, если не помогло, то пробуем просто переустановить текущую версию, если и это не помогло, то попытаемся найти драйвер новее на официальном сайте производителя оборудования.
  • Системный драйвер. Вероятность того, что причиной является системный драйвер очень мала, потому как системные (встроенные) драйвера хорошо отлаживаются перед запуском в релиз/обновление. Но если, все же, вы грешите на системный драйвер Windows - то Вам потребуется средство проверки драйверов verifier.exe.

Выводы

При всей серьезности проблемы, множество критических ситуаций могут быть исправлены. Существуют методы "перехвата" критических ситуаций с помощью специализированных отладчиков, ручной корректировки данных и возврата к нормальному режиму функционирования ОС. И ОС продолжает работу, худо-бедно, медленно, неуверенно, но продолжает. Объясняется это тем, что большинство ошибок не фатальны. Почему же тогда ядро предпочитает в большинстве случаев завершить работу системы, для меня загадка. Однако, для применения на практике этого метода требуется определенный уровень квалификации.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *