Дело о случайном сбое IE

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

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

Иногда у меня получается выкроить время для описания случаев диагностики ошибок, с которыми я столкнулся лично. В процессе решения этих проблем я часто придумываю новые методики, которыми я могу поделиться с вами в моих презентациях и статьях из серии «Дело о необъяснимом …». На днях я успешно справился с ошибкой, которая заключалась в сбое работы Internet Explorer  (IE) при прочтении в нем веб-страницы:

Каждый раз, когда я сталкиваюсь со сбоями — вне зависимости от того, является причиной этого сбоя сама система или приложение — я всегда пытаюсь разобраться, почему это произошло. И во многих случаях мне хватает всего нескольких минут, чтобы обнаружить подсказки, указывающие на то, что причиной ошибки является надстройка, после чего я уже могу исправить ошибку, либо обойти ее. В большинстве случаев, когда речь идет о сбое приложения, процесс, вызвавший этот сбой, очевиден, и я просто запускаю Windbg (из пакета Debugging Tools for Windows, который поставляется с Windows SDK и Windows DDK), прикрепляю его к этому процессу и начинаю расследование.

Однако, в некоторых случаях ошибочный процесс не очевиден, как это было в случае, когда я столкнулся со сбоем IE. Причина этого заключается в том, что я работал с IE8, который использует многопроцессную модель, в которой различные вкладки располагаются в различных процессах:

Как обычно, у меня было открыто несколько вкладок, так что я должен был выяснить, какой из четырех запущенных процессов IE (в дополнение к родительскому экземпляру процесса) вызвал сбой. Я мог бы выбрать метод решения этой задачи «в лоб», проследив за каждым процессом и найдя ошибочный поток, но есть более простой и более короткий путь для идентификации нужного процесса.

Когда происходит сбой процесса, служба Windows Error Reporting (WER) запускает свой собственный процесс, называемый WerFault, в сеансе ошибочного процесса для того, чтобы отобразить диалоговое окно с сообщением об ошибке для пользователя, запустившего сеанс, и для генерации файла аварийного дампа. Для того, чтобы WerFault знал, какой именно процесс претерпел сбой, служба WER передает идентификатор нужного процесс (PID) на строку команды WerFault. Вы можете легко просмотреть эту строку команды с помощью Process Explorer. Поскольку у меня всегда запущен Process Explorer и соответствующий значок отображается в системном трее на панели задач, я щелкнул по этому значку для открытия этой утилиты и нашел процесс WER в дереве процессов:

Я дважды щелкнул на нем для открытия диалогового окна свойств процесса, и строка команды содержала ID проблемного процесса IE:

Теперь, когда я узнал, что мне нужен процесс 4440, я запустил Windbg, нажал F6 для открытия диалогового окна выбора процесса и дважды щелкнул на процессе 4440 Iexplore.exe. Следующим моим шагом было нахождение потока, который вызвал сбой, чтобы я мог исследовать его стек на наличие проблемной надстройки. В некоторых случаях для решения этой задачи вы можете обратиться к встроенной в Windbg функции эвристического анализа, которую вы можете вызвать с помощью команды !analyze, но на этот раз она не помогла. Однако, процесс нахождения проблемного потока все-таки довольно прямолинеен.

Во-первых, перейдите в меню View в Windbg и откройте диалоговые окна Processes and Threads и Call Stack, расположив их рядом друг с другом. Целью является нахождение потока, у которого есть функции, в именах которых присутствуют слова fault, exception, или unhandled. Вы можете быстро сделать это, выбирая каждый поток в окне Processes and Threads, нажимая Enter и затем просматривая стек, который появляется в окне Call Stack. После того, как я просмотрел первые несколько потоков, я нашел искомый поток, в названиях функций которого по всему стеку встречали указанные строки:

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

Это случается, когда DLL использует соглашение о вызове пропуска указателя кадра (FPO), которое в отсутствие информации о символах для DLL препятствует тому, чтобы отладчик стал искать кадры стека только по цепочке указателей кадра. Обратные адреса для вызванных потоком функций должны быть в стеке (если они не были затерты ошибкой, вызвавшей сбой), но эвристический алгоритм Windbg не смог определить их местонахождение.

У Windbg есть команда, которую вы можете использовать в таких случаях для поиска пропущенных кадров с адресами функций — команда Display Words and Symbols. Если вы производите отладку 32-битного процесса, то используйте dds версию этой команды, а если 64-битного процесса — то dqs. Вы также можете использовать команду dps (Display Pointer Symbols), которая интерпретирует адреса функций в соответствующие размеры для 32-битных и 64-битных процессов. В качестве адреса, предоставляемого команде в качестве стартовой точки, нужно брать адрес фрейма стека, который расположен прямо над потерянным Windbg адресом. Чтобы увидеть этот адрес, нажмите кнопку Addrs в диалоговом окне стека вызовов:

Адрес рассматриваемого фрейма — 2cbc5c8:

Я передал его в качестве аргумента для dds и нажал Enter:

Первая страница с результатами содержала только одну функцию, KiUserException. Я снова нажал кнопку Enter, не введя никакой новой команды, поскольку команды для работы с адресами, такие как dds, подобное действие указывает Windbg повторить последнюю команду, начиная с того адреса, на котором она остановилась. Вторая страница выглядела уже интереснее и содержала имена DLL, с которыми я был не знаком:

Чтобы просмотреть информацию о версии модуля прямо из Windbg, можно воспользоваться командой lm (List Modules). Результат выполнения этой команды показал мне, что Yt.dll (именем DLL является текст слева от знака «!») являлся частью Yahoo Toolbar:

Это стало для меня неожиданностью, поскольку система, на которой произошел сбой, являлась мой домашней игровой системой, компьютером, который я приобрел всего несколько недель назад. Единственным программным обеспечением, которое я устанавливаю на моих игровых системах, является Microsoft Office и игры. Я не использую панели инструментов браузеров, а если бы я все таки сделал это, то выбрал бы Bing, а не Yahoo. Более того, дата создания DLL указывала на то, что ему более двух лет. Я очень внимательно просматриваю опции установщиков программ, так что вероятно эта панель инструментов появилась на моей системе через установку одной из утилит тестирования и отслеживания температуры видеокарты, которые я использовал для разгона системы. Я нахожу практику навязывания пользователям дополнительных опций весьма раздражающей, тем более когда пользователям даже не дают право выбора, как в данном случае. Пара минут работы с панелью задач и моя система освободилась от нежелательной и устаревшей панели задач.

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

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

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

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

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