Введение в сбор дампов сбоев Windows — WER/ProcDump/WinDbg

· · Разработка Windows, Расследование ошибок, Дамп сбоя, WER, ProcDump, WinDbg

Когда у Windows-приложения начинаются «изредка случающиеся» падения, довольно часто одних логов недостаточно, чтобы докопаться до причины.

Особенно тяжело в таких случаях:

  • сбой происходит только в среде заказчика;
  • сообщение об исключении есть, но недостаточно контекста о том, откуда был вызов;
  • затронуты не только managed-часть на C# / .NET, но и COM, P/Invoke, нативные DLL, SDK сторонних производителей;
  • падение возникает только после долгой непрерывной работы.

В таких случаях выручают дампы сбоев (crash dump). Если сохранить состояние процесса в момент сбоя в файл, впоследствии можно прочитать код исключения, стек упавшего потока, загруженные модули, а также часть или всю память.

В Windows проще всего рассуждать в таком порядке: сначала LocalDumps из WER, при необходимости — Sysinternals ProcDump, а если хочется ещё большего контроля — MiniDumpWriteDump. В этой статье, ориентируясь на Windows-приложения для рабочего стола, резидентные приложения, службы Windows и инструменты интеграции с оборудованием, мы разбираем первые шаги сбора дампов сбоев.

1. Сначала — вывод

Сначала перечислим то, что важно усвоить в первую очередь.

  • Безопаснее всего начать с настройки WER LocalDumps на уровне приложения. Без дополнительных инструментов можно сохранять дамп локально после каждого сбоя.
  • Для расследований на площадке с низкой воспроизводимостью, а также если нужно видеть first chance exception / hang, используйте ProcDump.
  • Собственный сбор дампов стоит рассматривать в последнюю очередь — примерно таким и должен быть приоритет. Обращайтесь к MiniDumpWriteDump, только когда он реально понадобится.
  • Не менее важно, чем сами дампы, сохранять PDB и распространяемые бинарники. Один лишь дамп без символов резко сокращает объём того, что можно прочитать.
  • Полный дамп мощный, но столь же весом его размер и риск попадания в него конфиденциальных данных. Место хранения, число хранимых копий, права доступа и порядок передачи стоит определить заранее.

На начальном этапе рекомендуемая конфигурация обычно сводится примерно к следующему.

Среда Начальная конфигурация
Рабочая машина / тестовая машина Настроить WER LocalDumps на уровне приложения, начать с полного дампа DumpType=2
Среда заказчика / машина на площадке Выбрать DumpType=1 или 2 с учётом объёма и требований конфиденциальности. Добавить ProcDump только при необходимости
Долгая работа или расследование зависаний В дополнение к WER рассмотреть -h или -e 1 в ProcDump
Нужен собственный UI или прикреплённые логи Собственный сбор через MiniDumpWriteDump, рассчитанный на отдельный процесс

Иными словами: сначала WER, затем ProcDump, и только потом — собственная реализация. Если начать в обратном порядке, архитектура почти всегда становится излишне тяжёлой.

2. Что можно узнать из дампа сбоя

Дамп сбоя — это «снимок момента». Он больше похож на статичную фотографию места происшествия, чем на запись камеры видеонаблюдения.

Поэтому такую информацию получить довольно легко:

  • код исключения, с которым произошёл сбой;
  • какой поток упал;
  • стек вызовов на тот момент;
  • какие модули были загружены;
  • в зависимости от того, сколько памяти включено, — состояние кучи и содержимое объектов.

С другой стороны, некоторых сведений в одном лишь дампе обычно не хватает:

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

Поэтому на практике базовый подход — не пытаться обойтись одним дампом, а сочетать его с логами и heartbeat-сигналами.

3. Общая картина способов сбора

Для сбора дампов Windows-приложений на начальном этапе стоит знать четыре следующих способа.

Способ Подходит для Сильные стороны На что обратить внимание
WER LocalDumps Постоянно включённый базовый сбор при сбоях Встроен в Windows. Легко настраивается на уровне приложения В основном ориентирован на сбои. Слаб для зависаний и тонких условий срабатывания
ProcDump Расследования с низкой воспроизводимостью, зависания, first chance exception Много триггеров. Легко развернуть на площадке Требует эксплуатации внешнего инструмента
Создание дампа из диспетчера задач Ручной захват текущего состояния Можно получить на месте через GUI Не является автоматическим сбором
MiniDumpWriteDump Реализация собственной диагностической функции Легко объединить с прикреплёнными логами и собственными метаданными Небрежная реализация сама может стать источником проблем

