Відстеження активності переривань і dpc
Відео: Диявол може зіграти [ДМС]
Для відстеження активності переривань і DPC можна скористатися засобом ProcessExplorer, відкривши діалогове вікно SystemInformation (Системна інформація) і перейшовши у вкладку CPU (Центральний процесор), де буде показано кількість переривань і DPC-процедур, зафіксоване при кожному оновленні засобом Process Explorer відображаються результатів (по замовчуванням з періодичністю в одну секунду).
Можна також відстежити виконання конкретних процедур обслуговування переривань і відкладених викликів процедур, використовуючи вбудоване відстеження подій:
- Запустіть перехоплення подій. Відкрийте вікно командного рядка, перейдіть в каталог Microsoft Windows Performance Toolkit (зазвичай він знаходиться в каталозі c: Program Files) і наберіть наступну команду1: xperf -on PROC_THREAD + LOADER + DPC + INTERRUPT
- Зупиніть перехоплення подій, набравши наступну команду: xperf -d dpcisr.etl
- Згенеруйте звіти для перехоплення подій, набравши наступне: xperf dpcisr.etl tracerpt kernel.etl -report dpcisr.html -f html В результаті буде згенеровано веб-сторінка dpcisr.html.
- Відкрийте файл report.html і розкрийте підрозділ DPC / ISR. Розкрийте область DPC / ISR Breakdown і побачите зведення, що показує час, витрачений на ISR-процедури і DPC-виклики кожним драйвером. Наприклад, як на малюнку.
При запуску в отладчике ядра команди ln із зазначенням адреси кожного запису про подію показується ім`я функції, що виконує DPC або ISR:
lkd> ln 0x806321C7
(806321c7) ndis! NdisInterruptDpc
lkd> ln 0x820AED3F
(820aed3f) nt! IopTimerDispatch
lkd> ln 0x82051312
(82051312) nt! PpmPerfIdleDpc
Першим показаний DPC-виклик, поміщений в чергу драйвером міні-порту мережевої карти NDIS. Другим показаний DPC-виклик обробки закінчення часу загального таймера введення-виведення. Третій адреса відноситься до DPC-викликом, призначеному для виконання операції простою (idle).
Крім використання цього засобу для отримання звіту в форматі HTML, для перегляду докладного огляду всіх DPC- ISR-подій можна скористатися засобом Xperf Viewer, клацнувши в головному вікні Xperf правою кнопкою миші на пункті DPC and / or ISR CPU Usage graphs (Діаграми використання центрального процесора DPC та ISR) і вибравши пункт Summary Table (Зведена таблиця).
Вам буде дана можливість детально розглянути кожні DPC і ISR кожного драйвера, а також побачити тривалість і кількість, як показано на наступному малюнку.
Механізм потокових DPC-викликів включений за замовчуванням, але його можна відключити шляхом додавання нульового DWORD-значення в параметр HKEY_LOCAL_MACHINE System CurrentControlSet Control SessionManager kernel ThreadDpcEnable. Оскільки потокові DPC-виклики можуть бути вимкнені, розробники драйверів, які користуються потоковими DPC-викликами, повинні писати свої процедури, слідуючи тим же правилам, які поширюються на непотоковие виклики.
Ці процедури не можуть звертатися до вивантажується пам`яті, чекати диспетчеризації або вибудовувати припущення щодо IRQL-рівня, з яким вони виконуються. Крім того, вони не повинні використовувати API-функції KeAcquire / ReleaseSpinLockAtDpcLevel, оскільки функції припускають, що центральний процесор має рівень dispatch. Замість цього в потокових DPC-виклики потрібно використовувати функцію KeAcquire / ReleaseSpinLockForDpc, що виконує відповідну дію після перевірки поточного IRQL.
Переривання асинхронних викликів процедур. Асинхронні виклики процедур (Asynchronous procedure call, APC) дають призначеним для користувача програмам і системному коду спосіб виконання в контексті конкретного користувача потоку (а отже, в адресному просторі конкретного процесу).
Оскільки APC-виклики шикуються в чергу на виконання в контексті конкретного потоку і запускаються на IRQL-рівні, який є нижчим рівня DPC / dispatch, вони не підпадають під такі ж обмеження, які накладаються на DPC. APC-процедура може отримувати ресурси (об`єкти), чекати дескрипторів об`єктів, справлятися з помилками відсутності сторінки і викликати системні служби.
APC-виклики описуються об`єктом управління ядра, званим APC-об`єктом. APC-виклики, які очікують виконання, поміщаються в керовану ядром APC-чергу. На відміну від черги DPC, яку видно всій системі, APC-чергу відноситься до конкретного потоку - у кожного потоку є своя власна APC-чергу. При запиті на приміщення в чергу APC-виклику ядро вставляє її в чергу, належить тому потоку, який буде виконувати APC-процедуру.
Ядро, в свою чергу, запитує програмне переривання на APC-рівні а потім, коли потік через деякий час почне працювати, в ньому виконується APC-виклик.
Відео: ФССП | Чебоксари | Територія беззаконня: у судових приставів - всі громадяни терористи!
Існує два види APC-викликів: режиму ядра і призначеного для користувача режиму. APC-виклики режиму ядра не вимагають дозволу від цільового потоку на запуск в його контексті, а APC-виклики для користувача потоку вимагають такого дозволу. APC-виклики режиму ядра переривають потік і виконуються без його втручання або дозволу. Є також два види APC-викликів режиму ядра: звичайні та спеціальні. Спеціальні APC-дзвінки здійснюються на рівні APC і дозволяють APC-процедурі змінювати деякі APC-параметри.
Звичайні APC-дзвінки здійснюються на рівні passive і отримують змінені параметри від спеціальної APC-процедури (або вихідні параметри, якщо вони не були змінені).
Звичайні та спеціальні APC-виклики можуть бути відключені шляхом підвищення IRQL на APC-рівень або шляхом виклику процедури KeEnterGuardedRegion.
Вона відключає APC-доставку, встановлюючи поле SpecialApcDisable в структурі KTHREAD викликає потоку.
Потік може відключити звичайні APC-виклики тільки шляхом виклику процедури KeEnterCriticalRegion, яка встановлює поле KernelApcDisable в структурі KTHREAD потоку. У таблиці зведено поведінку кожного виду APC-виклику по вставці і доставці APC.
Вставка і доставка APC
Вид APC-виклику | Поведінка, пов`язане зі вставкою | Поведінка, пов`язане з доставкою |
---|---|---|
Спеціальний (режим ядра) | Вставляється в кінець списку APC-викликів режиму ядра | Доставляється на APC-рівні, як тільки знизиться IRQL, і за умови, що потік не перебуває в захищеній області. Даються покажчики на аргументи, певні при вставці APC-виклику |
Звичайний (режим ядра) | вставляється відразу ж після останнього спеціального APC-виклику (на чолі всіх інших традиційних APC-викликів) | Доставляється на рівні PASSIVE_LEVEL після виконання пов`язаного спеціального APC-виклику. Доставці задаються аргументи, повернуті пов`язаними спеціальним APC; викликом (це можуть бути вихідні аргументи, використані при вставці, або нові аргументи) |
Звичайний (призначений для користувача режим) | Вставляється в кінець списку APC-викликів призначеного для користувача режиму | Доставляється на рівні PASSIVE_LEVEL, як тільки знизиться IRQL, і за умови, що потік не перебуває в критичній (або захищеної) області, а також якщо потік знаходиться в стані готовності. доставці задаються аргументи, повернуті пов`язаними спеціальним APC-викликом (це можуть бути вихідні аргументи, використані при вставці, або нові аргументи) |
звичайний (Призначений для користувача режим) Вихід з потоку (PsExitSpecialApc) | Вставляється в початок списку APC-викликів призначеного для користувача режиму | Доставляється на рівні PASSIVE_LEVEL після повернення в призначений для користувача режим, якщо знаходиться в готовності до виконання в стані очікування. доставці задаються аргументи, повернуті спеціальним APC; викликом, завершальним потік |
Виконуюча система використовує APC-виклики режиму ядра для виконання роботи операційної системи, яка повинна бути завершена в адресному просторі (в контексті) конкретного потоку. Вона може використовувати спеціальні APC-виклики, щоб направити потік, наприклад, на зупинку виконання переривається системної служби або для запису результатів асинхронної операції введення-виведення в адресному просторі потоку.
Підсистеми середовища оточення використовують спеціальні APC-виклики режиму ядра, щоб змусити потік призупинити або завершити свою роботу, або ж отримати або встановити контекст його виконання в призначеному для користувача режимі. Підсистема для UNIX-додатків використовує APC-виклики режиму ядра для імітації доставки UNIX-сигналів процесам підсистеми для UNIX-додатків.
Інша важлива застосування APC-викликів режиму ядра відноситься до припинення або завершення потоку. Оскільки ці операції можуть ініціюватися довільними потоками і спрямовані на інші довільні потоки, ядро використовує APC для запиту контексту потоку, а також для завершення потоку.
Драйвери пристроїв часто блокують APC-виклики або входять в критичну або охоронювану область, щоб перешкодити виконанню цих операцій в той момент, коли вони утримують блокування, в іншому випадку блокування може бути ніколи не знята, і система зависне.
APC-виклики режиму ядра використовуються також драйверами пристроїв.
Наприклад, якщо ініційована операція введення-виведення і потік перейшов в режим очікування, може бути спланований запуск іншого потоку в іншому процесі.
Коли пристрій завершить передачу даних, система введення-виведення повинна якимось чином повернутися в контекст потоку, який ініціював введення-виведення, щоб він міг скопіювати результати операції введення-виведення в буфер в адресному просторі процесу, в якому знаходиться цей потік. Для виконання цієї дії система введення-виведення використовує спеціальний APC-виклик режиму ядра, якщо тільки додаток не використало API-функція SetFileIoOverlappedRange або порти завершення введення-виведення, - в такому разі або буфер в пам`яті буде глобальним, або копіювання його станеться тільки після того , як потік одержить від порту ознака завершення.
APC-виклики для користувача режиму використовуються декількома Windows API-функціями, такими як ReadFileEx, WriteFileEx і QueueUserAPC. Наприклад, функції ReadFileEx і WriteFileEx дозволяють зухвалому коду вказати підпрограму завершення, викликану при закінченні операції введення-виведення.
Завершення введення-виведення реалізується постановкою APC-виклику в чергу того потоку, який видав запит на введення-виведення. Але зворотний виклик процедури завершення не обов`язково відбувається при постановці APC-виклику в чергу, оскільки APC-виклики для користувача режиму доставляються потоку тільки в тому випадку, коли він знаходиться в готовності до роботи в режимі очікування.
Потік може увійти в режим очікування або в очікуванні дескриптора об`єкта і позначенні, що його очікування ведеться в готовності до роботи (за допомогою Windows-функції WaitForMulti pleObjectsEx), або шляхом безпосередньої перевірки на наявність відкладеного APC (за допомогою функції SleepEx). В обох випадках, якщо APC-виклик користувальницького режиму відкладений, ядро перериває (сповіщає) потік, передаючи управління APC-процедурі, і відновлює виконання потоку, коли APC-процедура завершить свою роботу. На відміну від APC-викликів режиму ядра, які можуть виконуватися на рівні APC, APC-виклики для користувача режиму виконуються на рівні passive.
Доставка APC може змінити порядок черг очікування, тобто змінити списки, в яких зазначено, які потоки, що і в якому порядку очікують. Якщо при доставці APC-виклику потік знаходиться в стані очікування, після завершення APC-процедури очікування повторно виставляється або виконується.
Якщо очікування все ще не дозволено, потік повертається в стан очікування, але тепер він буде в кінці списку щодо тих об`єктів, які їм очікуються. Наприклад, оскільки APC-виклики використовуються для припинення виконання потоку, якщо потік очікує якихось об`єктів, його очікування видаляється до тих пір, поки не відновиться виконання потоку, після чого цей потік буде в кінці списку потоків, які очікують доступу до об`єктів, яких він чекає. Потік, що виконує очікування в готовності до роботи в режимі ядра, буде також розбуджений при завершенні своєї роботи. Це дозволить такого потоку перевірити, розбуджений він в результаті завершення своєї роботи або з якоїсь іншої причини.