Чтение крэш-дампов с WinDbg + SOS ── практическое введение в анализ после сбора

· · WinDbg, SOS, Дамп сбоя, .NET, CSharp, Отладка, PDB, Расследование сбоев, Техническая консультация

В предыдущей статье «Введение в сбор крэш-дампов Windows» мы разобрали, как «собрать» дамп с помощью WER LocalDumps, ProcDump и MiniDumpWriteDump. Но сам по себе собранный дамп ничего не рассказывает. Он становится материалом для расследования только тогда, когда вы реально засучиваете рукава и разбираетесь, какой поток упал, почему упал или что именно удерживает память.

В этой статье, как продолжение сбора, мы сосредоточимся исключительно на том, как реально читать собранный дамп в WinDbg с расширением SOS. Речь пойдёт об установке и настройке символов, о загрузке расширения SOS, обязательного для .NET-приложений, о том, «на что смотреть и как делать выводы» с помощью характерных команд вроде !clrstack и !dumpheap -stat, о !analyze -v для нативных сбоев, а также о том, когда вместо WinDbg стоит использовать dotnet-dump analyze.

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

  • Главный инструмент анализа дампов - WinDbg (актуальная версия, ранее называвшаяся WinDbg Preview). Его можно получить через winget install Microsoft.WinDbg или из Microsoft Store, он работает на x64/ARM64 начиная с Windows 10 Anniversary Update (1607) и на Windows 11.1
  • Даже без загруженных символов (PDB) команды !clrstack, !dumpheap -stat, !gcroot и подобные работают напрямую с метаданными CLR и данными кучи. Теряются только имена исходных файлов и номера строк managed-кода, а также имена символов для нативных фреймов. Впрочем, если нужно дойти до конкретной строки исходника, это уже другой разговор, и стандартная практика - указать в _NT_SYMBOL_PATH и публичный сервер символов Microsoft, и расположение собственных PDB.2
  • Для дампов .NET-приложений (Framework / Core / 5+) managed-информация становится видна только после загрузки расширения SOS. Одной лишь нативной командой k (вывод стека) код на C# не отследить.3
  • Есть три типовых сценария расследования. При падении из-за исключения - !clrstack!pe, при постоянном росте памяти - !dumpheap -stat!gcroot, при нативном сбое - !analyze -v.
  • Если хочется обойтись без WinDbg, есть вариант dotnet-dump analyze. Большинство команд SOS работают в нём как есть, но нативные стековые фреймы не обрабатываются. Для чисто managed-расследований, где не задействованы нативные DLL или COM, это более лёгкий в установке вариант.4
  • Описанные здесь шаги - это «как читать», а не «как собирать». О способах получения дампа (WER / ProcDump / MiniDumpWriteDump) - в статье про сбор, а о проектировании сопоставления логов и дампа в момент сбоя - в статье «Проектирование, при котором логи и дампы сохраняются в момент сбоя».

2. Ставим WinDbg и настраиваем символы

2.1 Установка

Актуальную версию WinDbg можно поставить одним из следующих способов.1

winget install Microsoft.WinDbg

Через Microsoft Store устанавливается тот же самый движок с идентичными командами, расширениями и рабочим процессом. После установки обновление происходит автоматически (в фоне - для установки через Store или напрямую, либо командой winget upgrade Microsoft.WinDbg - при установке через winget), так что разница в поведении между версиями почти не беспокоит.1

2.2 Открываем дамп

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

-z - опция, указывающая файл дампа для открытия при запуске. То же самое можно сделать из GUI через «File > Open Dump File».

2.3 Настраиваем путь к символам

Место, где отладчик Windows ищет файлы символов (PDB), задаётся переменной окружения _NT_SYMBOL_PATH либо командой .sympath внутри сессии.2 На практике базовый вариант - указать одновременно публичный сервер символов Microsoft и расположение собственных PDB.

