Программирование драйверов Windows

Торможение программных потоков


Одна из ошибок, приводящих к остановке программных потоков, состоит в том, что драйвер не завершает обработку IRP пакетов. В результате, поток пользовательского приложения, сделавший запрос, так и остается в состоянии ожидания. Это может быть обусловлено несколькими причинами.

Самая простая ошибка состоит в том, что драйвер по какой-то причине не выполняет вызов IoCompleteRequest. В результате, присланный IRP пакет никогда не возвращается Диспетчеру ввода/вывода. Иногда не столь очевидна необходимость сделать вызов IoStartNextPacket (при использовании очередей IRP пакетов). Однако даже если не существует запросов, ожидающих обработки, драйвер должен выполнить этот вызов, поскольку только таким образом объект устройства будет "помечен" как простаивающий. Без этого вызова новые IRP пакеты будут помещаться в очередь ожидания обработки, так и не поступая в процедуру StartIo драйвера.

Другая логическая ошибка, состоящая в попытке рекурсивно получить объект синхронизации или другие ресурсы исполнительной подсистемы, может остановить программный поток драйвера в одной из его рабочих процедур. Возможно, что другой фрагмент кода должен был освободить объект синхронизации, но так и не смог "добраться" до нужного места или "ушел по другой дороге". Последующие запросы только усугубляют ситуацию.

Аналогично, DMA драйверы могут остановиться в точке, где они сделали запрос на владение объектом адаптера. Драйверы, которые управляют сложными (составными) контроллерами, могут создать сходные проблемы в случае, если они не освобождают объект контроллера.

К сожалению, не существует безусловно хорошего способа решения таких проблем. Иногда полезно определить некую структуру данных, в которой все владельцы объектов синхронизации будут "отмечаться", когда они что-то используют, и удалять эти отметки, когда использование соответствующего объекта синхронизации прекращается. Разумеется, такой прием потребует дополнительных усилий, но он весьма эффективен в выявлении источника проблем.

Порой ошибки драйвера могут вызвать блокировку всей системы. Например, фатальную взаимоблокировку могут вызвать некорректное перекрестное использование нескольких объектов спин-блокировок или попытки повторно получить спин-блокировку на однопроцессорной платформе. Бесконечные циклы из кода процедур обслуживания прерывания или процедур DpcForIsr могут привести к аналогичному результату. Лучшим решением в данной ситуации было бы осуществление интерактивной отладки драйвера.



Содержание раздела