Литмир - Электронная Библиотека
2.Внутреннее устройство Windows (гл. 5-7) - pic_129.png

B этом примере структуры CM занимают основную часть пула подкачиваемой памяти, а структуры MmSt (структуры, относящиеся к управлению памятью и используемые для проецируемых файлов) — основную часть пула неподкачиваемой памяти.

Описание меток пулов см. в файле \Program Files\Debugging Tools for Windows\Triage\Pooltag.txt. (Он устанавливается вместе с Windows Debugging Tools.) Поскольку в этом файле не перечислены метки пулов для сторонних драйверов устройств, используйте ключ — с в версии Poolmon, поставляемой с Windows Server 2003 Device Driver Kit (DDK), для генерации файла меток локальных пулов (Localtag.txt). B этом файле содержатся метки пулов, используемых любыми драйверами, которые были обнаружены в вашей системе. (Учтите: если двоичный файл драйвера устройства был удален после загрузки, метки его пулов не распознаются.)

B качестве альтернативы можно вести поиск драйверов устройств в системе по метке пула, используя утилиту Strings.exe. Например, команда:

strings \windows\system32\drivers\*.sys › findstr /i "abcd"

покажет драйверы, содержащие строку «abcd». Заметьте, что драйверы устройств не обязательно должны находиться в \Windows\System32\Drivers — они могут быть в любом каталоге. Чтобы перечислить полные пути всех загруженных драйверов, откройте меню Start (Пуск), выберите команду Run (Выполнить) и введите Msinfo32. Потом щелкните Software Environment (Программная среда) и System Drivers (Системные драйверы).

Еще один способ для просмотра использования пулов драйвером устройства — включение наблюдения за пулами в Driver Verifier (см. далее в этой главе). Хотя при этом способе сопоставление метки пула с драйвером не нужно, он требует перезагрузки (чтобы включить функциональность наблюдения за пулами в Driver Verifier для интересующих вас драйверов). После этого вы можете либо запустить Driver Verifier Manager (\Windows\System32\ Verifier.exe), либо использовать команду Verifier /Log для записи информации об использовании пулов в какой-либо файл.

Наконец, если вы изучаете аварийный дамп, то можете исследовать использование пулов и с помощью команды !poolused. Команда !poolused 2 сообщает об использовании пула неподкачиваемой памяти с сортировкой по структурам, занимающим наибольшее количество памяти, а команда !poolused 4 — об использовании пула подкачиваемой памяти (с той же сортировкой). Ниже приведен фрагмент выходной информации этих двух команд.

2.Внутреннее устройство Windows (гл. 5-7) - pic_130.png

ЭКСПЕРИМЕНТ: анализ утечки памяти в пуле

B этом эксперименте вы устраните реальную утечку в пуле подкачиваемой памяти в своей системе, чтобы научиться на практике применять способы, описанные в предыдущем разделе. Утечка будет создаваться утилитой NotMyFault, которую можно скачать по ссылке wwwsysintemals.com/windowsinternalsshtmL (Заметьте, что эта утилита отсутствует в списке инструментов на основной странице Sysinternals.) После запуска NotMyFault.exe загружает драйвер устройства Myfault.sys и выводит такое диалоговое окно.

2.Внутреннее устройство Windows (гл. 5-7) - pic_131.png

1. Щелкните кнопку Leak Pool. Это заставит NotMyFault посылать запросы драйверу устройства Myfault на выделение памяти из подкачиваемого пула. (He нажимайте кнопку Do Bug, иначе вы вызовете крах системы; предназначение этой кнопки описывается в главе 14, где демонстрируются различные типы аварийных ситуаций.) NotMyFault продолжит посылать запросы, пока вы не щелкнете кнопку Stop Leaking. Заметьте, что пул подкачиваемой памяти не освобождается даже при закрытии программы; в нем происходит постоянная утечка памяти до перезагрузки системы. Однако, поскольку утечка пула будет непродолжительной, это не должно вызвать никаких проблем в вашей системе.

