Дело о медленной системе

Автор: Topol Четверг, Май 3rd, 2012 Нет комментариев

Рубрика: Операционные системы

Несколько недель назад моя жена пожаловалась мне, что Vista на ее настольном компьютере не реагирует на движение мышкой или ввод с клавиатуры. Принимая во внимание важность этого клиента, я тут же сел за компьютер, чтобы решить эту проблему. Система, как выяснилось, зависла не полностью, но ужасно тормозила. Например, когда я переместил курсор мыши на кнопку Start и нажал ее, то меню раскрылось секунд через тридцать. Я подумал, что что-то загружает процессор и эту проблему можно решить простым завершением сеанса или перезагрузкой, но я точно знал, что если я не выявлю причину столь низкой производительности и не решу ее, то, скорее всего, в ближайшем будущем моей жене вновь понадобится моя техническая помощь. В любом случае сдаваться на милость такой проблемы находится ниже моего достоинства. И поэтому я решил начать новое расследование.

Первое, что я сделал — это запустил Process Explorer, чтобы понять, какой процесс нещадно потреблял все ресурсы процессора. Через несколько минут томительного ожидания Process Explorer запустился и показал, что не один, а даже несколько процессов и потребляли все мощности процессора, каждый по 50%: iexplore.exe и dllhost.exe. Iexplore, как вы, наверное, догадались, это Internet Explorer (IE). Но я предположил, что причиной проблемы, скорее всего, является не сам IE, а один из BHO-объектов (абб. от browser helper object), элемент управления ActiveX или какой-нибудь плагин, загруженный в IE. Dllhost.exe является корневым процессом для COM сервера DLL-библиотек, так что проблема явно была не в самом процессе, а в COM-сервере, загруженном в процесс. Оба варианта требовали дальнейших изысканий.

Начать я решил с IE. В попытке высвободить немного вычислительной мощи, в рамках которой я бы смог действовать, я приостановил процесс Dllhost, кликнув по нему правой кнопкой в Process Explorer и выбрав в контекстном меню опцию Suspend:

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

Не процессы исполняют код — его исполняют потоки, поэтому мне надо было заглянуть внутрь процесса IE, чтобы увидеть какой поток или потоки запущены. Поэтому дважды щелкнув на процессе Iexplore.exe в Process Explorer, я переключился на вкладку Threads. Было запущено несколько потоков, но один доминировал в потреблении ресурсов процессора.

Из своего опыта я знаю, что Ieframe.dll является частью IE, но чтобы в этом убедиться, на закладке Threads я нажал кнопку Modules и перешел на вкладку Details.

Так как описание не помогло в определении предназначения потока, я решил обратиться к еще одной подсказке — функции запуска. Так как мой Process Explorer настроен на получение символов для образов Windows с сервера символов Microsoft, то Process Explorer сразу же показывал мне название функции, с которой начиналось исполнение потока. Иногда DLL или функции, с которой начинается поток, достаточно, чтобы понять назначение потока, ставшего причиной проблемы. В данном случае поток начинался с функции CTablWindow::_TabWindowThreadProc. Эта функция запускает основной поток вкладок, но причина, почему этот поток потреблял столько ресурсов, осталась загадкой. Нужно было копнуть еще глубже и проверить, где именно исполняется поток.

Чтобы узнать, что именно делает поток, я два раза щелкнул на списке потоков, чтобы открыть диалоговое окно стека потока, которое показывает функции в стеке потока. По сути, стек — это история запуска функций, в которой каждая указанная функция вызвана функцией, находящейся выше по списку, а самая первая в списке функция, была выполена потоком как раз перед тем как Process Explorer подключился к стеку. Я пролистал список, чтобы найти строки, которые бы указывали на обращение к сторонним DLL или плагинам IE, так как вероятность того, что ошибка была именно в них намного больше, чем если бы она была в самом IE. Действительно, я нашел ссылки, указывающие на популярный элемент управления ActiveX — Adobe Flash:

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