Для новичка самое важное — это прежде чем решать «чем собирать», определить «при каких условиях», «куда» и «какого размера».

4. Первая рекомендация — WER LocalDumps

4.1 Значения реестра, на которые стоит посмотреть в первую очередь

В Windows Error Reporting (WER) есть механизм LocalDumps, который после сбоя сохраняет дамп пользовательского режима локально. Поскольку не нужно распространять дополнительные инструменты, это весьма удобный первый шаг.

Базовый раздел находится здесь.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps

Здесь можно разместить глобальную настройку, но на практике удобнее ориентироваться на подраздел уровня конкретного приложения.

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe

В первую очередь стоит обратить внимание на три значения.

Значение Значение параметра Рекомендация для начала
DumpFolder Место вывода дампа Выделить отдельную папку
DumpCount Число хранимых копий Начать примерно с 5–10
DumpType 0=custom, 1=мини, 2=полный Сначала 2, если места мало — 1

4.2 Пример настройки на уровне приложения

Например, если для MyApp.exe нужно сохранять до 10 полных дампов в C:\CrashDumps\MyApp, для начала можно настроить это так.

reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /v DumpFolder /t REG_EXPAND_SZ /d "C:\CrashDumps\MyApp" /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /v DumpCount /t REG_DWORD /d 10 /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /v DumpType /t REG_DWORD /d 2 /f

В этом примере важны четыре момента.

  • настройка ограничена MyApp.exe, а не глобальна;
  • вывод отделён в специальную папку;
  • сначала выбран полный дамп;
  • число хранимых копий ограничено десятью.

4.3 Проверка, что дамп действительно собирается

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

Стоит проверить четыре момента.

  1. Появляется ли .dmp в ожидаемой папке
  2. Соответствует ли размер эксплуатационным ожиданиям
  3. Открывается ли файл в WinDbg
  4. Виден ли сбой в журнале Application в средстве просмотра событий

5. Когда использовать ProcDump

WER часто оказывается достаточно, но есть ситуации, где удобен ProcDump.

  • нужно избежать постоянной настройки в реестре;
  • нужно отслеживать только уже запущенный процесс;
  • нужно начать отслеживание только со следующего запуска;
  • нужно видеть first chance exception;
  • нужно захватить зависание (hang);
  • нужен захват по счётчикам производительности или другим условиям.

5.1 Часто используемые опции

Если сузить круг до того, что реально пригождается на начальном этапе, для уверенной работы с ProcDump достаточно запомнить следующее.

Опция Значение
-ma Полный дамп
-mp Дамп MiniPlus
-e Дамп при необработанном исключении
-e 1 Дамп при исключении first chance / second chance
-h Дамп при зависшем окне
-w Ожидание запуска целевого процесса
-x Запуск целевого процесса и его отслеживание
-n Максимальное число дампов
-accepteula Автоматическое принятие первого запроса на подтверждение EULA

5.2 Типичные примеры команд

Полный дамп уже запущенного процесса при необработанном исключении

procdump -accepteula -ma -e 1234 C:\CrashDumps\MyApp

Ожидание следующего запуска и полный дамп при необработанном исключении

procdump -accepteula -ma -e -w MyApp.exe C:\CrashDumps\MyApp

Самостоятельный запуск и отслеживание

procdump -accepteula -ma -e -x C:\CrashDumps\MyApp MyApp.exe

Захват также first chance exception

procdump -accepteula -ma -n 3 -e 1 MyApp.exe C:\CrashDumps\MyApp

Захват зависания

procdump -accepteula -h MyApp.exe C:\CrashDumps\MyApp

5.3 Почему не стоит начинать с -i

У ProcDump есть и способ применения через -i — регистрация в качестве postmortem-отладчика. Это мощная возможность, но она затрагивает поведение всей машины в момент сбоя, поэтому в качестве самого первого шага на начальном этапе это несколько тяжеловесно.

Поэтому проще начать либо с настройки WER на уровне приложения, либо с -w / -x / указания PID в ProcDump.

6. Как подходить к собственному сбору через MiniDumpWriteDump

Собственный сбор подходит, например, в таких ситуациях:

  • нужна кнопка «Сохранить диагностическую информацию» в UI;
  • нужно объединить дамп с логами, настройками и trace ID;
  • нужно захватить заодно связанные дочерние или вспомогательные процессы;
  • перед загрузкой нужно применить собственное маскирование или сжатие.

Центральным API здесь выступает MiniDumpWriteDump.

Однако у него есть свои особенности. На начальном этапе особенно важно не упустить два момента.

  1. По возможности вызывать его из процесса, отличного от того, дамп которого делается
  2. Считать семейство API DbgHelp однопоточным по умолчанию

