вторник, 27 июля 2010 г.

Методика диагностики зависания приложения при shutdown-е

   Исходная позиция: есть некое приложение app.exe (Проблемное приложение), которое "подвисает" при завершении работы системы, в результате чего отображается окно "Программа не отвечает" (либо "Завершение программы").
   Задача: найти отчет на вопрос "почему".
   Цель: решить проблему (в идеале - навсегда).

   Достижение поставленной цели - это отдельная песня и здесь обсуждаться не будет :)
   Речь пойдет о методах и приемах, с помощью которых можно определить причину такого поведения приложения.

   Итак, сфокусируемся на решении озвученной задачи.

   Когда я впервые столкнулся с такой ситуацией, мне стало интересно - в чем же причина и решил разобраться. Но путь к истине оказался тернист :)

   Начал я с изучения матчасти. Результаты этого исследования изложены в [1]. Исходя из этого, получаем следующее "общее" решение: для ответа на поставленный вопрос нам нужны два дампа (полных, т.к. для определения проблемного потока минидампа недостаточно):
  • csrss.exe (Client Server Runtime Process) - нужен для идентификации потока Проблемного приложения, который не успел вложиться в норматив при обработке сообщения WM_QUERYENDSESSION/WM_ENDSESSION
  • самого Проблемного приложения - он нужен для анализа ситуации и решения проблемы
   И анализ полученных дампов ([3]).


   На самом деле есть еще одно универсальное решение - использование ядерного отладчика (Debugging Tools for Windows). Но для этого нужна вторая машина (можно обойтись и одной, если проблему можно воспроизвести на виртуальной машине). А это не всегда возможно.

   Хотя есть еще безотказный вариант - вручную создать полный краш-дамп системы (Complete Memory Dump) [5].


   Следующим шагом стал поиск утилиты, с помощью которой можно создавать дампы процессов при зависании во время завершения работы системы. При этом она должна удовлетворять следующим критериям:
  1. Возможность снятия дампа с процесса csrss.exe
  2. На момент воспроизведения проблемы она должна быть запущена (т.к. при shutduwn-е нет возможности создавать новые процессы)

   Из списка доступных способов снятия дампов ([4]) в описанной ситуации на практике наиболее удобными IMHO являются:
  • Написание собственного приложения, использующего MiniDumpWriteDump ([2])
  • Штатный Диспетчер задач на системах Vista+
  • Process Explorer v12.04 и выше


   Важно!
   Перед использованием, я бы рекомендовал обновить файл %SystemRoot%\System32\dbghelp.dll до версии из последнего пакета Debugging Tools. Т.к. как правило там лежит не самая свежая версия (по крайней мере в Windows XP). А старые версии этой библиотеки не записывали в дамп ID потока для описателей типа Thread.


Ссылки
[1] WM_QUERYENDSESSION и WM_ENDSESSION (Windows Shutdown)
[2] MiniDumpWriteDump Function
[3] Crash Dump Analysis
[4] How to Capture a Minidump: Let Me Count the Ways
[5] Forcing a System Crash from the Keyboard

Комментариев нет:

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