Первое, что я делаю, когда подозреваю, что какое-либо ПО вызывает проблему, это проверяю сайт производителя, чтобы убедится, что у меня последняя версия ПО. Я открыл режим просмотра DLL в Process Explorer и посмотрел версию Flash.ocx, потом я перешел на сайт Adobe, посмотрел на последнюю версию Flash. Они совпадали.

Я был в тупике. Я не мог понять, где кроется ошибка — в самом Flash или, что более вероятно, в Flash-приложении. Также не было никакой уверенности в том, что проблема снова себя проявит. Я пытался определить, на каком сайте присутствует Flash-контент, закрывая вкладки одну за одной, но даже когда я закрыл их все, поток все равно работал.

На данном этапе единственным возможным вариантом было удалить Flash или принудительно завершить процесс IE, чтобы избавится от чудовищной загрузки процессора, и надеяться, что больше это не повторится. Я выбрал последний вариант и дело осталось открытым. С тех пор, как я проводил это расследование, я сталкивался с таким поведением Flash как на своем компьютере, так и на компьютере жены, так что я неусыпно следил за сайтом Adobe на наличие обновлений. Я был разочарован тем, что не получил никакого фактического результата, но, по крайней мере, я знал, что вызывало загрузку процессора.

Теперь я вернулся к проблеме Dllhost с надеждой, что здесь мне удастся найти решение проблемы. В всплывающем окне Process Explorer показывает компонент или компоненты, загруженные в корневые процессы Svchost.exe (обслуживающий корневой процесс Windows), Rundll32 (корневой процесс аплетов панели управления), Taskeng.exe (корневой процесспланировщика заданий в Vista и Server 2008) и Dllhost.exe. Я навел мышку на Dllhost.exe, чтобы увидеть, какой COM-сервер запущен в рамках процесса .

Это был COM-сервер Thumbnail Cache, задачей которого является создание в Windows Explorer эскизов изображений и видео-файлов. Он является частью Windows, так что мне еще раз пришлось лезть внутрь процесса за дополнительными подробностями. Я снова запустил процесс Dllhost, который я приостановил ранее, и открыл страницу свойств потоков процесса.

В данном случае все мощности процессора потребляла функция ObjectThread из Quartz.dll. Я заглянул в ее свойства, и увидел, что это еще одна библиотека Windows, компонент DirectShow Runtime со стандартным именем функции:

Потом я снова дважды щелкнул на имени процесса, чтобы увидеть стек потока.

Первые несколько строчек содержали информацию о User32.dll и Ntdll.dll, основных системных библиотеках Windows, но в строчках 4-7 содержалась информация о Sonicmp4demux.ax (.ax — расширение, часто используемое фильтрами для DirectShow), стороннем компоненте. Имена функций в этих библиотеках были те же самые, что не имело никакого смысла, так как сервер символов Microsoft хранит символы только для ПО, поставляемого с Windows. Еще несколько захватов состояния стека подтвердили, что это был именно тот код, который вызывал столь серьезное потребление ресурсов.

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

Ни в меню Start, ни в списке установленных приложений не было ничего похожего на Sonic. Я искал в Windows Live по запросу «Sonic» и узнал, что это часть программного пакета авторинга от Roxio. Я поискал в меню Start и, конечно же, нашел папку Roxio.

Я запустил приложение от Roxio, чтобы узнать номер версии, и обнаружил, что приложение Creator имеет встроенную возможность по проверке обновлений. Я запустил его, но результата не получил.

На всякий случай я зашел на сайт Roxio и оказалось, что таки есть новая версия, которую встроенный загрузчик не предлагал просто потому, что обновление, согласно описанию, не предлагало ничего нового.

Я все равно его загрузил (все 640 Мб!) и ждал около 15 минут, пока пакет установится. Потом я проверил информацию о версии Sonicmp4demux.ax, но номер версии — 1.4.402.60802 — был идентичен тому, который я видел в режиме просмотра библиотек, а сам файл был двухлетней давности.

