Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Механизм обнаружения взаимоблокировок следит за использованием драйвером ресурсов, которые необходимо заблокировать — спинлоки, мьютексы и быстрые мьютексы. Этот параметр средства проверки драйверов обнаружит логику кода, которая может вызвать взаимоблокировку в будущем.
Параметр "Deadlock Detection" средства Driver Verifier вместе с расширением отладчика ядра !deadlock является эффективным инструментом, чтобы убедиться, что код правильно использует эти ресурсы.
Обнаружение взаимоблокировок поддерживается только в Windows XP и более поздних версиях Windows.
Причины взаимоблокировок
Взаимоблокировка возникает, когда два или более потоков вступают в конфликт по поводу некоторых ресурсов таким образом, что выполнение невозможно.
Наиболее распространенная форма взаимоблокировки возникает, когда два или более потоков ожидают ресурса, принадлежащий другому потоку. Это иллюстрируется следующим образом:
| Поток 1 | Поток 2 |
|---|---|
| Принимает блокировку A | Принимает блокировку B |
| Блокировка запросов B | Блокировка запросов A |
Если обе последовательности происходят одновременно, поток 1 никогда не получит блокировку B, так как она принадлежит потоку 2, и поток 2 никогда не получит блокировку A, так как она принадлежит потоку 1. В лучшем случае это вызывает остановку потоков, а в худшем — приводит к тому, что система перестает отвечать.
Взаимоблокировки не ограничиваются двумя потоками и двумя ресурсами. Взаимоблокировки между тремя потоками и тремя блокировками распространены — и иногда возникают даже пятеричные или шестеричные взаимоблокировки. Эти взаимоблокировки требуют определенной степени "неудачи", так как они полагаются на ряд вещей, происходящих одновременно. Тем не менее, чем больше интервал между получением блокировок, тем выше вероятность их возникновения.
Однопотоковые взаимоблокировки могут возникать, когда поток пытается получить блокировку, которую он уже удерживает.
Общим знаменателем всех взаимоблокировок является то, что иерархия блокировки не соблюдается. Каждый раз, когда необходимо иметь несколько блокировок, приобретенных за раз, каждая блокировка должна иметь четкий приоритет. Если A принимается до B на одном этапе, а B — до C на другом, иерархия — A-B-C. Это означает, что A никогда не должно быть приобретено после B или C, и B не должно быть приобретено после C.
Иерархия блокировки должна следовать, даже если нет возможности взаимоблокировки, так как в процессе поддержания кода будет легко случайно появиться взаимоблокировка.
Ресурсы, которые могут привести к взаимоблокировке
Наиболее неоднозначные взаимоблокировки являются результатом собственных ресурсов. К ним относятся спин-блокировки, мьютексы, ускоренные мьютексы и ERESOURCE.
Ресурсы, которые сигнализируются, а не выделяются (например, события и порты LPC), обычно вызывают гораздо более неоднозначные взаимоблокировки. Конечно, это возможно, и это слишком часто случается, что код неправильно использует эти ресурсы таким образом, что два потока в конечном итоге будут бесконечно ждать завершения друг друга. Однако, поскольку эти ресурсы на самом деле не принадлежат одному потоку, невозможно определить непреднаправленный поток с какой-либо степенью достоверности.
Параметр "Обнаружение взаимоблокировок" средства проверки драйверов ищет потенциальные взаимоблокировки, связанные со спин-блокировками, мьютексами и фаст-мьютексами. Он не отслеживает использование ERESOURCEов и не отслеживает использование непренадлежащих ресурсов.
Эффекты обнаружения взаимоблокировок
Модули обнаружения взаимоблокировок в Driver Verifier находят нарушения иерархии блокировок, которые не обязательно происходят одновременно. В большинстве случаев эти нарушения выявляют пути кода, которые войдут в состояние взаимоблокировки, когда будет соответствующая возможность.
Чтобы найти потенциальные взаимоблокировки, средство проверки драйверов создает граф порядка приобретения ресурсов и проверяет циклы. Если бы вы создали узел для каждого ресурса и нарисуйте стрелку при каждом получении блокировки перед другой, то циклы путей будут представлять нарушения иерархии блокировки.
Driver Verifier (Средство проверки драйверов) выдаст синий экран при обнаружении одного из этих нарушений. Это произойдет до возникновения каких-либо фактических взаимоблокировок.
Замечание
Даже если конфликтующие пути кода никогда не могут произойти одновременно, они по-прежнему должны быть перезаписаны, если они связаны с нарушениями иерархии блокировки. Такой код — это «взаимоблокировка, которая вот-вот произойдет» и может привести к реальным взаимоблокировкам, если код немного изменить.
При обнаружении механизмом обнаружения взаимоблокировки нарушения будет выдана проверка ошибок 0xC4. Первый параметр этой проверки ошибок будет указывать на точное нарушение. Возможные нарушения включают:
Два или более потоков, участвующих в нарушении иерархии блокировки
Поток, который пытается эксклюзивно завладеть ресурсом, для которого он уже является общим владельцем (эксклюзивно принадлежащие ресурсы могут быть совместно использованы; общие ресурсы не могут быть использованы эксклюзивно).
Поток, который пытается захватить один ресурс дважды (самозаблокировка)
Ресурс, освобожденный без предварительного приобретения
Ресурс, выпущенный потоком, отличным от того, который приобрел его.
Ресурс, инициализированный более одного раза или не инициализированный вообще
Поток, который удаляется, всё ещё владея ресурсами
Начиная с Windows 7 проверяющий драйвер может предсказать возможные взаимоблокировки. Например, пытаясь использовать одну и ту же структуру данных KSPIN_LOCK как обычную спин-блокировку, так и в качестве стековой очереди спин-блокировок.
См. Проверку ошибок 0xC4 (DRIVER_VERIFIER_DETECTED_VIOLATION) для списка параметров проверки ошибок.
Мониторинг обнаружения взаимоблокировок
После обнаружения нарушения взаимоблокировки можно использовать расширение отладчика ядра !deadlock для точного изучения того, что произошло. Он может отображать топологию иерархии блокировок, а также стеки вызовов для каждого потока в момент первоначального захвата блокировок.
В документации пакета Debugging Tools for Windows имеется подробный пример расширения !взаимоблокировки, а также общие сведения о расширениях отладчика. Дополнительные сведения см. в разделе "Отладка Windows ".
Активация этого параметра
Замечание
Этот параметр несовместим с фаззингом задержки синхронизации ядра
Функцию обнаружения взаимоблокировок можно активировать для одного или нескольких драйверов с помощью диспетчера проверки драйверов или командной строки Verifier.exe. Дополнительные сведения см. в разделе "Выбор параметров средства проверки драйвера".
В командной строке
В командной строке параметр обнаружения взаимоблокировки представлен битом 5 (0x20). Чтобы активировать обнаружение взаимоблокировок, используйте значение флага 0x20 или добавьте 0x20 к значению флага. Рассмотрим пример.
verifier /flags 0x20 /driver MyDriver.sysФункция будет активна после следующей загрузки.
В Windows Vista и более поздних версиях Windows можно также активировать и отключить обнаружение взаимоблокировок без перезагрузки компьютера, добавив в команду параметр /volatile . Рассмотрим пример.
verifier /volatile /flags 0x20 /adddriver MyDriver.sysЭтот параметр действует немедленно, но теряется при завершении работы или перезагрузке компьютера. Для получения подробной информации см. Использование изменяемых параметров.
Функция обнаружения взаимоблокировок также включена в стандартные параметры. Рассмотрим пример.
verifier /standard /driver MyDriver.sysИспользование диспетчера проверки драйверов
Выберите "Создать настраиваемые параметры" (для разработчиков кода) и нажмите кнопку "Далее".
Выберите отдельные параметры из полного списка.
Выберите (проверьте) обнаружение взаимоблокировки.
Функция обнаружения взаимоблокировок также включена в стандартные параметры. Чтобы использовать эту функцию, в диспетчере проверки драйверов выберите "Создать стандартные параметры".