uawikipc.ru

Диспетчеризація винятків

На відміну від переривань, які можуть відбуватися в будь-який час, виключення є умовами, які є безпосередніми результатами виконання запущеної програми. У Windows використовується засіб, відоме як структурна обробка виключення (structured exception handling), яке дозволяє додаткам отримати управління при виникненні виключення.

Потім додаток може виправити ситуацію і повернутися до місця виникнення виключення, повернути назад покажчик стека (завершуючи тим самим виконання підпрограми, що видала виняток) або оголосити системі, що винятку не розпізнано і система повинна продовжити пошук обробника виключення, який може впоратися з виключенням. В даному розділі передбачається, що ви знайомі з основними поняттями, покладеними в основу структурної обробки виключень Windows.

Якщо це не так, то перед тим як продовжити читання вам, потрібно прочитати огляд довідкової документації по Windows API в Windows SDK або глави з 23 по 25 в книзі Джеффрі Ріхтера (Jeffrey Richter) і Крістофера Назара (ChristopheNasarre) «WindowsviaC / C ++». Слід мати на увазі, що, незважаючи на доступність обробки виключень засобами розширень мови програмування (наприклад, конструкції __try в Microsoft Visual C ++), даний механізм є системним і, отже, не має відношення до якогось певного мови.

На процесорах x86 і x64 все виключення мають зумовлені номера переривань, які безпосередньо співвідносяться із записом в IDT-таблиці, що вказує на обробник системного переривання для конкретного винятку.

У таблиці показується винятки, визначені для x86-системи і задані для них номери переривань. Оскільки, як уже говорилося, перші записи в IDT-таблиці використовуються для винятків, апаратні переривання призначаються тим записам, які слідують в цій таблиці пізніше.

виключення-і-номера-их-переривань

Всі виключення, крім найпростіших, дозволених за допомогою процесора системних переривань, обслуговуються модулем ядра, який називається диспетчером винятків. Завданням цього диспетчера є пошук відповідного обробника виключення. До винятків, незалежних від архітектури і визначеним ядром, можна віднести порушення доступу до пам`яті, цілочисельні ділення на нуль, цілочисельні переповнення, виключення при роботі з числами з плаваючою точкою і контрольні точки відладчика. Для отримання повного переліку винятків, що не залежать від архітектури, потрібно звернутися до довідкової документації по Windows SDK.

Ядро перехоплює і обробляє деякі з цих винятків прозоро для користувача програм. Наприклад, зустріч контрольної точки при виконанні налагоджують програму призводить до видачі виключення, яке ядро обробляє шляхом виклику отладчика. Ядро обробляє деякі інші винятки, повертаючи викликає програмі код невдалого стану.

Деякі винятки можуть передаватися в незайманому вигляді назад в призначений для користувача режим. Наприклад, деякі види помилок звернення до пам`яті або арифметичне переповнення генерують виняток, що не обробляється операційною системою. Для роботи з цими винятками 32-розрядні додатки можуть встановлювати фреймових обробники винятків.



Поняття фреймових відноситься до обробникам винятків, пов`язаних з активацією конкретної процедури. При виклику процедури в стек поміщається стековий фрейм, який представляє її активацію. Стековий фрейм може мати пов`язаний з ним один або кілька обробників винятків, кожен з яких захищає конкретний блок коду у вихідній програмі. При видачі виключення ядро здійснює пошук обробника виключення, пов`язаного з поточним стековим фреймом.

Якщо такий відсутній, ядро шукає обробник виключення, пов`язаний з попереднім стековим фреймом, і так далі, до тих пір, поки не буде знайдений фреймовий обробник виключень. Якщо обробник виключень не знайдений, ядро викликає свої власні обробники винятків, що використовуються за замовчуванням.