2. Пока происходит утечка памяти в пуле, сначала откройте диспетчер задач и перейдите на вкладку Performance (Быстродействие). Вы увидите, как растет показатель Paged Pool (Выгружаемая память). To же самое можно увидеть в окне System Information утилиты Process Explorer. (Выберите Show и System Information.)

3. Чтобы определить метку пула, где происходит утечка, запустите Poolmon и нажмите клавишу b, чтобы сортировать по числу байтов. Дважды нажмите клавишу p для отображения в Poolmon только пула подкачиваемой памяти. Вы должны заметить, что пул с меткой «Leak» поднимается вверх по списку. (Poolmon выделяет строки, где происходят изменения.)

4. Теперь щелкните кнопку Stop Leaking, чтобы не истощить пул подкачиваемой памяти в своей системе.

5. Используя приемы, описанные в предыдущем разделе, запустите Strings (ее можно скачать с wwwsysinternals.com) для поиска двоичных файлов драйвера, содержащих метку пула «Leak»:

Strings \windows\system32\drivers\*.sys | findstr Leak

Эта команда должна указать на файл Myfault.sys.

Ассоциативные списки

Windows поддерживает механизм быстрого выделения памяти — ассоциативные списки (look-aside lists). Главное различие между пулом и ассоциативным списком в том, что из пула можно выделять блоки памяти различного размера, а из ассоциативного списка — только фиксированные. Хотя пулы обеспечивают более высокую гибкость, ассоциативные списки работают быстрее, так как не используют спин-блокировку и не заставляют систему подбирать подходящую область свободной памяти, в которой мог бы уместиться текущий выделяемый блок.

Функции ExInitializeNPagedLookasideList и ExInitializePagedLookasideList (документированные в DDK) позволяют компонентам исполнительной системы и драйверам устройств создавать ассоциативные списки, размеры которых кратны размерам наиболее часто используемых структур данных. Для минимизации издержек, связанных с синхронизацией в многопроцессорных системах, некоторые компоненты исполнительной системы, в том числе диспетчер ввода-вывода, диспетчер кэша и диспетчер объектов, создают отдельные для каждого процессора ассоциативные списки, из которых выделяется память под часто используемые структуры данных. Сама исполнительная система создает для каждого процессора универсальные ассоциативные списки подкачиваемой и неподкачиваемой памяти с гранулярностью выделения в 256 байтов или менее.

Если ассоциативный список пуст (как это бывает сразу после его создания), система должна выделить память из подкачиваемого или неподкачиваемого пула. Ho если в списке уже присутствует освобожденная структура, то занимаемая ею память выделяется очень быстро. (Список разрастается по мере возврата в него структур.) Процедуры выделения памяти из пула автоматически настраивают число освобожденных буферов, хранящихся в ассоциативном списке, в зависимости от частоты выделения памяти из этого списка драйвером или компонентом исполнительной системы. Чем чаще они выделяют память из списка, тем больше буферов в списке. Размер ассоциативных списков автоматически уменьшается, если память из них не выделяется. (Эта проверка выполняется раз в секунду, когда системный поток диспетчера настройки баланса пробуждается и вызывает функцию KiAdjustLookasideDepth.)

ЭКСПЕРИМЕНТ: просмотр системных ассоциативных списков

Содержимое и размер различных ассоциативных списков в системе можно просмотреть командой !lookaside отладчика ядра. Вот фрагмент вывода этой команды.

2.Внутреннее устройство Windows (гл. 5-7) - pic_132.png
2.Внутреннее устройство Windows (гл. 5-7) - pic_133.png
Утилита Driver Verifier

Driver Verifier представляет собой механизм, который можно использовать для поиска и локализации наиболее распространенных ошибок в драйверах устройств и другом системном коде режима ядра. Microsoft проверяет с помощью Driver Verifier свои драйверы и все драйверы, передаваемые производителями оборудования для тестирования на совместимость и включения в список Hardware Compatibility List (HCL). Такое тестирование гарантирует совместимость драйверов, включенных в список HCL, с Windows и отсутствие в них распространенных ошибок. (Существует и парная утилита Application Verifier, позволяющая улучшить качество кода пользовательского режима. Однако в этой книге она не рассматривается.)

40
{"b":"94486","o":1}