РАСЧЕТНО-ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
к курсовому проекту на тему:
Профилировщик приложений
Содержание
1. Введение
2. Аналитический раздел
2.1. Техническое задание
2.2. Обзор архитектуры Windows NT 5.x
2.3. Классификация драйверов
2.4. Общая структура Legacy-драйвера
2.4.1. Процедура DriverEntry
2.4.2. Процедура DriverUnload
2.4.3. Рабочие процедуры обработки IRP-пакетов
2.4.3.1. Заголовок IRP пакета
2.4.3.2. Стек IRP-пакета
2.4.3.3. Функция обработки пакетов IRP_MJ_CREATE
2.4.3.4. Функция обработки пакетов IRP_MJ_CLOSE
2.4.3.5. Функция обработки пакетов IRP_MJ_DEVICE_CONTROL
2.4.4. ISR – процедура обработки прерываний
2.4.5. DPC – процедура отложенного вызова
3. Конструкторский раздел
3.1. Legacy-драйвер
3.1.1. Процедура DriverEntry
3.1.2. DriverUnload
3.1.3. DispatchCreate и DispatchClose
3.1.4. DispatchDeviceControl
3.1.4.1. IOCTL_LAST_CLIENT
3.1.4.2. IOCTL_LOCK_INFO и IOCTL_UNLOCK_INFO
3.1.4.3. IOCTL_PROCESS_FIRST и IOCTL_PROCESS_NEXT
3.1.4.4. IOCTL_THREAD_FIRST и IOCTL_THREAD_NEXT
3.1.4.5. IOCTL_OPEN_THREAD
3.1.4.6. IOCTL_CLOSE_THREAD
3.1.4.7. IOCTL_GET_THREAD_CONTEXT
3.2. Пользовательское приложение
4. Технический раздел
4.1. Выбор операционной системы и среды программирования.
4.2. Интерфейс
4.3. Системные требования
5. Заключение.
6. Список использованной литературы.
1. Введение
Очень часто при разработке программного обеспечения возникает необходимость, проследить за его работой: сколько времени его потоки выполняются в режиме ядра, сколько – в пользовательском режиме, сколько времени они проводят в ожидании, а также количество переключений контекста из одного режима в другой. Всё это важно, так как каждый из режимов имеет свои особенности. В режиме ядра код выполняется быстрее, но существует потенциальная возможность повреждения данных/кода системы. В противоположность режиму ядра, пользовательский режим ограничен в предоставляемых ему сервисах так, чтобы его код не мог привести к краху системы. Для этой же цели в пользовательском режиме выполняются дополнительные проверки, позволяющие предотваратить выполнение вредоносных инструкций. Поэтому скорость выполнения кода пользовательского режима существенно ниже. Количество переключений контекста тоже влияет на скорость выполнения кода, так как это операция является довольно дорогостоящей (около 2000 тактов). Это было хорошо заметно при разработке лабораторных работ и курсового проекта по машинной графике: при рисовании изображения попиксельно с помощью функции SetPixel, скорость прорисовки была несоизмеримо меньше, чем при использовании буфера пользовательского режима, в который постепенно заносилась информация о цвете соответствующих элементам буффера пикселям. Это происходило засчёт того, что при использовании функции SetPixel происходило два переключения контекста (из пользовательского режима в режим ядра и обратно) на один пиксель, а при использовании буфера, хранящего контекстно независимое представление цвета, - те же два переключения, но один раз на прорисовку целого кадра.
Таким образом, возможность узнать вышеуказанную статистическую информацию о целевом программном обеспечении, позволит своевременно заметить так называемые «узкие» места в программе, которые мешают улучшению производительности приложения в целом.
2.1 Техническое задание
Целью представленного курсового проекта является разработка простого профилировщика приложений, который в себя включает:
Legacy-драйвер, который должен:
Периодически обновлять информацию о процессах и их потоках;
Предоставлять базовую информацию о процессах и их потоках;
Предоставлять аппаратный контекст выбранного потока;
Обеспечивать безопасное обращение к этой информации от нескольких пользовательских приложений-клиентов.
Пользовательское приложение, позволяющее:
Корректно устанавливать и удалять драйвер без необходимости перезагрузки системы;
Обращаться к драйверу с запросами для получении различной информации.
2.2 Обзор архитектуры Windows NT 5.x
В Windows приложения отделены от самой операционной системы. Код её ядра выполняется в привилегированном режиме процессора (режим ядра), который обеспечивает доступ к системным данным и оборудованию. Код приложений выполняется в непривилегированном режиме процессора (пользовательский режим) с неполным набором интерфейсов, ограниченным доступом к системным данным и без прямого доступа к оборудованию. Когда программа пользовательского режима вызывает системный сервис, процессор перехватывает вызов и переключает вызывающий поток в режим ядра. По окончании системного сервиса операционная система переключает контекст потока обратно в пользовательский режим и продолжает его выполнение.
Далее схематично показана та часть архитектуры Windows, которая затронута данным курсовым проектом. Здесь не указываются такие компоненты, как: процессы поддержки системы, процессы сервисов, подсистемы окружения, уровень абстрагирования от оборудования и поддержка окон и графики.
Пользовательские приложения — один из типов пользовательских процессов, выполняющихся в пользовательском режиме, в рамках которого они ограничены использованием непривилегированных инструкций.
DLL подсистем — в Windows пользовательские приложения не могут вызывать сервисы операционной системы напрямую, вместо этого они работают с одной или несколькими DLL подсистем, назначение которых заключается в трансляции документированных функций в соответствующие внутренние (и обычно недокументированные) вызовы системных сервисов.
Исполнительная система — содержит базовые сервисы операционной системы, которые обеспечивают управление памятью, процессами и потоками, защиту, ввод-вывод и взаимодействие между процессами.
Ядро — содержит низкоуровневые функции операционной системы, которые поддерживают, например, планирование потоков, диспетчеризацию прерываний и исключений. Оно также предоставляет набор процедур и базовых объектов, применяемых исполнительной системой для реализации структур более высокого уровня.
Драйверы — служат для расширения функциональных возможностей ядра.
2.3 Классификация драйверов
В отличие от пользовательского приложения, драйвер не является процессом и не имеет потока исполнения. Вместо этого управление драйверу передаётся в результате запроса на ввод/вывод от пользовательского приложения или драйвера, либо возникает в результате прерывания. В первом случае контекст исполнения драйвера точно известен - это прикладная программа. Во втором случае контекст исполнения может быть как известным, так и случайным - это зависит от контекста исполнения функции вызывающего драйвера. В третьем случае контекст исполнения случайный, поскольку прерывание (и, соответственно, исполнение кода драйвера) может произойти при выполнении любой прикладной программы.
По расположению в стеке драйверов:
Драйверы высшего уровня — получают запросы от пользовательского приложения и взаимодействуют с нижестоящими драйверами;
Промежуточные драйверы — получают запросы от вышестоящих драйверов и взаимодействуют с нижестоящими драйверами;
Драйверы низшего уровня — получают запросы от вышестоящих драйверов, осуществляют конечную обработку пакетов запросов.
Также выделяют понятие монолитного драйвера – драйвера высшего уровня, не взаимодействующего ни с какими другими драйверами.
В связи с усовершенствованием модели драйверов Windows (WDM – Windows Driver Model), в которой были добавлены поддержка Plug and Play и энергосберегающие технологии, драйвера стали разделять на:
Унаследованные драйвера (Legacy-драйвера, драйвера «в стиле NT») — драйвера, написанные в старом манере, без поддержки нововведений;
WDM-драйвера – драйвера, которые удовлетворяют всем требованиям расширенной модели WDM.
2.4 Общая структура Legacy-драйвера
Legacy-драйвер имеет следующие основные точки входа:
DriverEntry – процедура загрузки драйвера;
DriverUnload – процедура выгрузки драйвера;
Рабочие процедуры обработки IRP-пакетов;
ISR-процедура (Interrupt Service Routine) – процедура обработки прерывания;
DPC-процедура (Deferred Procedure Call) – процедура отложенного вызова.
2.4.1 Процедура DriverEntry
Данная процедура присутствует в любом драйвере и вызывается диспетчером ввода/вывода при загрузке драйвера.
Legacy-драйверы выполняют в ней существенно большую работу, нежели WDM-драйвера, так как они вынуждены выполнять работу процедуры AddDevice, обязательной для WDM-драйверов. Помимо решения инициализационных задач и регистрации точек входа рабочих процедур обработки поддерживаемых IRP-пакетов и процедуры выгрузки драйвера, здесь:
Определяется аппаратное обеспечение, которое драйвер будет контролировать;
Создаются объекты устройств (функция IoCreateDevice) для каждого физического или логического устройства под управлением данного драйвера;
Для устройств, которые должны быть видимы пользовательским приложениям, создаются символьные ссылки (функция IoCreateSymbolicLink);
При необходимости, устройство подключается к объекту прерываний. В случае, если ISR-процедура требует использования DPC-процедуры, то соответсвующий ей объект создаётся и инициализируется на этом этапе;
Выделение памяти, необходимой для работы драйвера.
2.4.2 Процедура DriverUnload
Диспетчер ввода/вывода вызывает данну процедуру при динамической выгрузке драйвера. Эта процедура выполняет действия, «обратные» тем, что выполняются в процедуре DriverEntry.
Для Legacy-драйверов характерны следующие шаги:
Для некоторых типов аппаратуры необходимо сохранить ее состояние в системном реестре, т.к. при последующей загрузке драйвера эти данные могут быть использованы;
Если прерывания разрешены для обслуживаемого устройства, то процедура выгружки должна запретить их и произвести отключение от объекта прерываний. Ситуация, когда устройство будет порождать прерывания для несуществующего объекта прерывания, неминуемо приведет к краху системы;