Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Объекты ядра — это примитивные объекты данных, которые ядро Windows реализует в системной памяти. Они представляют такие сущности, как устройства, драйверы, файлы, разделы реестра, события, семафоры, процессы и потоки.
Большинство объектов ядра не являются постоянными. Чтобы предотвратить удаление непостоянного объекта ядра Windows в то время, когда драйвер в режиме ядра его использует, драйвер получает подсчитываемую ссылку на объект. Если драйвер больше не нуждается в объекте, драйвер освобождает ссылку на объект.
Если драйвер не выпускает все ссылки на объект, число ссылок объекта никогда не достигает нуля, а диспетчер объектов никогда не удаляет его. Вы не можете повторно использовать утечки ресурсов до перезапуска операционной системы.
Другая ошибка ссылки возникает, если драйвер недостаточно ссылается на объект. В этом случае драйвер освобождает больше ссылок на объект, чем драйвер фактически содержит. Эта ошибка может привести к преждевременному удалению объекта диспетчером объектов, а другие клиенты по-прежнему пытаются получить доступ к объекту.
Утечки и недостачи объектов ядра — это ошибки, которые трудно отследить. Например, объект процесса или объект устройства может содержать десятки тысяч ссылок. В этих обстоятельствах может быть трудно определить источник ошибки ссылки на объект.
В Windows 7 и более поздних версиях Windows можно указать тег для ссылок на объекты, чтобы упростить поиск этих ошибок. Следующие подпрограммы связывают теги с приобретением и выпуском ссылок на объекты ядра:
ObDereferenceObjectDeferDeleteWithTag
ObReferenceObjectByHandleWithTag
ObReferenceObjectByPointerWithTag
Например, ObReferenceObjectWithTag и ObDereferenceObjectWithTag, которые доступны в Windows 7 и более поздних версиях Windows, являются расширенными версиями подпрограмм ObReferenceObject и ObDereferenceObject , которые доступны в Windows 2000 и более поздних версиях Windows. Эти расширенные подпрограммы позволяют предоставлять четырехбайтовое, настраиваемое значение тега в качестве входного параметра. Средства отладки Windows можно использовать для проверки трассировки ссылки на объект, содержащей значение тега для каждого вызова. ObReferenceObject и ObDereferenceObject не позволяют вызывающему объекту указывать настраиваемые теги, но в Windows 7 и более поздних версиях Windows эти подпрограммы добавляют теги по умолчанию (с значением тега "Dflt") в трассировку. Поэтому вызов ObReferenceObject или ObDereferenceObject имеет тот же эффект, что и вызов ObReferenceObjectWithTag или ObDereferenceObjectWithTag , указывающий значение тега Dflt. (В программе это значение тега отображается как 0x746c6644 или tlfD.)
Чтобы отследить потенциальную утечку объекта или проблему с ссылкой, определите набор связанных вызовов ObReferenceObjectXxxWithTag и ObDereferenceObjectXxxWithTag в вашем драйвере, которые увеличивают и уменьшают количество ссылок на определенный объект. Выберите общее значение тега (например, "Lky8") для всех вызовов в этом наборе. После того как драйвер завершит работу с объектом, число декрементов должно точно соответствовать количеству инкрементов. Если эти числа не совпадают, драйвер имеет ошибку ссылки на объект. Отладчик может сравнить количество добавок и уменьшений для каждого значения тега и сообщить, не совпадают ли они. Используя эту функцию, можно быстро определить источник несоответствия в числах ссылок.
Чтобы просмотреть трассировку ссылки на объект в средствах отладки Windows, используйте расширение отладчика в режиме ядра !obtrace . Если трассировка ссылок на объект включена, можно использовать расширение !obtrace для отображения тегов ссылок на объект. По умолчанию трассировка ссылок на объект отключена. Используйте редактор глобальных флагов (Gflags ), чтобы включить трассировку ссылок на объекты. Дополнительные сведения о Gflags см. в разделе "Настройка трассировки ссылок на объекты".
Выходные данные расширения !obtrace включают столбец Tag, как показано в следующем примере:
0: kd> !obtrace 0x8a226130
Object: 8a226130
Image: leakyapp.exe
Sequence (+/-) Tag Stack
-------- ----- ---- --------------------------------------------
36 +1 Dflt nt!ObCreateObject+1c4
nt!NtCreateEvent+93
nt!KiFastCallEntry+12a
37 +1 Dflt nt!ObpCreateHandle+1c1
nt!ObInsertObjectEx+d8
nt!ObInsertObject+1e
nt!NtCreateEvent+ba
nt!KiFastCallEntry+12a
38 -1 Dflt nt!ObfDereferenceObjectWithTag+22
nt!ObInsertObject+1e
nt!NtCreateEvent+ba
nt!KiFastCallEntry+12a
39 +1 Lky8 nt!ObReferenceObjectByHandleWithTag+254
leakydrv!LeakyCtlDeviceControl+6c
nt!IofCallDriver+63
nt!IopSynchronousServiceTail+1f8
nt!IopXxxControlFile+6aa
nt!NtDeviceIoControlFile+2a
nt!KiFastCallEntry+12a
3a -1 Dflt nt!ObfDereferenceObjectWithTag+22
nt!ObpCloseHandle+7f
nt!NtClose+4e
nt!KiFastCallEntry+12a
-------- ----- ---- --------------------------------------------
References: 3, Dereferences 2
Tag: Lky8 References: 1 Dereferences: 0 Over reference by: 1
Последняя строка в этом примере указывает, что счетчики ссылок и разыменований, связанные с тегом "Lky8", не совпадают, и что результатом этого несоответствия является избыточная ссылка на один (то есть утечка).
Если результат был бы недосылкой, последняя строка выходных данных !obtrace может выглядеть следующим образом:
Tag: Lky8 References: 1 Dereferences: 2 Under reference by: 1
По умолчанию операционная система экономит память, удалив трассировку ссылки на объект после освобождения объекта. Сохранение следа в памяти даже после освобождения объекта может быть полезным при отслеживании недостаточной ссылки. Для этого средство Gflags предоставляет параметр "Постоянный", который сохраняет трассировку в памяти, пока компьютер завершает работу и запускается снова.
В Windows XP появилась трассировка ссылок на объекты. Так как изначально трассировка не включала теги, разработчикам пришлось использовать менее удобные методы для выявления ошибок ссылки на объекты. Отладчик может отслеживать ссылки на группы объектов, выбранные разработчиком по типу объекта. Единственный способ, которым разработчик мог определить различные источники, связанные с ссылками и разыменованиями объектов, — это сравнить их стеки вызовов. Хотя предыдущий пример !obtrace содержит только пять стеков, некоторые типы объектов, например объект процесса (EPROCESS), могут ссылаться и разыменовываться много тысяч раз. При наличии тысяч стеков для проверки может быть трудно определить источник утечки объекта или недостаточного упоминания без использования тегов.