Я мог бы удалить программный пакет и проблема более никогда бы не появилась, но мне не хотелось терять пакет Roxio из-за его возможностей по авторингу DVD. Для меня не являлось трагедией, если я больше не буду получать значки форматов образов, связанных с Roxio, я даже не был уверен, что видел когда-либо таковой в Windows Explorer, поэтому я решил выключить только демультиплексор от Sonic. Я мог провести поиск в реестре по имени библиотеки, где она, конечно же, была зарегистрирована, но это грубый подход, и в случае существования непрямых или дублирующихся ссылок я мог легко довести до того, что перестало бы работать не только создание эскизов изображений и видео-файлов, но и что-то более серьезное.

Process Monitor — замечательный инструмент для подобной работы. Так как я не знал, когда именно проблема появится снова, на ее повторение могли понадобиться дни, я не хотел просто запустить программу и отдать ей на съедение всю виртуальную память, так что я ограничил глубину хранения истории в Process Monitor 1 миллионом событий.

Также я включил фильтр на поиск совпадений с адресом C:\Windows\System32\Dllhost.exe, свернул программу и пустил жену за компьютер.

На следующий день, когда я вернулся с работы и сел за компьютер, я увидел, что процесс Dllhost.exe снова потребляет около 50% времени процессора. Я предположил, что так как система двухъядерная, то эта проблема появлялась регулярно, однако, моя жена этого не замечала, так как оставшихся ресурсов было достаточно, чтобы скрывать это (еще одна хорошая причина покупать многоядерные процессоры!). В Process Monitor за это время было записано около 114000 операций с Dllhost, что было явно слишком много, чтобы изучить их все индивидуально. Я запустил поиск sonicmp4 и ближе к концу трассировки нашел ссылку на запрос в реестре.

Запрос является COM-объектом регистрации для мультиплексора. Так как COM-объект является сторонней библиотекой, то я был уверен, что COM Class ID (CLSID) не вписан жестко в Windows, так что я вернулся к началу трассировки и начал искать значение A7DD215 (первые несколько знаков данного CLSID). Поиск нашел совпадение на несколько тысяч операций раньше.

CLSID содержался в имени ключа реестра в еще одном регистраторе COM-объекта. Я провел поиск в Windows Live родительского CLSID и обнаружил эту статью в базе знаний Microsoft, в которой объяснено, в каком ключе реестра зарегистрированы фильтры DirectShow. Я взглянул на стек в поисках определенного запроса, чтобы убедится в том, что именно поэтому Dllhost проводил чтение оттуда.

Теперь я был уверен, что смогу просто переименовать ключ регистрации фильтра Sonic, чтобы предотвратить его использование. Я никогда не удаляю ключи реестра, когда провожу такого рода диагностику, просто на случай, если изменение заблокирует важную функциональность или каким-то образом нанесет вред системе. Из трассировок я видел, что генератор кэша эскизов столкнулся с AVI, который и вынудил генератор кэша загрузить демультиплексор от Sonic, а этот формат Windows явно может обработать и сама, так что я был уверен, что все продолжит и так работать. После уничтожения процесса Dllhost и внесения изменений, я открыл ту же папку, удалил эскизы и убедился, что, как я и предсказывал, уменьшения функциональности не произошло. После чего я успешно воспользовался Roxio для записи DVD с множеством AVI-файлов. Дело было закрыто.

Систему моей жены можно было использовать и хотя я не смог раскрыть причин столь серьезной загрузки процессора Flash-плагином, я, по крайней мере, знал причину, поэтому мог следить за обновлениями. Что более важно, решив часть дела по Dllhost, даже если Flash опять начнет сходить с ума, я сделал систему снова годной к использованию. Теперь моя жена более не будет сталкиваться с такими инцидентами. В очередной раз спасибо Process Explorer и Process Monitor.

Источник: thevista.ru

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты