Задача: найти отчет на вопрос "почему".
Цель: решить проблему (в идеале - навсегда).
Достижение поставленной цели - это отдельная песня и здесь обсуждаться не будет :)
Речь пойдет о методах и приемах, с помощью которых можно определить причину такого поведения приложения.
Итак, сфокусируемся на решении озвученной задачи.
Когда я впервые столкнулся с такой ситуацией, мне стало интересно - в чем же причина и решил разобраться. Но путь к истине оказался тернист :)
Начал я с изучения матчасти. Результаты этого исследования изложены в [1]. Исходя из этого, получаем следующее "общее" решение: для ответа на поставленный вопрос нам нужны два дампа (полных, т.к. для определения проблемного потока минидампа недостаточно):
- csrss.exe (Client Server Runtime Process) - нужен для идентификации потока Проблемного приложения, который не успел вложиться в норматив при обработке сообщения WM_QUERYENDSESSION/WM_ENDSESSION
- самого Проблемного приложения - он нужен для анализа ситуации и решения проблемы
На самом деле есть еще одно универсальное решение - использование ядерного отладчика (Debugging Tools for Windows). Но для этого нужна вторая машина (можно обойтись и одной, если проблему можно воспроизвести на виртуальной машине). А это не всегда возможно.
Хотя есть еще безотказный вариант - вручную создать полный краш-дамп системы (Complete Memory Dump) [5].
Следующим шагом стал поиск утилиты, с помощью которой можно создавать дампы процессов при зависании во время завершения работы системы. При этом она должна удовлетворять следующим критериям:
- Возможность снятия дампа с процесса csrss.exe
- На момент воспроизведения проблемы она должна быть запущена (т.к. при 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
Комментариев нет:
Отправить комментарий