Проследяване на прекъсване и DPC
Можете да използвате инструмента ProcessExplorer за проследяване на прекъсване и DPC активност, като отворите диалоговия прозорец SystemInformation и отидете до раздела CPU, който ще покаже броя на прекъсванията и DPC процедурите, заснети всеки път, когато Process Explorer актуализира показаните резултати (по подразбиране на интервали от една секунда).
Можете също така да проследявате изпълнението на конкретни повиквания за прекъсване и чакащи процедури, като използвате вграденото проследяване на събития:
- Започнете да улавяте събития. Отворете прозорец на командния ред, преминете към директорията на Microsoft Windows Toolkit Performance (обикновено се намира в директорията 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 разбивката, за да видите обобщение, показващо времето, прекарано на ISR и DPC от всеки драйвер. Например, както е на снимката.
lkd> ln 0x806321C7
lkd> ln 0x820AED3F
lkd> ln 0x82051312
Ще ви бъде дадена възможност да разгледате по-отблизо всеки DPC и ISR на всеки водач, както и да видите продължителността и броя, както е показано на следващата фигура.
Механизмът за поточно предаване DPC е активиран по подразбиране, но може да бъде деактивиран чрез добавяне на нулева стойност DWORD към параметъра HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ SessionManager \ kernel \ ThreadDpcEnable. Тъй като поточните DPCs могат да бъдат деактивирани, разработчиците на драйвери, използващи поточни DPC, трябва да напишат своите съчетания, като следват същите правила, които се прилагат за повиквания без поточно предаване.
Тези подпрограми не могат да получат достъп до странична памет, да чакат изпращане или да правят предположения относно IRQL, при който се изпълняват. В допълнение, те не трябва да използват функциите на API KeAcquire/ReleaseSpinLockAtDpcLevel, тъй като функциите приемат, че процесорът е на ниво изпращане. Вместо това, при поточно извикване на DPC, използвайте функцията KeAcquire/ReleaseSpinLockForDpc, която изпълнява съответното действие след проверка на текущия IRQL.
Тъй като извикванията на APC са на опашка за изпълнение в контекста на конкретна нишка и се задействат при IRQL по-ниско от DPC/ниво на изпращане, те не подлежат на същите ограничения като DPC. Процедурата на APC може да получава ресурси (обекти), да изчаква манипулатори на обекти, да се справя с грешки при излизане на страницата и да извиква системни услуги.
APC повикванията се описват от обект за управление на ядрото, наречен APC обект. Изчакващите APC повиквания се поставят в управлявана от ядрото APC опашка. За разлика от DPC опашката, която е видима за цялата система, APC опашката е специфична за нишката - всяка нишка има своя собствена APC опашка. Когато е направена заявка за опашка на APC повикване, ядрото я вмъква в опашката, принадлежаща на нишката, която ще изпълни процедурата APC.
Ядрото от своя страна изисква прекъсване на софтуера на ниво APC и след това, когато нишката започне да работи след известно време, в нея се прави извикване на APC.