Как отслеживать потребление ОЗУ своим драйвером NT
От: LimyKurn  
Дата: 18.09.18 14:58
Оценка:
В диспетчере задач нету даже потребления ОЗУ процессом System. Причем, ЦП есть, а ОЗУ нет. То ли это от разгильдяйства, то ли это такой маркетинг (вроде автомобиля: "мощность двигателя — достаточная"), но может сыграть злую шутку с новичком, ну и мешает проверять драйвер на утечки
Хочется видеть все буферы памяти, которые выделяет и очищает драйвер.
Можно просто содержимое буферов видеть — но не так, что всю память системного процесса, а именно те, которые принадлежат драйверу.

Была идея сделать обертки для всех функций, который делают Allocate и Free, и считать, но идея неважная — усложнение, тормоза и т.п. Непонятно зачем изобретать велосипед, если оно уже должно быть.

Отладчик использую WinDbg — наверно там как-то можно?

Driver Verifier смотрел — но с ним еще разбираться... и не знаю, есть ли в нем это...
Re: Как отслеживать потребление ОЗУ своим драйвером NT
От: EreTIk EreTIk's Box
Дата: 18.09.18 16:38
Оценка: 10 (1)
Здравствуйте, LimyKurn, Вы писали:

LK>В диспетчере задач нету даже потребления ОЗУ процессом System. Причем, ЦП есть, а ОЗУ нет. То ли это от разгильдяйства, то ли это такой маркетинг (вроде автомобиля: "мощность двигателя — достаточная"), но может сыграть злую шутку с новичком, ну и мешает проверять драйвер на утечки


Там есть показатели использования Paged и NonPaged пулов:
  Скрытый текст


LK>Хочется видеть все буферы памяти, которые выделяет и очищает драйвер.

LK>Можно просто содержимое буферов видеть — но не так, что всю память системного процесса, а именно те, которые принадлежат драйверу.

Каждое выделение памяти вызовом ExAllocatePoolWithTag раскрашивается Tag'ом. Стоит придумать достаточно уникальный для своего драйвера и проблема решена.

LK>Была идея сделать обертки для всех функций, который делают Allocate и Free, и считать, но идея неважная — усложнение, тормоза и т.п. Непонятно зачем изобретать велосипед, если оно уже должно быть.


LK>Отладчик использую WinDbg — наверно там как-то можно?


Да, команда !poolfind

LK>Driver Verifier смотрел — но с ним еще разбираться... и не знаю, есть ли в нем это...


При настроенном Driver Verifier при выгрузке драйвера из-за утекшой памяти будет принудительный BSOD. В этот момент (или просто в момент работы системы) настроенный Verifier позволяет видеть call-stack'и выделений памяти — Use the !verifier 3 extension command to find out about the pool allocations.
Re[2]: Как отслеживать потребление ОЗУ своим драйвером NT
От: LimyKurn  
Дата: 18.09.18 16:42
Оценка:
Здравствуйте, EreTIk, Вы писали:

ETI>Здравствуйте, LimyKurn, Вы писали:


ETI>Там есть показатели использования Paged и NonPaged пулов:

Но это же от всех процессов и драйверов.

ETI>Каждое выделение памяти вызовом ExAllocatePoolWithTag раскрашивается Tag'ом. Стоит придумать достаточно уникальный для своего драйвера и проблема решена.

Придумать единый тэг для своего драйвера — это еще ладно. Но каждому вызову свой тэг?!

ETI>При настроенном Driver Verifier при выгрузке драйвера из-за утекшой памяти будет принудительный BSOD.

BSODы он действительно вызывает, судя по всему при малейших ошибках, но совершенно неинформативные. По крайней мере на самом экране ничего нет.
Отредактировано 18.09.2018 16:43 LimyKurn . Предыдущая версия .
Re[3]: Как отслеживать потребление ОЗУ своим драйвером NT
От: EreTIk EreTIk's Box
Дата: 18.09.18 16:59
Оценка:
ETI>>Там есть показатели использования Paged и NonPaged пулов:
LK>Но это же от всех процессов и драйверов.

Системные пулы расположены в адресном пространстве ядра, которое одно (почти) для всех процессов системы. Выделять из Paged и NonPaged пулов могут только драйвера или ядро под свои нужды.

ETI>>Каждое выделение памяти вызовом ExAllocatePoolWithTag раскрашивается Tag'ом. Стоит придумать достаточно уникальный для своего драйвера и проблема решена.

LK>Придумать единый тэг для своего драйвера — это еще ладно. Но каждому вызову свой тэг?!

Хорошим тоном является назначение каждому типу объекта (буфера) своего тега. Примеры можно посмотреть (и дополнить своими) в файле triage\pooltag.txt из директории WinDbg.

ETI>>При настроенном Driver Verifier при выгрузке драйвера из-за утекшой памяти будет принудительный BSOD.

LK>BSODы он действительно вызывает, судя по всему при малейших ошибках, но совершенно неинформативные. По крайней мере на самом экране ничего нет.

Вся нужная информация в отладчике — Use !analyze to display information about the bug check
Re[3]: Как отслеживать потребление ОЗУ своим драйвером NT
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 18.09.18 17:56
Оценка:
Здравствуйте, LimyKurn, Вы писали:

LK>BSODы он действительно вызывает, судя по всему при малейших ошибках, но совершенно неинформативные. По крайней мере на самом экране ничего нет.


Вам бы очень желательно вначале получше изучить матчасть. Судя по всему, Вы пытаетесь въехать в разработку драйверов галопом, интуитивно перенося навыки user-mode программирования. В ядре многое (точнее — почти все) очень по-другому.
Re[4]: Как отслеживать потребление ОЗУ своим драйвером NT
От: LimyKurn  
Дата: 18.09.18 18:44
Оценка:
Здравствуйте, EreTIk, Вы писали:

