Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Параметр "Принудительно ожидающие запросы ввода-вывода" случайным образом возвращает STATUS_PENDING в ответ на вызовы драйвера к IoCallDriver. Этот параметр проверяет логику драйвера в реакции на значение STATUS_PENDING, возвращаемое из IoCallDriver.
Этот параметр поддерживается только в Windows Vista и более поздних версиях операционной системы Windows.
Осторожность Не используйте этот параметр для драйвера, если у вас нет подробных знаний об его работе и вы не удостоверились, что драйвер предназначен для обработки возвращаемых значений STATUS_PENDING при всех своих вызовах IoCallDriver. Выполнение этого параметра на драйвере, который не предназначен для обработки STATUS_PENDING со всех вызовов, может привести к сбоям, повреждению памяти и необычному поведению системы, которое может быть трудно отлаживать или исправлять.
Почему принудительно завершают незавершенные запросы ввода-вывода?
Драйверы более высокого уровня в стеке драйверов вызывают IoCallDriver для передачи IRP в драйверы нижнего уровня в стеке драйверов. Подпрограмма отправки драйвера в драйвере нижнего уровня, получающем IRP, может немедленно завершить IRP или вернуть STATUS_PENDING и завершить IRP позже.
Как правило, звонящий должен быть готов к обработке любого результата. Однако, поскольку большинство подпрограмм отправки немедленно обрабатывают IRP, логика STATUS_PENDING в вызывающем объекте не часто выполняется, и могут не обнаруживаться серьезные ошибки логики. Параметр Force Pending I/O Requests перехватывает вызовы IoCallDriver и возвращает STATUS_PENDING для проверки редко используемой логики вызывающего драйвера.
Когда вы используете принудительную постановку запросов ввода-вывода в ожидание?
Перед выполнением этого теста просмотрите архитектуру и исходный код драйвера и убедитесь, что драйвер предназначен для обработки STATUS_PENDING от всех вызовов IoCallDriver.
Многие драйверы не предназначены для обработки STATUS_PENDING на всех вызовах IoCallDriver. Они могут отправлять IRP конкретному хорошо известному драйверу, который гарантированно немедленно завершит IRP. Отправка STATUS_PENDING драйверу, который не обрабатывает его, может вызвать сбои драйверов и системных сбоев и повреждения памяти.
Как драйверы должны обрабатывать STATUS_PENDING?
Драйвер более высокого уровня, вызывающий IoCallDriver, должен обрабатывать возвращаемое значение STATUS_PENDING следующим образом:
Перед вызовом IoCallDriver драйвер должен вызвать IoBuildSynchronousFsdRequest для синхронной обработки IRP.
Если IoCallDriver возвращает STATUS_PENDING, драйвер должен ждать завершения IRP путем вызова KeWaitForSingleObject в указанном событии.
Драйвер должен ожидать, что IRP может быть освобожден, прежде чем менеджер ввода-вывода сигнализирует о событии.
После вызова IoCallDriver вызывающий объект не может ссылаться на IRP.
Какие ошибки обнаруживает форсированный ожидающий запрос ввода-вывода?
Опция принудительного ожидания ввода-вывода обнаруживает следующие ошибки в драйвере, который вызывает IoCallDriver и получает возвращаемое значение STATUS_PENDING:
Драйвер не вызывает IoBuildSynchronousFsdRequest для синхронной обработки.
Драйвер не вызывает KeWaitForSingleObject.
Драйвер ссылается на значение в структуре IRP после вызова IoCallDriver. После вызова IoCallDriver драйвер более высокого уровня не может получить доступ к IRP, если он не установил подпрограмму завершения, а затем, только если все драйверы более низкого уровня завершили IRP. Если IRP освободится, драйвер завершится сбоем.
Драйвер неправильно вызывает связанную функцию. Например, драйвер вызывает KeWaitForSingleObject и передает дескриптор событию (в качестве параметра object ), а не передает указатель на объект события.
Драйвер ожидает неправильного события. Например, драйвер вызывает IoSetCompletionRoutine, но ожидает внутреннего события, сигнализируемого собственной подпрограммой завершения, вместо ожидания события IRP, сигнализируемого Менеджером ввода-вывода, когда IRP завершается.
Принудительное ожидание изменений запросов ввода-вывода, представленных в Windows 7
Начиная с Windows 7, опция "Принудительное ожидание запросов ввода-вывода" стала более эффективной в принудительном выполнении путей кода с STATUS_PENDING в проверенных драйверах. В более ранних версиях Windows средство проверки драйверов вызывало задержку завершения IRP только при выполнении первого IoCompleteRequest для этого IRP. Это означает, что эффективность проверки Driver1 может быть сокращена поведением Driver2 из одного стека устройств. Driver2 может ожидать синхронного завершения операции, прежде чем вернуться в свою процедуру отправки к Driver1. Принудительная задержка завершения IRP происходит точно перед разворачиванием запроса ввода/вывода обратно в проверенный драйвер на пути завершения. Это означает, что кодовый путь STATUS_PENDING проверенного драйвера действительно выполняется, в то время как проверенный драйвер воспринимает задержку в завершении.
Активация этого параметра
Чтобы активировать принудительно ожидающие запросы ввода-вывода, необходимо также активировать проверку ввода-вывода. Вы можете активировать параметр "Принудительное ожидание запросов операций ввода-вывода" для одного или нескольких драйверов, используя Driver Verifier Manager или команду Verifier.exe в командной строке. Дополнительные сведения см. в разделе "Выбор параметров средства проверки драйвера".
Параметр "Принудительное завершение ожидающих запросов ввода-вывода" поддерживается только в Windows Vista и более поздних версиях Windows.
В командной строке
Чтобы активировать запросы ввода-вывода в состоянии ожидания, используйте флаговое значение 0x210 или добавьте его к текущему значению флага. Это значение активирует проверку ввода-вывода (0x10) и принудительное ожидание запросов ввода-вывода (0x200).
Рассмотрим пример.
verifier /flags 0x210 /driver MyDriver.sysПараметр будет активным после следующей загрузки.
Если вы пытаетесь активировать только Принудительное ожидание запросов ввода-вывода (проверка /флаги 0x200), Проверка драйверов автоматически включает как Принудительное ожидание запросов ввода-вывода (0x200), так и проверку ввода-вывода.
Вы также можете активировать или деактивировать выполнение ожидающих запросов ввода-вывода без перезагрузки компьютера, добавив параметр /volatile в команду. Рассмотрим пример.
verifier /volatile /flags 0x210 /adddriver MyDriver.sysЭтот параметр действует немедленно, но теряется при завершении работы или перезагрузке компьютера. Для получения подробной информации см. Использование изменяемых параметров.
Использование диспетчера проверки драйверов
- Запустите диспетчер проверки драйверов. В окне командной строки введите средство проверки .
- Выберите "Создать настраиваемые параметры" (для разработчиков кода) и нажмите кнопку "Далее".
- Выберите отдельные параметры из полного списка.
- Выберите проверку ввода-вывода и принудительное ожидание запросов ввода-вывода.
Если выбрать только Принудительное выполнение ожидающих запросов ввода-вывода, Диспетчер проверки драйверов напомнит вам, что требуется Проверка ввода-вывода и предложит включить ее для вас.
Просмотр результатов
Чтобы просмотреть результаты теста на принудительное ожидание запросов ввода-вывода, используйте расширение отладчика !verifier со значением флага 0x40.
Дополнительные сведения о !verifier см. в разделе !verifier документации Средства отладки для Windows.
Если на тестовом компьютере происходит сбой в результате теста принудительного ожидания запросов ввода-вывода, можно использовать команду !verifier 40 для поиска причины. В текущей трассировке стека найдите адрес IRP, который недавно использовался драйвером. Например, если вы используете команду kP , отображающую кадр стека для потока, можно найти адрес IRP среди параметров функции текущей трассировки стека. Затем запустите !verifier 40 и найдите адрес IRP. Последние трассировки ожидающего стека принудительно отображаются в верхней части экрана.
Например, следующая трассировка стека Pci.sys показывает ответ на запросы принудительного ввода-вывода. Тест не показывает никаких ошибок в логике Pci.sys.
kd> !verifier 40
# Size of the log is 0x40
========================================================
IRP: 8f84ef00 - forced pending from stack trace:
817b21e4 nt!IovpLocalCompletionRoutine+0xb2
81422478 nt!IopfCompleteRequest+0x15c
817b2838 nt!IovCompleteRequest+0x9c
84d747df acpi!ACPIBusIrpDeviceUsageNotification+0xf5
84d2d36c acpi!ACPIDispatchIrp+0xe8
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
817c6a9d nt!ViFilterDispatchPnp+0xe9
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
84fed489 pci!PciCallDownIrpStack+0xbf
84fde1cb pci!PciDispatchPnpPower+0xdf
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
817c6a9d nt!ViFilterDispatchPnp+0xe9
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
84ff2ff5 pci!PciSendPnpIrp+0xbd
84fec820 pci!PciDevice_DeviceUsageNotification+0x6e
84fde1f8 pci!PciDispatchPnpPower+0x10c
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
84d76ce2 acpi!ACPIFilterIrpDeviceUsageNotification+0x96
84d2d36c acpi!ACPIDispatchIrp+0xe8
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
84f7f16c PCIIDEX!PortWdmForwardIrpSynchronous+0x8e
84f7b2b3 PCIIDEX!GenPnpFdoUsageNotification+0xcb
84f7d301 PCIIDEX!PciIdeDispatchPnp+0x45
817b258f nt!IovCallDriver+0x19d
8142218e nt!IofCallDriver+0x1c
Трассировка стека показывает, что Acpi.sys пыталось завершить IRP 8f84ef00. Средство проверки драйверов проставило отложенное выполнение, поэтому Acpi.sys STATUS_PENDING вернулся в pci!PciCallDownIrpStack. Если этот вызов вызвал сбой, владельцу драйвера потребуется проверить исходный код pci! PciCallDownIrpStack и пересмотреть его, чтобы правильно обрабатывать STATUS_PENDING.