Для 64-розрядних винятків в структурованої обробці виключень фреймових обробники не використовуються. Замість цього під час компіляції в образ вбудовується таблиця оброблювачів. Ядро шукає обробники, пов`язані з кожною функцією, і слід в цілому тим же алгоритмом, який був описаний для 32-розрядного коду.

Структурована обробка винятків активно використовується в самому ядрі, тому воно запросто може перевірити, чи можна безпечно звертатися до покажчиків з призначеного для користувача режиму для доступу з читання або за записом.

Драйвери можуть скористатися такою ж технологією при роботі з покажчиками, відправленими разом з кодами управління вводу-виводу (IOCTL-кодами).

Ще один механізм обробки виключень називається векторною обробкою винятків. Цей метод може бути використаний тільки додатками призначеного для користувача режиму. Додаткову інформацію про нього можна знайти в Windows SDK або в бібліотеці MSDN.

При видачі виключення, або явною, з боку програмного забезпечення, чи неявній, ініційованої обладнанням, ланцюжок подій починається в ядрі. Апаратура центрального процесора передає управління оброблювачу системних переривань ядра, який створює фрейм системного переривання (так само, як при виникненні переривання). Фрейм системного переривання (trap frame) дозволяє системі відновити виконання з того ж місця, на якому воно було зупинено, якщо виключення буде дозволено. Оброблювач системного переривання також створює запис виключення, в якій міститься причина виключення і інша, що відноситься до нього інформація.

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

Оскільки необроблені виключення режиму ядра вважаються фатальними помилками операційної системи, можна припустити, що диспетчер завжди знаходить обробник виключення. Проте деякі системні переривання не призводять до обробника виключення, тому що ядро завжди вважає такі помилки фатальними. Це відноситься до тих помилок, які могли бути викликані тільки критичними збоями у внутрішньому коді ядра або серйозними неузгодженостями в коді драйвера, що виникають тільки завдяки навмисним, низькорівневим системних змін, за які драйвери не повинні нести відповідальність. Такі фатальні помилки призводять до збою перевірки з кодом UNEXPECTED_KERNEL_MODE_TRAP.

Якщо виняток видається в призначеному для користувача режимі, диспетчер виключень виконує більш складні дії. Як буде показано, у підсистеми Windows є порт налагодження (який фактично є об`єктом відладчика) і порт виключення для отримання повідомлень користувача режиму в процесах Windows1. Як показано на малюнку, ядро використовує ці порти в своїй обробці виключень, використовуваної за замовчуванням.

диспетчеризація-виключення

Звичайними джерелами винятків є контрольні точки відладчика.

Тому перш за все диспетчер виключень перевіряє, чи не пов`язаний процес, який видав виняток, з процесом налагодження. Якщо пов`язаний, диспетчер виключень відправляє повідомлення об`єкта відладчика об`єкту налагодження, пов`язаного з процесом. Всередині себе система звертається до об`єкта налагодження як до «порту» для сумісності з програмами, які можуть залежати від поведінки в Windows 2000, де використовується не об`єкт налагодження, а LPC-порт.

Якщо у процесу немає підключеного до нього процесу відладчика або якщо відладчик і не виконує жодних виняток, диспетчер виключень перемикається в призначений для користувача режим, копіює фрейм системного переривання в призначений для користувача стек, відформатований як структура даних CONTEXT (документація по якій є в Windows SDK), і викликає процедуру для пошуку структурованого або векторного обробника виключення. Якщо такої не буде знайдений або якщо виключення нічим не обробляється, диспетчер виключень перемикається назад в режим ядра і знову викликає відладчик, щоб дати можливість користувачу провести додаткову налагодження програми.

Це називається повторним повідомленням.

Якщо відладчик не запущені і не знайдено жодного обробника виключення призначеного для користувача режиму, ядро відправляє повідомлення порту виключення, пов`язаного з процесом потоку. Цей порт виключення, якщо такий є, був зареєстрований підсистемою оточення, яка контролює цей потік. Порт виключення дає підсистемі оточення, яка, ймовірно, прослуховує порт, можливість транслювати виключення в характерний для цього оточення сигнал або виключення. Наприклад, коли підсистема для додатків UNIX - Subsystem for UNIX Applications - отримує повідомлення від ядра про те, що один з його потоків згенерував виняток, підсистема Subsystem for UNIX Applications відправляє сигнал в UNIX-стилі того потоку, який став причиною виключення.

Але якщо ядро заходить настільки далеко в обробці виключення, і підсистема цей виняток не обробляє, ядро відправляє повідомлення на загальносистемний порт помилки, який підсистема часу виконання клієнт / сервер (Client / ServerRun-TimeSubsystem, Csrss) використовує для системи звіту про помилки Windows Error Reporting (WER) і запускає обробник виключень, який використовується за умовчанням. Цей оброблювач просто завершує той процес, чий потік став причиною виключення.

Поділитися в соц мережах:
Схожі
» » Диспетчеризація винятків