ETI>Хорошим тоном является назначение каждому типу объекта (буфера) своего тега.


Хороший тон я люблю. Но пока сам не попробовал — не представляю, насколько оно важно, и почему это нельзя заменить использованием бряков вместе с анализом памяти.
В любом случае, 4 байта — это адски мало. Даже, если отбросить всякую фигню типа отсутствие глобальной уникальности тэга.
2 байта под префикс драйвера, 2 байта под объект... Это никогда помнить не будешь.
Однозначно, нужно на каждый драйвер заводить таблицу: тэг и его значение в менее компактной форме
Причем, желательно встроить это в драйвер, чтобы в коде в итоге были не тэги, а развернутые значения. Это облегчит детект ошибок, например. Но актуализировать таблицу придется постоянно.

Была еще идея — придумать формат тэга, чтобы сам тэг нес какую-то информацию о том, где именно находится данный код (допустим, 1 байт будет идентификатором файла .cpp/.c) Но здесь еще больше таблиц и действий по их актуализации при написании.

Вообще, какие-то правила относительно именования этих тэгов есть?
На MSDN их вроде нет. Но это еще не дает уверенность, что система с таблицей не будет моим велосипедом. А ведь, будучи им, она куда меньше стоит.
Отредактировано 18.09.2018 18:50 LimyKurn . Предыдущая версия . Еще …
Отредактировано 18.09.2018 18:48 LimyKurn . Предыдущая версия .
Отредактировано 18.09.2018 18:47 LimyKurn . Предыдущая версия .
Отредактировано 18.09.2018 18:46 LimyKurn . Предыдущая версия .
Отредактировано 18.09.2018 18:45 LimyKurn . Предыдущая версия .
Re[5]: Как отслеживать потребление ОЗУ своим драйвером NT
От: EreTIk EreTIk's Box
Дата: 18.09.18 19:40
Оценка:
Здравствуйте, LimyKurn, Вы писали:

LK>Вообще, какие-то правила относительно именования этих тэгов есть?

LK>На MSDN их вроде нет. Но это еще не дает уверенность, что система с таблицей не будет моим велосипедом. А ведь, будучи им, она куда меньше стоит.

Обычно их перечисляют в одном месте, например так — https://github.com/Microsoft/Windows-driver-samples/blob/6c1981b8504329521343ad00f32daa847fa6083a/filesys/miniFilter/avscan/filter/utility.h#L24
По именованию: принято два символа использовать на драйвер, следующие два на тип выделяемого объекта. Символы записываются в обратном порядке, что бы в дампе памяти они имели осмысленный вид.
Re[6]: Как отслеживать потребление ОЗУ своим драйвером NT
От: LimyKurn  
Дата: 18.09.18 20:25
Оценка:
Здравствуйте, EreTIk, Вы писали:

ETI> следующие два на тип выделяемого объекта


Именно на тип, а не имя каждой переменной? Точно?
В таком случае задача создания таблицы (в данном случае — просто кучки дефайнов) сильно упрощается. Можно сделать готовую таблицу и в каждом новом драйвере просто заменять первые 2 байта (их в отдельный дефайн), ну и по надобности добавлять кастомные типы.
Но где же взять принятые сокращения для всех стандартных типов? Насобирать из официальных семплов?

И насколько недопустимо указывать тип без имени драйвера (например, ставить '__' вместо него)? Ничего такого не принято?
Отредактировано 18.09.2018 20:26 LimyKurn . Предыдущая версия .
Re[7]: Как отслеживать потребление ОЗУ своим драйвером NT
От: EreTIk EreTIk's Box
Дата: 19.09.18 06:25
Оценка:
Здравствуйте, LimyKurn, Вы писали:

LK>Здравствуйте, EreTIk, Вы писали:


ETI>> следующие два на тип выделяемого объекта


LK>Именно на тип, а не имя каждой переменной? Точно?


Строгих правил нет. Из triage\pooltag.txt:
FM?? - fltmgr.sys   - Unrecognized FltMgr tag (update pooltag.w)
FMac - fltmgr.sys   -       ASCII String buffers
FMas - fltmgr.sys   -       ASYNC_IO_COMPLETION_CONTEXT structure
FMcb - fltmgr.sys   -       FLT_CCB structure
FMcn - fltmgr.sys   -       Non paged context extension structures
FMcp - fltmgr.sys   -       Client port wrapper structure
FMcr - fltmgr.sys   -       Context registration structures
FMct - fltmgr.sys   -       TRACK_COMPLETION_NODES structure
FMdh - fltmgr.sys   -       Paged ECP context for targeted create reparse
FMdl - fltmgr.sys   -       Array of DEVICE_OBJECT pointers
FMea - fltmgr.sys   -       EA buffer for create
FMfc - fltmgr.sys   -       FLTMGR_FILE_OBJECT_CONTEXT structure
FMfi - fltmgr.sys   -       Fast IO dispatch table


LK>В таком случае задача создания таблицы (в данном случае — просто кучки дефайнов) сильно упрощается. Можно сделать готовую таблицу и в каждом новом драйвере просто заменять первые 2 байта (их в отдельный дефайн), ну и по надобности добавлять кастомные типы.

LK>Но где же взять принятые сокращения для всех стандартных типов? Насобирать из официальных семплов?

Кроме семплов WDK примеры можно посмотреть (и дополнить своими) в файле triage\pooltag.txt из директории WinDbg.

LK>И насколько недопустимо указывать тип без имени драйвера (например, ставить '__' вместо него)? Ничего такого не принято?


В любом случае это только рекомендации, а не формальные требования.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.