Windows Анализ цепочки ожидания зависшего приложения

Может относиться для любой версии Windows

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
7,864
Реакции
6,621
При работе с операционной системой Windows случается ситуация, когда программа (процесс) зависает, другими словами просто перестает отвечать на запросы системы и/или пользователя. Если программа имеет графический интерфейс, то в заголовке основного окна к выводимому имени программы добавляется статус «не отвечает», и сам интерфейс при этом зачастую перестает отвечать на какие-либо запросы оператора и визуально как бы вуалируется.

outlook-not-responding.png

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


Почему приложения виснут? В общем случае основания для зависания могут быть разные, как внутренние, так и внешние. К внутренним относятся ошибки в коде самого приложения, к внешним же принадлежат события, случающиеся в других процессах, от которых может каким-либо образом зависеть работоспособность нашего приложения. Для выявления подобных зависимостей разработчики предложили нам в Windows Vista механизм под названием Обход Цепочки ожидания (Wait Chain Traversal (WCT)), который при помощи специализированных функций позволяет выявлять взаимоблокировки процессов, работающих в системе. В данной статье мы будем рассматривать инструментарий анализа цепочки ожидания зависшего приложения. В качестве подобного инструментария мы будем использовать одно из системных средств, которое носит название Монитор ресурсов.

Монитор ресурсов — системное приложение, являющееся надстройкой монитора производительности, которое отображает информацию об использовании аппаратных (процессор, память, диск, сеть) и программных (файловые дескрипторы, модули) ресурсов системы в реальном времени.

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

Запуск монитора ресурсов


Все действия данного раздела следует производить из-под учетной записи с правами локального администратора.

Для начала, Монитор ресурсов все же следует запустить :), и сделать это можно несколькими способами. Можно запустить его через панель «Выполнить», которая вызывается нажатием комбинации клавиш Win + R или через строку поиска, затем ввести команду «resmon».

resmon-start.png

Можно при помощи комбинации Ctrl + Shift + Esc вызвать Диспетчера задач, перейти на вкладку «Быстродействие» и нажать кнопку «Монитор ресурсов».

resmon-run.png

Анализ цепочки ожидания

Сразу после запуска откроется главное окно монитора ресурсов. Нам необходимо перейти к списку запущенных на данный момент в системе процессов, и сделать это можно несколькими способами, можно активировать вкладку «Обзор», затем раскрыть область «ЦП», а можно сразу перейти на вкладку «ЦП» и развернуть область «Процессы». После развертывания интересующей нас области, мы увидим список исполняющихся в данный момент в системе процессов. Как видно на скриншоте ниже, зачастую монитор ресурсов маркирует зависшие программы (процессы) красным цветом, однако данное правило действует не всегда. Если нажать на зависшем процессе (в нашем случае это Outlook.exe) правую кнопку мыши, то взору нашему предстанет контекстное меню:

wait-chain-application-hang.png

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

analyze-wait-chain.png

Если внимательно проанализировать все цепочки ожидания на скриншоте, приведенном выше, и сопоставить их друг с другом, то можно сделать вывод, что в нашем случае Outlook блокирует поток 4648 процесса с идентификатором 8160 и именем iexplore.exe, который на поверку оказывается ни чем иным как системным браузером Internet Explorer. Почему у нас появилась зависимость от Internet Explorer, я точно уже сказать не могу, потому как детали инцидента уже давно утеряны, однако могу лишь предположить, что в почтовом клиенте Outlook было открыто какое-либо вложение, которое потребовало функционала IE. Теперь перед нами встала задача попытаться разблокировать подвисшее приложение (Outlook) с минимальными потерями, в идеале хотелось бы продолжить функционирование в штатном режиме без повреждения рабочих данных. Для достижения данной цели можно поступить достаточно грубо и попросту завершить процесс (iexplore.exe), который блокирует наш основной подвисший процесс (Outlook.exe). Для этого, активируем чекбокс напротив надписи iexplore.exe (PID: 8160) поток 4648 и нажмем кнопку «Завершить процесс».

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