7. Как выбирать между мини-дампом, полным дампом и промежуточными размерами

Здесь застревает довольно много людей. Приведём практический подход к выбору в виде таблицы.

Тип Подходит для Плюсы На что обратить внимание
Мини-дамп Широкое включение по умолчанию, облегчённая передача Маленький размер, легко передавать Слабая глубина восстановления состояния
Полный дамп Приоритет — расследование причины, подозрение на нативные границы или кучу Максимум доступной информации Большой размер, повышенный риск попадания конфиденциальных данных
MiniPlus / Custom Мини-дампа не хватает, а полный слишком тяжёл Позволяет найти баланс Требует знаний для настройки

Рекомендация для новичков довольно простая.

  • на рабочих / тестовых машинах — полный дамп;
  • в среде заказчика выбирать мини или полный дамп исходя из условий эксплуатации;
  • при подозрении на повреждение памяти, проблемы в нативных DLL, COM, P/Invoke или аномалии состояния после долгой работы — склоняться к полному дампу.

8. Что стоит решить заранее в части эксплуатации

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

8.1 Как сохранять PDB и бинарники

Это самое важное.

  • точная версия распространяемых EXE / DLL;
  • PDB, соответствующие этой версии;
  • каким коммитом / каким конвейером сборки они были созданы;
  • информация о версии инсталлятора и распространяемых артефактов.

8.2 Куда выводить и сколько хранить

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

  • не оставлять дампы прямо на системном диске;
  • выделить отдельную папку;
  • ограничить число копий через DumpCount или -n;
  • разделить долгосрочное и первичное хранение.

8.3 Кому разрешён доступ

В полный дамп может попасть конфиденциальная или персональная информация.

  • настройки в открытом виде;
  • строки подключения;
  • токены и учётные данные;
  • бизнес-данные, с которыми работали непосредственно перед сбоем;
  • пути к файлам и имена пользователей.

Поэтому одновременно с проектированием «как собирать» нужно решить и то, «кому разрешено обращаться к дампам».

9. Кратчайший путь к анализу после получения дампа

После того как дамп получен, первые действия удивительно просты.

9.1 Установить WinDbg

Сегодня WinDbg легко установить из Microsoft Store или через winget.

winget install Microsoft.WinDbg

9.2 Открыть дамп

windbg -z C:\CrashDumps\MyApp\MyApp_YYMMDD_HHMMSS.dmp

9.3 Настроить символы

Сначала нужно включить публичные символы Microsoft, а затем добавить путь к собственным PDB.

.symfix C:\Symbols\Microsoft
.sympath+ C:\Symbols\MyApp
.reload

9.4 Сначала посмотреть автоматический анализ

!analyze -v

После этого по порядку проверяются:

  • какой код исключения;
  • какой модуль вызвал сбой (faulting module);
  • насколько далеко ваш собственный код виден в стеке;
  • нет ли подозрительных ожиданий или зависаний в других потоках, помимо потока с исключением.

10. Типичные подводные камни

10.1 Дамп собран, но нет PDB

Это встречается очень часто. Сам сбор дампа прошёл успешно, но материала для чтения не хватает. Проектирование хранения PDB стоит закладывать одновременно с настройкой сбора дампов.

10.2 Не проверены ACL папки DumpFolder

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

10.3 Непрерывный вывод полных дампов на системный диск рабочей машины

Это классический сценарий инцидента с нехваткой места. Ограничение числа хранимых копий и отделение папки вывода стоит закладывать с самого начала.

10.4 Попытка покрыть зависания целиком одним лишь WER

WER LocalDumps в первую очередь силён для сбоев. Для зависаний и first chance exception во многих случаях лучше подходит ProcDump.

10.5 Постоянно включённый -e 1 превращается в шторм исключений

First chance exception полезны, но их обычно очень много. Реалистичный подход — ограничивать число дампов, включать опцию на короткое время и сужать цель.

11. Итог

Дамп сбоя — весьма сильная точка наблюдения для отказов с низкой воспроизводимостью. Особенно если в Windows-приложении задействованы COM, P/Invoke, нативные DLL или длительная непрерывная работа, стоит с самого начала решить, «что останется после падения».

Рекомендуемый порядок прост.

  1. Сначала настроить WER LocalDumps на уровне приложения
  2. При необходимости добавить ProcDump
  3. Если требуется ещё больше контроля, использовать MiniDumpWriteDump, рассчитанный на отдельный процесс

Если двигаться в этом порядке, серьёзно промахнуться сложно.