.symfix C:\Symbols\Microsoft
.sympath+ C:\Symbols\MyApp
.reload
  • .symfix - это ярлык, задающий путь к публичному серверу символов Microsoft (https://msdl.microsoft.com/download/symbols) вместе с указанным локальным кэшем. Символы для стандартных DLL ОС загружаются оттуда автоматически.5
  • .sympath+ дописывает к существующему пути расположение собственных PDB. PDB для своего кода нужно готовить самостоятельно - на сервере символов Microsoft их нет.
  • .reload перезагружает символы и позволяет проверить их состояние в списке модулей.

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

set _NT_SYMBOL_PATH=srv*C:\Symbols\Microsoft*https://msdl.microsoft.com/download/symbols;C:\Symbols\MyApp

Правильно ли читаются символы, можно проверить командой lm (loaded modules), выведя список модулей и посмотрев, стоит ли у нужного модуля статус pdb symbols. Если он остался deferred, символы ещё не разрешены.

3. Загружаем расширение SOS

Для дампов .NET-приложений одних только нативных команд WinDbg недостаточно, чтобы увидеть содержимое managed-кучи, стековые фреймы C# и содержимое объектов исключений. Этот пробел закрывает расширение SOS (Son of Strike). Через команды SOS можно исследовать кучу, обнаруживать повреждение кучи, выводить внутренние типы данных runtime и оценивать состояние выполняющегося managed-кода.3

3.1 Разница между рантаймами

От того, .NET Framework перед вами или .NET (Core) / .NET 5+, зависит, какой рантайм нужно загрузить и откуда берётся SOS.

Цель Модуль рантайма Команда загрузки
.NET Framework clr.dll .loadby sos clr
.NET Core / .NET 5+ coreclr.dll .loadby sos coreclr

.loadby - команда, которая ищет DLL расширения (sos.dll) в той же директории, что и указанный модуль (clr или coreclr), и загружает её оттуда. Преимущество в том, что она надёжно подхватывает версию SOS, соответствующую окружению, в котором был снят дамп, без необходимости вводить полный путь.6

Начиная с версии 10.0.18317.1001 WinDbg и cdb, если отладчик обнаруживает, что целевой процесс загрузил coreclr.dll (или libcoreclr.so на Linux/macOS), расширение для .NET загружается автоматически из Microsoft Extension Gallery.6 Команда .loadby, приведённая выше, нужна для случаев, когда автозагрузка не срабатывает, или при использовании более старой версии отладчика.

3.2 Если SOS не находится

В окружениях, где автозагрузка не работает, SOS можно установить локально с помощью инструмента dotnet-sos.

dotnet tool install --global dotnet-sos
dotnet-sos install

После установки его также можно загрузить вручную прямо в WinDbg следующим образом (для старых отладчиков это может потребоваться).7

.load %USERPROFILE%\.dotnet\sos\sos.dll

3.3 Проверяем, что загрузка прошла

!sos.help

Либо можно попробовать !Threads для целей на базе Core или !sosstatus для целей на базе Framework - если команда не завершается ошибкой и что-то возвращает, загрузка прошла успешно. Если команда здесь падает с ошибкой вроде Unable to find module, почти наверняка причина - несовпадение пути к символам или рантайма (например, разница разрядности или версии между окружением, где снимался дамп, и локальным рантаймом). Застрять именно здесь, ещё до команд из следующей главы, - не редкость и на практике.

4. Читаем исключения и стек ── !clrstack и !pe

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

!threads

Сначала через !Threads (в среде lldb - псевдоним clrthreads) выводим список managed-потоков и проверяем колонку Exception для каждого.8 Если у какого-то потока есть исключение, переключаемся на него.

~5s
!clrstack

!CLRStack выводит трассировку стека только для managed-кода.9 Если нужно увидеть ещё и аргументы с переменными, добавляется -a (ярлык, объединяющий -l и -p).

!clrstack -a
  • Если видны методы собственного кода, по ним сразу читается, «где» и «по какому пути вызовов» произошло падение. Появление имени исходного файла и номера строки зависит от того, правильно ли загружены символы (глава 2). CLRStack перечисляет managed-фреймы напрямую из метаданных CLR, поэтому наличие или отсутствие символов никак не влияет на то, отобразится ли фрейм. При нехватке символов теряются только имя исходного файла и номер строки - сами фреймы никогда не пропускаются.9
  • Если не видно ни одного фрейма собственного кода, дело не в нехватке символов, а в одном из следующего: выбран не тот поток, у которого нет исключения (ошибка выбора потока); сбой произошёл целиком на нативной стороне, и managed-фреймов там попросту нет; либо тип дампа (например, Mini) не содержит на этот момент достаточно информации о стеке.

Далее смотрим сам объект исключения.

!pe

!PrintException (сокращённо !pe) без указанного адреса выводит последнее исключение, брошенное в текущем потоке. Можно получить имя типа, сообщение, внутренние исключения (отображаются через -nested) и даже строку трассировки стека.10 Чем меньше говорит само по себе имя типа - как у System.NullReferenceException, - тем сильнее нужно сверять его со значениями локальных переменных, видимыми через !clrstack -a.

5. Отслеживаем кучу и утечки ── !dumpheap -stat и !gcroot

Эти команды - центральные для расследований в духе «память понемногу растёт, и через часы или дни всё падает». Предварительный этап - отличение ожидания GC от настоящей утечки - подробно разобран в статье «Как отличить ожидание GC от утечки памяти в .NET». Эта статья - её продолжение, в части, где мы читаем один дамп и докапываемся до того, что именно удерживает память.

!dumpheap -stat

Опция -stat выводит только статистическую сводку по managed-куче. Типы выводятся примерно в порядке убывания количества экземпляров и суммарного размера, так что сначала можно выявить «тип, который давит объёмом».11 На практике часто встречаются два варианта:

  • Растёт сам бизнес-класс (например, сотни тысяч экземпляров MyApp.Models.Customer) - где-то есть сильная ссылка, продолжающая его удерживать
  • Аномально много только System.String или массивов - часто это внутренние данные бизнес-класса, стоящего выше в списке; обычно быстрее сначала заподозрить сам бизнес-класс, чем сразу разбирать отдельные экземпляры

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

!dumpheap -type MyApp.Models.Customer

И затем выясняем, почему этот объект так и не был собран сборщиком мусора.

!gcroot 000001a2b3c4d5e0

!GCRoot ищет по всей managed-куче и таблице хендлов и перечисляет корни (переменные на стеке, статические поля, GC-хендлы и т. д.), через которые можно дойти до указанного объекта.12 Если в выводе видно статическое поле, используемое как кэш, или подписку на обработчик события, это первый подозреваемый на незакрытую подписку. Типичный пример такого рода кода - «оставлено в кэше без освобождения»:

public static class CustomerCache
{
    // Статический словарь без пути очистки — только растёт
    private static readonly Dictionary<int, Customer> _cache = new();

    public static void Add(Customer c) => _cache[c.Id] = c;
}

Если в выводе !gcroot появляется статический контейнер вроде CustomerCache, это повод на стороне кода задуматься о сроке жизни записей, ограничении числа элементов или переходе на WeakReference.11

6. Автоматический анализ нативных сбоев ── !analyze -v

Для нативных сбоев (нарушения доступа к памяти и т. п.), связанных с DLL на C++, COM или SDK стороннего производителя, начинать нужно с этой команды.

!analyze -v

!analyze - команда расширения, выполняющая автоматический анализ сбоя или исключения; -v включает подробный вывод.13 В выводе стоит обратить внимание в первую очередь на три поля:

  • EXCEPTION_CODE / BUGCHECK_STR: какого рода аномалия произошла (нарушение доступа, переполнение стека и т. п.)
  • FAULTING_IP / FOLLOWUP_IP: адрес инструкции, на которой реально произошло падение, и соответствующий модуль/имя функции
  • MODULE_NAME / IMAGE_NAME: собственный ли это модуль или DLL стороннего производителя

Если падение происходит не в собственном модуле, а внутри DLL вендора, чтобы продвинуться дальше, нужен PDB этого вендора (обычно недоступный). На практике реалистичный итог расследования - подняться до места вызова (последних аргументов, переданных собственным кодом) и проверить, не были ли переданные значения некорректными. Поле STACK_TEXT в выводе !analyze -v покажет, что именно было вызвано из собственного кода непосредственно перед падением.

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

!analyze -hang

7. Вариант без WinDbg ── dotnet-dump analyze

Если нужно исследовать только managed-код .NET Core / .NET 5+ (без нативных DLL и COM), есть более лёгкий, чем WinDbg, вариант - dotnet-dump.

dotnet tool install --global dotnet-dump
dotnet-dump analyze C:\CrashDumps\MyApp\MyApp_20260702_101500.dmp

Подкоманда analyze открывает интерактивную сессию с предустановленным SOS, где большинство представленных здесь команд - clrstack, dumpheap, gcroot и другие - можно использовать напрямую, без префикса !.4

Ориентир для выбора между инструментами такой:

Аспект WinDbg + SOS dotnet-dump analyze
Нативные стековые фреймы Видны Не видны (только managed)4
Автоматический нативный анализ через !analyze -v Доступен Недоступен
Дампы с Linux Можно анализировать через WinDbg на Windows (для x64-дампов - x64-версия, для Arm64-дампов - x64-версия, для x86-дампов - x86-версия) Поддерживается (нужен инструмент той же разрядности, что и платформа)14
Дампы с macOS Не поддерживается (поддержка Linux-дампов в WinDbg не включает macOS) Поддерживается (.NET 5 и новее)4
Лёгкость установки Инсталлятор или winget Одна команда dotnet global tool
Встраивание в кросс-платформенный CI Требует усилий Проще

Практическая граница выбора: если «может быть замешан COM, P/Invoke или нативные DLL» - WinDbg; если это «расследование утечки памяти в чисто managed-коде, которое также должно работать в CI и на разных платформах» - dotnet-dump analyze. Оба инструмента используют общий набор команд SOS, поэтому команды, освоенные в одном, почти без изменений переносятся в другой. Учтите: если приходится иметь дело с дампом, снятым на macOS, WinDbg вообще не вариант, так что остаётся только dotnet-dump (или LLDB).

8. Без читаемых символов ничего не начинается

Часть описанных выше шагов вполне работоспособна и без корректно загруженных символов (PDB). Как отмечалось в главе 4, !clrstack, !dumpheap -stat и !gcroot читают метаданные CLR и данные кучи напрямую, поэтому сами фреймы и информация о типах отображаются даже без PDB. При отсутствии PDB теряются имена исходных файлов и номера строк managed-кода, а также имена символов для нативных фреймов и нативных модулей (вместо имени функции отображается только адрес). В ситуации, когда под рукой только дамп и исполняемый файл и хочется для начала просто понять, что случилось, вполне нормально начать с !threads!clrstack, не увязая заранее в поисках PDB. Тем не менее, если нужно дойти до строки исходника, чтобы точно локализовать причину, это уже другой разговор. В главе 2 мы добавили путь к собственным PDB через .sympath+, но на практике простое «неизвестно, где лежит PDB, соответствующий распространённому EXE/DLL» чаще, чем можно предположить по материалу статьи про сбор, останавливает расследование до того, как удаётся дойти до строки исходника.

О том, что именно содержит и не содержит PDB, о Portable PDB и о Source Link (механизме, который встраивает в сборку метаданные системы контроля версий, позволяя отладчику напрямую получать исходный код на момент соответствующего коммита), подробно рассказано в отдельной статье «Что такое PDB».15 Если анализ дампов встраивается в постоянную эксплуатацию, хранение PDB для каждой сборки и включённый Source Link - подготовка, не менее важная, чем сама настройка сбора дампов. Пренебрежёте этим - и вывод !clrstack вообще не покажет строк исходника, оставив вас с адресами и именами типов в качестве единственных зацепок.

9. Практический пример ── анализ дампа при расследовании утечки хендлов

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

  1. Через !dumpheap -stat подтверждаем, что managed-куча в порядке (количество и размер по типам не растут бесконтрольно)
  2. Если при этом количество хендлов процесса всё равно растёт, можно заключить, что утечка - это не managed-объекты, а OS-хендлы (файлы, события, хендлы, которые SDK камеры выделяет внутри себя, и т. п.)
  3. Если ещё жив managed-объект-обёртка, держащий SafeHandle, через !gcroot отслеживаем его GC-корень и находим место, где ссылка сохраняется там, где её следовало бы освободить

Иными словами, !dumpheap -stat работает как точка ветвления - определяет, идёт ли речь о росте managed-кучи, - а как только выясняется, что это не так, центр расследования смещается к инструментам обнаружения аномалий на нативной границе, вроде Application Verifier. О том, как строить такую базу для тестирования аварийных сценариев, рассказано в статье «Строим базу для тестирования аварийных сценариев Windows с Application Verifier». Анализ дампа отвечает за «состояние, в котором всё находится прямо сейчас», а Application Verifier - за «воспроизведение аномалии заранее»; использование обоих вместе - стандартная практика при расследовании сбоев после длительной работы.

10. Итог

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

  1. Ставим WinDbg и прописываем в пути к символам одновременно публичный сервер символов Microsoft и собственные PDB (глава 2)
  2. Для .NET-приложения загружаем расширение SOS (.loadby sos clr / .loadby sos coreclr, либо полагаемся на автозагрузку. Глава 3)
  3. Начинаем с !clrstack!pe при исключении, !dumpheap -stat!gcroot при росте памяти, !analyze -v при нативном сбое (главы 4-6)
  4. Если задача - чисто managed-расследование, стоит рассмотреть более лёгкий dotnet-dump analyze (глава 7)

И фундаментом для всего этого служит управление PDB и символами. Если решить вопрос хранения PDB для каждой сборки и включения Source Link одновременно с настройкой сбора дампов, время расследования при реальном инциденте изменится очень сильно. Если самостоятельный анализ затруднён или на него нет времени, вы всегда можете прислать нам дампы и логи целиком - мы проведём анализ сами.

Похожие статьи

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

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

Справочные ссылки

  1. Microsoft Learn, Install the Windows debugger. Об установке WinDbg через winget или Microsoft Store, поддерживаемых версиях ОС (Windows 10 1607 и новее, Windows 11) и архитектурах (x64, ARM64), а также о поведении автообновления.  2 3

  2. Microsoft Learn, Symbol path for Windows debuggers. О настройке пути к символам через переменную окружения _NT_SYMBOL_PATH и о задании пути по умолчанию к публичному серверу символов командой .symfix 2

  3. Microsoft Learn, SOS debugging extension. О том, что расширение SOS используется для сбора информации о managed-куче, обнаружения повреждений кучи и вывода внутренних типов данных рантайма, а также о том, что синтаксис в WinDbg - ![command] 2

  4. Microsoft Learn, Dump collection and analysis utility (dotnet-dump). О том, что dotnet-dump analyze предоставляет интерактивную сессию, в которой команды SOS работают напрямую, что из-за отсутствия статуса нативного отладчика он не может отображать нативные стековые фреймы, и что поддержка macOS требует .NET 5 или новее.  2 3 4

  5. Microsoft Learn, Microsoft public symbol server. О синтаксисе пути к символам вида srv*DownstreamStore*https://msdl.microsoft.com/download/symbols и о настройке с локальным кэшем через .symfix

  6. Microsoft Learn, Debugging Managed Code Using the Windows Debugger. О том, что рантайм .NET Framework - это clr.dll, а рантайм .NET Core/.NET 5+ - coreclr.dll, о загрузке расширений из соседней директории через .loadby и об автозагрузке в WinDbg версии 10.0.18317.1001 и новее.  2

  7. Microsoft Learn, SOS installer (dotnet-sos). Об установке расширения SOS локально через dotnet-sos install и о команде ручной загрузки для старых версий отладчика. 

  8. Microsoft Learn, SOS debugging extension - Commands. О том, что команда Threads (с псевдонимом clrthreads в среде lldb) выводит список ID каждого потока, домена, последнего брошенного исключения и прочего. 

  9. Microsoft Learn, SOS debugging extension - Commands. О том, что команда CLRStack выводит трассировку стека только для managed-кода, что опция -a выводит и локальные переменные, и аргументы, и что символы (SYMOPT_LOAD_LINES) влияют только на отображение имени исходного файла и номера строки, но не на отображение самих фреймов.  2

  10. Microsoft Learn, SOS debugging extension - Commands. О том, что команда PrintException (pe) без указания адреса выводит последнее исключение, брошенное в текущем потоке, и что -nested также выводит вложенные исключения. 

  11. Microsoft Learn, Debug a memory leak in .NET и Dump collection and analysis utility (dotnet-dump) - Analyze memory leaks and allocations. О статистическом выводе количества и суммарного размера по типам через dumpheap -stat и о том, как строить расследование от этой точки.  2

  12. Microsoft Learn, SOS debugging extension - Commands. О том, что команда GCRoot ищет по всей managed-куче и таблице хендлов и перечисляет ссылки (корни) на указанный объект. 

  13. Microsoft Learn, Using the !analyze Extension и !analyze (WinDbg). Об автоматическом анализе сбоя/исключения через !analyze -v, о значении полей вывода вроде FAULTING_IP и MODULE_NAME, а также о !analyze -hang для расследования зависаний. 

  14. Microsoft Learn, Debug Linux dumps. О том, что дампы Linux можно анализировать на Windows с помощью WinDbg или dotnet-dump, и что нужно использовать версию инструмента, соответствующую разрядности (x64/Arm64/x86) окружения, в котором был снят дамп. 

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

Спящий режим, гибернация, Modern Standby и долго работающие приложения — как проектированием предотвратить «остановилось ночью»

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

Практическое руководство по Process Monitor (ProcMon) — как за 10 минут выяснить, почему «настройки не читаются» или возникает ACCESS DENIED

«Исправил конфигурационный файл, но изменения не применяются», «вчера всё работало, а сегодня приложение не запускается» — прежде чем лез...

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

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

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

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

С какой команды начинать чтение крэш-дампа .NET-приложения?
Есть три типовых сценария. Если приложение упало из-за необработанного исключения, сначала через !threads находим поток с исключением, затем через !clrstack выводим managed-стек и через !pe смотрим тип, сообщение и внутренние исключения объекта. Если расследуется постоянный рост памяти, начинаем с !dumpheap -stat, чтобы найти тип, занимающий больше всего места, а затем через !gcroot выясняем, какие корни (статические поля, подписки на события) удерживают объект. При нативном сбое отправная точка - автоматический анализ !analyze -v.
Как загрузить расширение SOS в WinDbg?
Для .NET Framework - .loadby sos clr, для .NET Core/.NET 5+ - .loadby sos coreclr. Начиная с версии 10.0.18317.1001 WinDbg автоматически загружает SOS, как только обнаруживает, что целевой процесс загрузил coreclr.dll. Если автозагрузка не срабатывает, можно установить SOS локально через инструмент dotnet-sos и загрузить его вручную командой .load. Успешность загрузки проверяется тем, что !sos.help или !Threads отрабатывают без ошибки и что-то возвращают.
Можно ли анализировать дамп без PDB (символов)?
В какой-то мере да. Команды !clrstack, !dumpheap -stat и !gcroot читают метаданные CLR и данные кучи напрямую, поэтому фреймы и информация о типах отображаются даже без PDB. Теряются только имена исходных файлов и номера строк managed-кода, а также имена символов для нативных фреймов. Если нужно дойти до конкретной строки исходного кода, в путь к символам нужно добавить и публичный сервер символов Microsoft, и расположение собственных PDB. Для регулярной работы важно хранить PDB для каждой сборки и включать Source Link.
Как выбирать между dotnet-dump analyze и WinDbg?
Если может быть замешан COM, P/Invoke или нативные DLL - WinDbg, если расследование касается чисто managed-кода - ориентир на dotnet-dump analyze. dotnet-dump устанавливается одной командой dotnet global tool, и в нём напрямую доступно большинство команд SOS вроде clrstack и dumpheap, но нативные стековые фреймы он не обрабатывает и !analyze -v не поддерживает. Дампы, снятые на macOS, WinDbg анализировать не может, так что там остаётся только dotnet-dump или LLDB. Оба инструмента используют общий набор команд SOS, поэтому освоенные команды почти без изменений переносятся из одного в другой.

Об авторе

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

Го Комура

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

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

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

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