- Загальні причини виникнення BSOD
- Види помилок, що призводять до BSOD
- алгоритм BSOD
- Пошук причини BSOD
- Візуальний аналіз
- автоматизований аналіз
- Усунення (виправлення) 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 виводиться в текстовому режимі, символами білого кольору на синьому тлі. Хоча, треба згадати, що зовнішній вигляд BSOD протягом усього часу розвитку Windows зазнає змін. Не у всіх ОС BSOD виглядає подібним чином, наприклад, починаючи з Windows 8 / Windows 2012 кількість виведеної інформації істотно скорочено до назви помилки, іншу інформацію користувач може знайти в журналі подій системи.
Найчастіше користувач не бачить самого екрану BSOD з інформацією про помилку! Відбувається це тому, що за замовчуванням система налаштована на автоматичне перезавантаження в разі виникнення BSOD. Для користувача це виглядає як періодичні мимовільні перезавантаження комп'ютера з подальшим виведенням повідомлення про те, що система була відновлена після серйозної помилки.
Загальні причини виникнення BSOD
Причиною BSOD може побут один з джерел, описаних нижче (пункти відсортовані у напрямку зниження частоти народження):
- Драйвер обладнання. За статистикою самої Microsoft, близько 85% всіх фіксованих помилок зупинки відносяться саме до драйверів. Різні проблеми в драйверах - найвірогідніша і поширена причина виникнення синього екрану смерті, яку можна поділити на кілька частин.
- Помилка в драйвері. Утворюється в результаті помилки розробника на стадії написання коду.
- Невідповідний до обладнання драйвер. Microsoft всіляко намагається захистити користувача від подібної ситуації, проте людський фактор тут панує.
- Конфлікт драйверів пристроїв. Драйвери різних пристроїв можуть конфліктувати між собою.
- Несумісність драйвера з поточною версією операційної системи. Знову ж, установник Microsoft попереджає про подібні ситуації.
Як ми бачимо, досить часто причиною BSOD є драйвера пристроїв. Саме з цієї причини Microsoft перейшла до сертифікації та захисту драйверів пристроїв методом цифрового підпису. Однак, варто зауважити, що не всі драйвера управляють фізичними пристроями, а більшість так званих Windows-драйверів вдають із себе звичайні програми, які не управляють ніякими пристроями, але, при цьому, їм потрібен доступ до структур ядра, до яких неможливо отримати доступ з коду призначеного для користувача режиму через традиційний Win32 API.
Види помилок, що призводять до BSOD
А що ж із себе представляє той самий "серйозна помилка", що є причиною BSOD, на більш низькому рівні машинних інструкцій? Помилки, що призводять до BSOD, діляться на дві основні категорії. Спробую їх деталізувати:
- Необроблюваних виняток:
- Звернення до нульового адресою (нульові покажчики, коли покажчик з якоїсь причини містить значення 0);
- Спроба запису в сторінку пам'яті, доступну тільки для читання;
- Помилка введення / виведення при спробі підкачки сторінки в ОП з файлу підкачки;
- Невірне посилання на пам'ять. Причиною може бути драйвер, який виконує операцію введення / виводу в той час, як Асинхронні Виклики Процедур (APCs) відключені.
- Некоректна операція:
- Повторне звільнення вже звільненій пам'яті.
Приклад №1 (з дампа ядра):
. . .
bc582f10 push esi
bc582f11 mov esi, dword ptr [ecx + 4Ch]
bc582f14 mov edx, dword ptr [esi]
bc582f16 mov eax, dword ptr [edx + 24h]; Місце помилки!
bc582f19 sub eax, dword ptr [edx + 20h]
bc582f1c mov esi, dword ptr [esi + 30h]
bc582f1f add edx, 1Ch
. . .
Помилка сталася в рядку 5. Оскільки значення регістра EDX = 00000000, було зроблено спробу читання подвійного слова пам'яті за адресою 00000024, тобто з області, що є областю нульових покажчиків. Виникло виключення "помилка доступу до пам'яті". Залишається відкритим питання, чому ж в пам'яті за адресою [ESI] виявилося значення 0?
Приклад №2 (з дампа ядра):
. . .
8eb20967 xor edx, edx
8eb20969 div eax, dword ptr [ebp + 0Ch]; Місце помилки!
8eb20972 xchg eax, edx
. . .
Помилка в рядку 3. Оскільки значення в регістрі EBP = a3c84bc0, і відповідно, SS: 0010: a3c84bcc = 00000000. Сталося виняток "поділ на нуль".
Приклад №3 (з вихідного коду ядра):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
. . .
INIT: 007A0307 mov edi, edi
INIT: 007A0309 push ebp
INIT: 007A030A mov ebp, esp
INIT: 007A030C and esp, 0FFFFFFF8h
INIT: 007A030F mov eax, _InitializationPhase
INIT: 007A0314 mov ecx, eax
INIT: 007A0316 xor edx, edx
INIT: 007A0318 sub ecx, edx
INIT: 007A031A jz short loc_7A0331
INIT: 007A031C dec ecx
INIT: 007A031D jz short loc_7A032D
INIT: 007A031F push edx
INIT: 007A0320 push edx
INIT: 007A0321 push edx
INIT: 007A0322 push eax
INIT: 007A0323 push 2
INIT: 007A0325 push 33h
INIT: 007A0327 call _KeBugCheck2 @ 24
. . .
А ось цей приклад вже з вихідного коду ядра (файл 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 біта.
Як Ви вже здогадалися, дані параметри введені розробниками не просто так. Подейкують, що гуру візуальної налагодження :) можуть лише за кодом помилки і значенням цих додаткових параметрів досить точно визначити причину збою. Ну а для нас, простих смертних, параметри ці однозначно вказують на додаткові деталі збою, які допомагають отладчику (WinDBG) в процесі виконання аналізу інциденту. Як вже говорилося, параметри можуть використовуватися і для поверхневого візуального аналізу проблеми. Наприклад, для помилки STOP 0x000000ED, другий параметр, який має значення 0xC0000185 і носить назву STATUS_IO_DEVICE_ERROR, досить часто вказує на те, що з нашим диском коїться щось недобре, і при цьому на апаратному рівні.
У самому ядрі Windows функція KeBugCheckEx викликається з досить великої кількості місць коду.
Алгоритм роботи функції KeBugCheckEx наступний:
- Формується текст BSOD і виводиться на екран.
- Код ядра системи перевіряє цілісність карти блоків файлу підкачки (або призначеного для користувача файлу, вказаного для збереження дампа), раніше збереженої в пам'яті.
- Код ядра перевіряє працездатність спеціалізованого незалежного дискового драйвера і цілісність керуючих структур дискового драйвера.
- Код ядра записує дані з пам'яті в блоки, зазначені в карті блоків файлу підкачки (або призначеного для користувача файлу, вказаного для збереження дампа).
- Можлива передача управління отладчику.
- Залежно від налаштувань виконується або не виконується автоматичне перезавантаження системи.
- У процесі наступного завантаження ОС, winlogon.exe переносить дамп пам'яті (повний / скорочений) з тимчасового файлу в файл, вказаний в налаштуваннях. Для скидання використовується спеціалізована утиліта.
- При наступному завантаженні, в залежності від налаштувань створюється запис в журналі подій.
Пошук причини BSOD
Будь-який фахівець рано чи пізно стикається з завданням виявлення винуватця BSOD, тобто компонента, який і є, в кінцевому підсумку, причиною падіння операційної системи. Не варто боятися братися за аналіз BSOD. Адже від того, чи володіє фахівець необхідною інформацією, залежить вибір методу рішення, від витрат всього декількох хвилин на переустановку драйвера / пристрої, до багатогодинної перевстановлення та налаштування операційної системи з нуля. Ви можете собі уявити, скільки часу ви втратите, пішовши цим хибним шляхом, з урахуванням того, що всі ці дії можуть і не вирішити проблеми? Тільки уявіть, які тимчасові витрати ми отримаємо б при спробі, припустимо, "перезаліть" контролер домену або сервер додатків? Тому, підіть хорошому раді: у всіх ситуаціях, де тільки можливо, до останньої зубожілій зачіпки намагайтеся визначити джерело проблеми і уникнути переустановлення ОС.
Є два основні варіанти знаходження причини виникнення синього екрану смерті:
Візуальний аналіз
Спробувати без використання спеціалізованого ПЗ, за кодом помилки або імені драйвера, інформація про яких представлена на екрані або в балці події BSOD, з'ясувати причину. Якщо вдалося отримати тільки код STOP-помилки, то це найменш точний і найменш швидкий метод з'ясувати причину порушення, оскільки деякі класи помилок мають безліч потенційних причин виникнення. Однак, якщо нам пощастило і ми отримали з екрану або з логу найменування збійного драйвера, то метод перетворюється в досить точний і найбільш швидкий.
Описана раніше функція KeBugCheckEx містить в собі алгоритми, які збирають і виводять на екран максимально-можливий об'єм інформації про стан певних тригерів системи в момент збою. І така поведінка цілком зрозуміло, оскільки фахівця може знадобитися вся доступна інформація для подальшого аналізу виниклої проблеми. Бувають, однак, випадки, коли повідомлення недостатньо інформативно, тобто інформації відверто мало, але такі ситуації зустрічаються досить рідко.
Давайте спробуємо "розшифрувати" BSOD і розберемося з даними, які процедура виводить на екран. Для зручності розуміння інформації, представленої на синьому екрані смерті, я промарковані основні блоки:
Давайте тепер розглянемо ці блоки докладніше:
- Сімволічне имя помилки (в нашому випадка: BAD_SYSTEM_CONFIG_INFO). Може буті відсутнім.
- Рекомендації относительно Усунення Загальна характеру.
- Код STOP-помилки. (В нашому випадка: 0x00000074).
- Чотири параметра, що конкретизують помилку, призначені для налагоджувального ПО (Значення параметрів залежить від коду помилки і коротко описується в таблиці вище).
- Необов'язковий параметр. На нашому скріншоті відсутня. Ім'я програмного модуля або драйвера ядра, в коді якого виникла помилка. Адреса інструкції, що викликала зупинку, "база" драйвера. Час, дата. Якщо помилка не відноситься до модуля / драйверу, або ядро не змогло зв'язати проблему з об'єктом, то даний параметр відсутній.
приклад: gv3.sys - address F86B5A89 base at F86B5000, DateStamp 3dd991eb
BSOD-помилки можна умовно розділити на дві категорії. Перша категорія містить адресу інструкції, що викликала виняток (як в нашому прикладі, 00000074h: BAD_SYSTEM_CONFIG_INFO). Друга категорія BSOD-помилок не містить адреси проблемної інструкції, тому що ядро діагностує аварійну ситуацію на пізній стадії.
Для подальшої роботи над проблемою нам потрібно як мінімум один параметр від синього екрану смерті: код STOP-помилки і / або (якщо є) ім'я програмного модуля або драйвера ядра.
Запишіть всю цю інформацію і сміливо переходите до наступного розділу "Усунення BSOD".
автоматизований аналіз
За допомогою спеціалізованого програмного забезпечення проаналізувати аварійний дамп пам'яті системи. Цей метод дозволяє, в переважній більшості випадків, достатньо точно визначити джерело проблеми. Практично завжди дає певний результат, за винятком досить рідкісних випадків, коли ситуація залишається неясною. Винуватцями подібних виняткових збоїв є, як правило, обладнання (залізо).
Для використання даного методу, нам необхідно буде спочатку провести налаштування параметрів аварійного дампа з метою отримання повного дампа пам'яті системи.
Після установки необхідно знову дочекатися системного збою. Коли відбудеться збій, Ви отримаєте в своє розпорядження дамп пам'яті (файл з розширенням .dmp), і можете переходити безпосередньо до аналізу. Я приведу три основних способи вивчення дампа пам'яті:
- Аналіз дампа за допомогою утиліти BlueScreenView .
- Аналіз дампа за допомогою скрипта kdfe .
- Аналіз дампа за допомогою відладчика WinDbg .
- Аналіз дампа за допомогою онлайн-аналізатора OSR Instant Online Crash Analysis . Приймаються дампи розміром до 40Мб.
Який з методів вибрати, запитаєте Ви? Я б на Вашому місці дотримувався логіки перебору методів до з'ясування джерела проблеми, або виконання всіх описаних методів для складання повної картини події. В даному конкретному випадку ніяка інформація зайвою не буде!
Усунення (виправлення) BSOD
Скориставшись одним з вищеописаних способів знаходження причин збою, Ви отримали на руки інформацію про передбачуване джерелі проблеми. Тепер, залежно від роду наявною інформацією, давайте опишемо подальші кроки:
- Код помилки. Якщо ми маємо тільки код STOP-помилки, просто подивилися списали його з BSOD і не стали займатися аналізом ніяких там дампов, то в цьому випадку можна за допомогою таблиці STOP-помилок , Наявної на офіційному сайті, визначити передбачуваного винуватця. Можна не обмежувати себе тільки лише офіційним ресурсом, а просто пошукати в Мережі.
- Сторонній драйвер. Якщо передбачуваним джерелом проблеми є драйвер пристрою, то нам необхідно зрозуміти, до якого компоненту ОС він належить. Для цього використовуємо пошуковик.
Якщо недавно був встановлений оновлений драйвер відеокарти, звукової, материнської, мережевий - пробуємо відкотитися на старий, якщо не допомогло, то пробуємо просто перевстановити поточну версію, якщо і це не допомогло, то спробуємо знайти ще новіший, взятий з офіційного сайту виробника обладнання. - Системний драйвер. Імовірність того, що причиною є системний драйвер дуже мала, тому як системні (вбудовані) драйвера дуже добре отлаживаются перед запуском в реліз. Але якщо, все ж, ви грішите на системний драйвер Windows - то Вам буде потрібно засіб перевірки драйверів verifier.exe.
При всій серйозності проблеми, безліч критичних ситуацій можуть бути виправлені. Існують методи "перехоплення" критичних ситуацій за допомогою спеціалізованих отладчиков, ручного коректування даних і повернення до нормального режиму функціонування ОС. І ОС продовжує роботу, так-сяк, повільно, невпевнено, але продовжує. Пояснюється це тим, що більшість помилок не фатальні. Чому ж тоді ядро воліє в більшості випадків завершити роботу системи, для мене загадка. Однак, для застосування на практиці цього методу потрібен певний рівень кваліфікації.
Давайте подивимося, як же виглядає та інформація, яку бачить користувач на екрані в разі виникнення виняткової ситуації?Залишається відкритим питання, чому ж в пам'яті за адресою [ESI] виявилося значення 0?
Ви можете собі уявити, скільки часу ви втратите, пішовши цим хибним шляхом, з урахуванням того, що всі ці дії можуть і не вирішити проблеми?
Тільки уявіть, які тимчасові витрати ми отримаємо б при спробі, припустимо, "перезаліть" контролер домену або сервер додатків?
Який з методів вибрати, запитаєте Ви?