12. Справочные материалы

  • [Сбор дампов пользовательского режима — приложения Win32 Microsoft Learn](https://learn.microsoft.com/ja-jp/windows/win32/wer/collecting-user-mode-dumps)
  • [ProcDump v11.1 - Sysinternals Microsoft Learn](https://learn.microsoft.com/en-us/sysinternals/downloads/procdump)
  • [MiniDumpWriteDump function (minidumpapiset.h) - Win32 Microsoft Learn](https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/nf-minidumpapiset-minidumpwritedump)
  • [User-mode dump files - Windows drivers Microsoft Learn](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/user-mode-dump-files)
  • [Анализ файла дампа пользовательского режима — Windows drivers Microsoft Learn](https://learn.microsoft.com/ja-jp/windows-hardware/drivers/debugger/analyzing-a-user-mode-dump-file)
  • [Установка отладчика Windows — Windows drivers Microsoft Learn](https://learn.microsoft.com/ja-jp/windows-hardware/drivers/debugger/)
  • [Symbol path for Windows debuggers - Windows drivers Microsoft Learn](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/symbol-path)
  • [!analyze (WinDbg) - Windows drivers Microsoft Learn](https://learn.microsoft.com/en-us/windows-hardware/drivers/debuggercmds/-analyze)
  • [Troubleshoot processes by using Task Manager - Windows Server Microsoft Learn](https://learn.microsoft.com/en-us/troubleshoot/windows-server/support-tools/support-tools-task-manager)
  • [Enabling Postmortem Debugging - Windows drivers Microsoft Learn](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/enabling-postmortem-debugging)

Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.

Реагирование на инциденты не заканчивается восстановлением — шаблон постмортема (предотвращения повторения) для небольших команд разработки

Считать инцидент закрытым сразу после исправления и извинений — гарантированный способ повторить его снова. Адаптируем blameless-постморт...

Эти страницы показывают тему статьи в более широком контексте услуг и решений.

Статья напрямую связана со следующими услугами.

Расследование ошибок и причин

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

Технические консультации и ревью дизайна

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

Частые вопросы

Вопросы, которые часто возникают при консультациях по теме статьи.

Что такое дамп сбоя (crash dump) и что по нему можно узнать?
Это состояние процесса в момент сбоя, сохранённое в файл, — что-то вроде статичного снимка места происшествия. По нему впоследствии можно посмотреть код исключения, упавший поток и его стек вызовов, загруженные модули, а в зависимости от того, сколько памяти включено в дамп, — даже содержимое объектов на куче. При этом временную последовательность событий, приведших к сбою, и внешнее состояние коммуникаций или оборудования по одному лишь дампу обычно восстановить сложно, поэтому на практике его принято сочетать с логами и heartbeat-сигналами.
Где настраивается LocalDumps в WER?
Настройка выполняется в реестре, в разделе HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps. На практике удобнее ориентироваться не на глобальную настройку, а на подраздел уровня конкретного приложения, например MyApp.exe. В первую очередь стоит обратить внимание на три значения: DumpFolder (место вывода), DumpCount (число хранимых дампов) и DumpType (тип дампа) — это позволяет сохранять дамп после сбоя локально, не распространяя дополнительных инструментов.
Что выбрать — мини-дамп или полный дамп?
Ориентир такой: на рабочих и тестовых машинах — полный дамп (DumpType=2), а в среде заказчика выбор между мини-дампом (DumpType=1) и полным делается с учётом объёма и требований к конфиденциальности. Если есть подозрение на повреждение памяти, проблемы в нативных DLL, COM, P/Invoke или аномалии состояния после долгой работы, выгоднее склоняться к полному дампу. Однако полный дамп получается большим по размеру и несёт риск попадания в него конфиденциальной информации — строк подключения, токенов и т. п., поэтому место хранения, число хранимых копий и права доступа нужно определить заранее.
Когда стоит использовать ProcDump?
WER LocalDumps по своей природе ориентирован на сбои, поэтому ProcDump подходит, когда нужно ещё увидеть зависания (hang) или first chance exception, когда хочется избежать постоянной настройки в реестре, или когда требуется отслеживать только уже запущенный процесс. Из типичных опций стоит знать -ma (полный дамп), -e (сбор при необработанном исключении), -h (обнаружение зависания), -w (ожидание запуска). Опция -e 1, нацеленная на first chance exception, обычно даёт много срабатываний, поэтому реалистичнее ограничивать число дампов через -n и использовать её кратковременно и точечно.

Об авторе

Страница с профилем автора статьи.

Го Комура

Представитель KomuraSoft LLC

Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.

Публичные ссылки

Вернуться в блог