Несколько недель назад моя жена мне пожаловалась, что ее компьютер под
управлением ОС Windows Vista не отвечает на самые обычные движения мышкой.
Приняв во внимание важность клиента, от которого поступила жалоба, я
незамедлительно принялся за устранение причины возникшей проблемы. Система не
зависала совсем, но была чрезвычайно медленной. Например, при нажатии на кнопку
Пуск появления соответствующего меню приходилось ждать по 30 секунд. Подозреваю,
что проблемы крылись в загрузке процессора и думаю решить их можно было
простой перезагрузкой. Тем не менее я понимал, что если не выясню основную
причину замедления системы, то в самом скором времени мне вновь придется
исполнять роль службы техподдержки для моей жены. В конце концов, это просто
было вопросом чести. Поэтому я засел за компьютер и стал разбираться.
Сначала я запустил
Process Explorer для того, чтобы выяснить какой процесс так подгружает
систему. После нескольких минут ожидания он все-таки появился, и я выяснил, что
таких процессов не один, а два, каждый из которых занимал по 50% ресурсов
процессора. Это были Iexplore.exe и Dllhost.exe. Как известно, Iexplore - это
Internet Explorer (IE) и я предположил, что проблема может состоять не в самом
броузере, а либо в DLL-модуле browser helper object (BHO) или средствах ActiveX,
либо в каком-то другом плагине, загруженном в IE. Аналогичным образом, так как
Dllhost.exe – это родительский процесс для DLL служащих COM серверами, виноват,
скорее всего, не он сам, а загруженный в него COM сервер. И тот и другой вариант
требовали более глубокого изучения и я решил начать с IE.
Чтобы получить возможность нормально работать, мне надо было получить
некоторое количество свободных ресурсов процессора. Поэтому я приостановил
выполнение Dllhost, нажав на него правой кнопкой в Process Explorer, и затем в
контекстном меню выбрав кнопку Suspend:
Предпринятые действия погрузили Dllhost в сон, и, как я и ожидал, освободили
около 50% процессорного времени. Это произошло потому что в системе был
установлен двухядерный процессор и чтобы занять все 100% доступных циклов,
процесс должен иметь, как минимум, два потока, с одним потоком на каждое ядро.
Большинство виденных мною проблем, вызывавших подтормаживание ЦП, были вызваны
работой одного потока.
Сам по себе процесс не выполняет кода, его выполняют потоки, и поэтому я
решил заглянуть внутрь процесса IE, с тем, чтобы определить, какой поток (или
потоки) активны. Я два раза кликнул по процессу Iexplore.exe в Process Explorer
для того, чтобы открыть его свойства, и переключился на вкладку Threads. Потоков
оказалось несколько, но доминировал лишь один:
Как я позже выяснил, Ieframe.dll был частью IE, но, чтобы точно в этом
удостовериться, я кликнул на кнопке модулей в общем меню и переключился на
вкладку Details:
Описание потока не содержало информации о его назначении, и поэтому я зашел с
другой стороны. Раньше я уже настроил Process Explorer на то, чтобы он получал
информацию о названиях отображаемых процессов с сервера Microsoft (сделать это
можно в Options->Configure Symbols). Поэтому Process Explorer показывал название
функции, где начиналось выполнение каждого потока. Иногда названия DLL или
определенной функции бывает достаточно, чтобы выяснить назначение выполняемого в
ней потока, либо узнать какая именно программа вызывает проблемы. В данном
случае, поток начинался в функции под названием
CTablWindow::_TabWindowThreadProc. Название функции подсказывает, что в ней
стартует главный поток закладки, но этого все еще недостаточно, чтобы прояснить,
по какой именно причине он выполняется столь интенсивно. Пришлось лезть еще
глубже, внутрь самого потока, и выяснять где именно он работает.
Чтобы посмотреть, к чему относится этот поток, я два раза кликнул по нему в
списке Threads для того, чтобы открыть диалог Thread Stack, показывающий
функции, находящиеся в стеке потока. Стек, по сути своей, это – история
выполнения, где каждая записанная функция вызывает функцию, находящуюся в этом
списке выше, а функция, находящаяся во главе списка, - это самая последняя (на
момент открытия диалогового окна Process Explorer) выполненная функция. Я
пролистал список в поисках свидетельств запуска DLL сторонних разработчиков или
плагинов Microsoft IE, поскольку именно они – наиболее вероятные кандидатуры на
роль авторов бага. В конечном итоге, я нашел следы, ведущие к Adobe Flash:
Для того, чтобы убедиться, что я не застукал Flash в тот момент, когда
процессор загружали другие компоненты, я закрыл и открыл диалоговое окно
несколько раз, но все указывало на Flash.
Первое, что я обычно делаю, когда думаю, что какое-то приложение вызывает
определенные сбои – это захожу на официальный сайт разработчика, чтобы получить
последнюю версию ПО. Поэтому я узнал в Process Explorer используемую мною версию
Flash.ocx и сверил ее с последней, доступной для скачивания на официальном
сайте. Версии оказались идентичны.
Я оказался в тупике. Не было никакой возможности узнать, где именно находится
баг – в самой Flash или, что более вероятно, в каком-то приложении, использующем
Flash, также, как не было и гарантии того, что баг не вернется вновь. Я
попытался выяснить, с какого сайта приходит глючный контент, и стал закрывать
вкладки одну за другой, но даже после того, как все они были закрыты, поток все
еще исполнялся.
В тот момент единственное, что мне оставалось сделать – это удалить Flash и
лишить свою жену полноценного веб-серфинга, либо закрыть IE и надеяться на то,
что ошибка больше не повторится. Я выбрал последний вариант и оставил вопрос
открытым. Однако позже такое поведение Flash на компьютере моей жены
повторилось, более того, я боялся, что подобное может произойти и на моей
машине. Надежда на то, что баг все-таки находится в самом Flash и связанное с
ней тщательное изучение официального сайта Adobe в поисках новых версий не
принесли результата, зато теперь я, по крайней мере, точно знал, что вызывает
зависания ЦП.
После этого я обратил свое внимание на проблему с Dllhost в надежде, что
здесь мне удастся достичь большего успеха. Process Explorer показывает
всплывающие подсказки, указывающие на компоненты, загруженные в хост-процессы,
такие как Svchost.exe, Rundll32, Taskeng.exe (хост-процесс планировщика задач в
Vista и Server 2008) и Dllhost.exe. Я навел мышь на Dllhost.exe для того, чтобы
посмотреть, какой COM сервер запущен:
Запущенной оказалась служба Thumbnail Cache COM, ответственная за создание
пиктограмм для фотографий и других медиафайлов в среде Explorer. Поскольку эта
служба является частью Windows, мне пришлось еще раз заглянуть внутрь процесса в
поисках подсказок. Я возобновил процесс, приостановленный мною ранее, и открыл
закладку со свойствами потоков, работающих внутри него:
Поток, который в данном случае занимал основную часть процессорного времени,
начинался в функции ObjectThread библиотеки Quartz.dll. Я посмотрел на его
свойства, и обнаружил еще одну DLL, DirectShow Runtime с ничего не говорящим
названием функции:
Затем я кликнул мышкой два раза чтобы взглянуть на стек потока:
Первые несколько функций находились в User32.dll и Ntdll.dll, основных
системных библиотеках Windows, однако фреймы под номерами 4-7 находились в
Sonicmp4demux.ax (".ax" – расширение, используемое преимущественно в фильтрах
DirectShow), стороннем приложении. Названия функций этого потока были
одинаковыми и изучать их не имело смысла, поскольку Microsoft symbol server
предоставляет информацию о компонентах только тех программ, которые входят в
комплект поставки Windows. Несколько раз обновив стек я убедился в том, что это
действительно был тот самый тормозящий процессор поток.
Теперь следовало проверить наличие новой версии этого программного
обеспечения. Однако, трудность состояла в том, что установить принадлежность
обнаруженной DLL какой-либо определенной программе оказалось сложнее, чем я
думал. Я открыл страницу просмотра информации о DLL для того, чтобы получить
сведения об установленной на компьютере версии, однако полученные подробности
ничего не дали:
Также не оказалось никаких указаний на программу со словом Sonic в названии
ни в меню Пуск, ни в Панели установки и удаления программ. Тогда я провел поиск
в Windows-Live и обнаружил, что эта программа является частью пакета программ
Roxio для работы с CD и DVD. И действительно, в меню Пуск обнаружилась папка
Roxio:
Я запустил программу от Roxio чтобы проверить номер ее версии и обнаружил в
ней модуль, отвечающий за проверку обновлений. Я его запустил, но это ничего мне
не дало:
Я для полной гарантии я решил проверить сайт Roxio и обнаружил там доступную
для скачивания более свежую версию, скачать которую модуль обновления не
предложил, может быть в связи с тем, что она не предлагала ничего нового:
В любом случае, я решил ее скачать (все 650 Мб!) и затем ждал около 15 минут,
пока приложение установится. Затем я снова сверил номер версии Sonicmp4demux.ax
с тем, что я нашел ранее во вкладке с информацией о DLL, и обнаружил, что передо
мной все тот же двухгодичной давности файл, с номером версии 1.4.402.60802:
Я мог бы, конечно, удалить эту программу, чтобы быть уверенным в том, что
проблема не повторится, но мне нравилась предлагаемая Roxio функциональность при
работе с DVD. Мне было, в общем-то, все равно, будет или нет Windows создавать
специальные пиктограммы для файлов в формате Roxio. Я даже не был уверен в том,
что вообще когда-либо видел их в Explorer – поэтому я решил убрать лишь Sonic
demultiplexer. Я мог бы поискать это название в реестре Windows, но это было бы
слишком прямолинейно, и, если бы мне не удалось обнаружить прямой ссылки, я
легко мог бы закончить тем, что поотключал бы гораздо больше того, на что
рассчитывал, и мог бы повредить систему.
Идеальным решением этой проблемы оказался Process Monitor. Поскольку я не мог
просто так сидеть и ждать, пока этот баг не появится снова, я задал на странице
History Depth в меню Options этой программы параметр отображения в один миллион
последних произведенных системой операций:
Также я включил поиск по фильтру и установил в нем путь C:\Windows\System32\Dllhost.exe,
свернул программу и вернул компьютер жене.
На следующий день я вернулся домой с работы, сел перед компьютером и при
помощи Process Explorer выяснил, что проблема с Dllhost.exe вернулась и этот
процесс снова съедает половину процессорного времени. Я ожидал, что из-за того,
что система является двухядерной, баг будет появляться снова и снова, но жена
сказала мне, что никаких подтормаживаний больше не заметила. Похоже оставшихся
процессорных ресурсов вполне хватало, чтобы скрыть признаки этой проблемы (еще
один повод покупки многоядерного процессора). Я развернул Process Monitor и
увидел, что он зафиксировал 114 000 операций с Dllhost. Естественно,
просматривать их все вручную не было никакого желания, поэтому я задал критерий
поиска "sonicmp4" и ближе к концу списка обнаружил ссылку на запрос Реестра:
Запрос относился к регистрации COM-объекта для процесса demultiplexer.
Поскольку объект COM принадлежал сторонней DLL, я был уверен, что его COM Class
ID (CLSID) не является частью внутреннего кода Windows, и поэтому я вернулся к
первой записи в списке и ввел поисковый запрос "A7DD215", который представлял
собой первые несколько символов имени CLSID. Поиск выявил соответствие на
несколько тысяч операций ранее:
CLSID оказался именем ключа Реестра внутри регистрации другого
COM-компонента. Я опять поискал в Windows-Live на предмет наличия сведений о
родительском CLSID и нашел
статью, в которой объяснялось, что данный ключ находится в той части, где
зарегистрированы фильтры DirectShow. Я вновь просмотрел стек потока чтобы
убедиться в том, что Dllhost считывал информацию именно оттуда:
Теперь я был уверен в том, что простое переименование ключа регистрации
фильтра Sonic предотвратит его использование. Я никогда не удаляю ключи реестра
в подобных случаях, чтобы предотвратить повреждение системы. Из трассировки мне
стало понятно, что генератор thumbnail-ов наткнулся на AVI файл, что и вызвало
загрузку Sonic demultiplexer даже несмотря на то, что сама Windows прекрасно
может справляться с такими файлами и, я уверен, сможет и в дальнейшем. После
уничтожения Dllhost и внесения необходимых изменений, я перешел в ту же папку,
удалил превьюшку и убедился в том, что никакой потери функциональности не
произошло. Затем при помощи Roxio я успешно записал DVD с большим количеством
AVI-файлов. Дело было закрыто.
Компьютер моей жены теперь снова можно использовать. И хотя мне не удалось
решить проблему с Flash, система больше не будет требовать немедленного
вмешательства с моей стороны – благодаря Process Explorer и Process Monitor.
Источник:
http://blogs.technet.com/markrussinovich/
Читай так же:
История пропавшего
автозапуска