Есть и другой, менее разрешительный способ избавления от блокировки. Можно попробовать изучив проблему глубже, проанализировав все нисходящие цепочки ожидания процесса. Сначала выясняем, кто блокирует (iexplore.exe), потом спускаемся далее к виновному процессу и изучаем его цепочку ожидания и так далее. У нас появляется шанс, что следуя таким образом по дереву блокировок, нам, в конечном итоге, удастся найти первопричину блокировки. Но вот разблокируются ли все процессы вверх по цепочке, точно сказать не могу.
Но, вернемся к нашей проблеме.
После снятия блокирующих процессов программа может продолжать висеть. Причиной этого может быть блокировка ресурса, например программа может постоянно пытаться сохранить данные в файл, который заблокирован.

Начиная с Windows 8, функция «анализ цепочки ожидания» включена в состав диспетчера задач Windows.

Удивителен тот факт, что подобная, чрезвычайно полезная, функция не появлялась в операционной системе до версии Vista, ведь очевидно, что если бы подобный функционал был построен на использовании стандартных функций Windows API, то мы могли бы видеть его и ранее. Выходит, что функционал анализа цепочки ожидания зависшего приложения это не что иное как совершенно новый системный механизм, уже упоминавшийся нами выше и носящий название Обхода Цепочки Ожидания (Wait Chain Traversal (WCT)), позволяющий отлаживать заблокированные процессы и потоки и выявлять тупики. Цепочка ожидания — это причинно-следственная связь между событиями в системе, которая представляет собой последовательность чередующихся пар потоков и событий, каждый поток сопровождается событием, которого он ждет, а это событие, в свою очередь, сопровождается следующим потоком в цепочке, которому оно принадлежит, и так далее. Под событием в данном контексте мы подразумеваем любой тип объекта синхронизации, мьютекс, критическую секцию, COM, LPC/RPC ответ, сообщения и прочее. Поток ждет событие начиная с момента, когда он его запрашивает и заканчивая моментом, когда он им овладевает. Блокировка находится в собственности потока с момента получения её потоком и до момента, когда он её освобождает. Понятие «владение блокировкой» подразумевает блокировку, ожидающую когда поток-владелец её освободит. Таким образом, если поток А ожидает блокировку, которой владеет поток Б, то можно смело утверждать, что поток А ждет поток Б. WCT позволяет запросить цепочку ожидания для одного или нескольких потоков путем создания сессии через использование функций WCT, таких как OpenThreadWaitChainSession, GetThreadWaitChain, EnumProcesses и GetThreadWaitChain.

Основываясь на практических наблюдениях, могу с уверенностью утверждать, что далеко не во всех случаях монитору ресурсов удается построить цепочку ожидания зависшего приложения, иногда она оказывается пуста. Объясняется это тем фактом, что не все зависания зависят от других процессов/потоков. Например, если поток повис по своим внутренним причинам: кривой собственный код на бесконечном программном цикле какой-либо внутренней функции, такой как цикл for с кривым условием, sleep(), delay() и аналогичные.


Выводы
С появлением технологии обхода цепочки ожидания, в арсенале технического специалиста появился довольно действенный метод изучения цепочки ожидания зависшего приложения и разблокировки подвисших процессов. Конечно, по уму, при изучении инцидента стоило бы проанализировать более детально, какие именно функции потоков блокируют исполнение и чего именно они ждут, но это уже совершенно другой уровень и мы не ставили себе подобной цели при написании данной статьи. Тем не менее, теперь мы вооружены еще одним, достаточно простым, понятным и быстрым способом разблокировки зависшего (не отвечающего) процесса. Сам по себе способ не требует наличия углубленных технических знаний, а так же специализированных сторонних инструментов и опирается на штатное средство, монитор ресурсов (resmon), что является достаточно весомым преимуществом. Резюмируя, можно сказать, что использование функции «анализ цепочки ожидания» зависшего приложения достаточно эффективный способ устранения причины зависания процесса.
 
Последнее редактирование модератором:
Назад
Сверху Снизу