Администраторы среды Windows понимают, что обращения в службу технической поддержки — часть их работы. Но устранять неполадки можно значительно быстрее, а можно и вовсе избежать обременительных обращений в службу поддержки. За девять лет работы в качестве инженера в группе Global Escalation Services компании Microsoft я открыл для себя несколько инструментов, полезных при решении проблем с технической поддержкой. Начнем знакомство со средствами диагностики Microsoft с утилиты получения динамического дампа пользовательского режима (UMDH) для обнаружения и устранения утечек памяти.

Диагностика утечки памяти

UMDH (umdh.exe) — часть набора инструментов отладки для Windows, который можно загрузить по адресу www.microsoft.com/whdc/devtools/debugging/installx86.mspx#a. С помощью UMDH проще исследовать утечки памяти процесса, отыскивая компоненты, которым выделено больше всего памяти. UMDH можно использовать с операционными системами Windows Server 2008, Windows Server 2003, Windows 2000 Server, Windows Vista и Windows XP.

Недавно я использовал UMDH для решения проблемы утечки памяти у одного из пользователей. Судя по журналам системного монитора, утечка памяти процесса svchost.exe была достаточной, чтобы существенно снизить быстродействие компьютера. Однако по этой информации не удавалась определить, какие компоненты были связаны с утечкой, или узнать, какие функции выполняли эти компоненты. Нужные сведения можно собрать с помощью утилиты UMDH.

Этапы применения UMDH

Для диагностики утечки памяти с использованием UMDH следует выполнить несколько простых шагов.

  • С помощью программы gflags.exe включите параметр реестра Create user mode stack trace database. В этом режиме вызовы функций процесса и список модулей сохраняются в базе данных в ходе выполнения; затем UMDH записывает базу данных в выходной файл. Gflags устанавливается при загрузке набора инструментов Debugging Tools for Windows. Приведенный ниже образец команды gflags.exe активизирует параметр для процесса notepad.exe:

gflags.exe -i notepad.exe +ust

Команда устанавливает параметр реестра, который считывается операционной системой при запуске процесса и позволяет отслеживать потоки, выделяющие память внутри процесса. После активизации параметра с помощью gflags.exe нужно перезапустить процесс перед выполнением шага 3. Кроме того, не забудьте отключить параметр после завершения трассировки процесса утечки. Следующая команда отключает gflags.exe для процесса notepad.exe:

gflags.exe -i notepad -ust

  • Назначьте путь к базе данных Microsoft, размещенной в Internet. Благодаря символам информация о трассировке процесса выдается в удобном для чтения формате. Без символов в каждой строке выхода трассировки вместо настоящего имени dll будет указано слово module, а вместо имени функции — номер (более подробно о выходных данных трассировки см. ниже).

Чтобы активизировать символы, щелкните правой кнопкой мыши My Computer, выберите пункт Properties и вкладку Advanced Tab, а затем нажмите кнопку Environment Variables. В разделе System Variables щелкните New и введите в поле Variable name:

_NT_SYMBOL_PATH

В поле Variable value введите путь к символам srv*c:symbols* http://msdl.microsoft.com/download/symbols. UMDH будет использовать символьный путь для показа компонентов, ответственных за утечку памяти. Этот символьный путь действителен для Server 2008, Windows 2003, Windows 2000, Vista и XP.

  • Теперь можно сделать первый моментальный снимок UMDH. Для этого в командной строке нужно перейти в каталог, в котором установлены инструменты отладки. Затем введите команду вида:

c:debug>umdh -p:260-f: Notepad1.txt

В данном примере инструменты установлены в каталоге C:debug. Ключ -p: указывает идентификатор процесса с утечкой (его можно получить из системного монитора или диспетчера задач), а параметр -f: — имя, выбранное для первого файла моментального снимка.

  • Между первым и вторым моментальными снимками должно пройти достаточно времени, чтобы произошла утечка памяти. Во время ожидания между процессами можно увидеть величину утечки памяти с помощью системного монитора.
  • Сделайте второй моментальный снимок, например

c:debug>umdh -p:260-f: Notepad2.txt

  • Сравните два моментальных снимка, запустив команду

c:debug>umdh -v Notepad1.txt

Notepad2.txt >c:comparefiles.txt

Параметр -v указывает, что в итоговую сводку будет включена информация о размерах утечки памяти каждого потока между первым и вторым моментальными снимками (более подробно о потоках — далее). Нужно указать файл, в котором будут сохранены результаты сравнения моментальных снимков; в данном примере имя файла — comparefiles.txt.

В выводе предшествующей команды перечислены компоненты и вызовы функций, которые занимают больше всего памяти внутри процесса. Благодаря собранной подробной информации о процессе техническим консультантам проще обнаружить и устранить неполадки, а у системных администраторов появляется достаточно конкретной информации для дальнейшего анализа проблемы и возможного обновления двоичных файлов, связанных с утечкой.

Примечание об использовании UMDH: с помощью команд UMDH можно отслеживать процессы, связанные с программами и службами как Microsoft, так и других поставщиков; однако, чтобы определить компонент утечки, необходим соответствующий файл символов для этого компонента. Некоторые поставщики не публикуют свои символьные файлы; при отсутствии доступа к символьному файлу информация в выходном файле UMDH будет состоять лишь из загрузочного адреса компонента и не будет содержать имени компонента и выполняемой функции. Поэтому, чтобы получить осмысленные выходные данные от UMDH, следует указать по крайней мере файл символов Microsoft, как объяснялось выше.

Анализ выходных данных UMDH

Открыв выходной файл (comparefiles.txt на экране), в верхней части можно увидеть первый поток исполнения (именуемый для краткости «потоком») — две строки, за которыми расположена последовательность сгруппированных строк. Потоки представляют задачу, выполняемую внутри процесса; это компоненты и функции, которым выделена память. Для загрузки и выполнения каждого процесса требуется, чтобы он содержал по крайней мере один поток. Две верхние строки содержат сводную информацию потока, а группа строк под сводной информацией представляет каждую запись потока в этом процессе. Рассмотрим более подробно выходные данные и выясним, что они означают.

В первых двух строках набора потоков приведены сравнительные сведения об использовании памяти из двух моментальных снимков. Первое шестнадцатеричное число, +113 faf000, представляет разницу потребления памяти между первым и вторым моментальными снимками. Так, в нашем примере можно увидеть изменение на более чем 4,6 Гбайт памяти (113faf000–0 = 4,6 Гбайт). Преобразовать шестнадцатеричное значение можно с помощью калькулятора Windows в научном режиме (запустить калькулятор можно из меню Start или выполнив команду calc.exe).

Следующее число, 81df8, представляет количество выделений памяти. Шестнадцатеричное число 81df8 соответствует 531 960 выделениям. Большое количество выделений нормально, учитывая, что на поток приходится более 4 Гбайт памяти. Следующая часть, BackTrace8117, — внутренний идентификатор, присвоенный потоку операционной системой.

Поток в верхней части выходных данных UMDH — это поток, потребляющий больше всего памяти, поэтому именно с него начинается анализ утечки памяти. Каждый поток выходного файла содержит загрузочный адрес компонента (например, в первой записи — 77EDCA76), имя файла компонента (или имя DLL — ntdll в первой записи) и, сразу после восклицательного знака, выполненную функцию в DLL (например, !$$VProc_ImageExportDirectory).

Верхний поток в выходных данных UMDH

Выходные данные UMDH могут стать отправной точкой для диагностики. Пользователь может просматривать компоненты в выходном файле и при необходимости обновлять их. Если участвующие в процессе компоненты обновлены, а утечка сохранилась, необходимо обратиться в службу технической поддержки или продолжить самостоятельное исследование.

Использование информации UMDH

Можно еще более сузить область поиска и, возможно, решить проблему, проведя поиск в Internet. Например, я выполнил поиск с использованием информации из тестовых моментальных снимков UMDH — строки repdrvfs wmi leak. Термин wmi включен, потому что утечка произошла в процессе Windows Management Instrumentation (WMI); repdrvfs — потому что имя этого компонента находится вверху списка потоков (т. е. поток потреблял больше всего памяти) и повторялось несколько раз (т. е. DLL-библиотека repdrvfs вовлечена в потребление памяти). В результате поиска была обнаружена статья TechNet по адресу support.microsoft.com/kb/838884.

Конечно, с помощью UMDH нельзя устранить все неполадки, связанные с утечками памяти в приложениях. Однако, применяя UMDH для диагностики процессов с утечкой, можно собрать важную информацию, которая поможет специалистам службы поддержки сэкономить немало времени.