dd_action('wp_footer', function() { ?>

5.9 WinDbg — профессиональный анализ падений игр и DLL

WinDbg анализ crash dump игры, DLL и стека вызовов Windows

🧩 Что такое WinDbg

WinDbg (Windows Debugger) — профессиональный отладчик Microsoft для анализа сбоев программ Windows.

Он используется для глубокого поиска причин:

  • вылетов игр;
  • ошибок DLL;
  • повреждения памяти;
  • конфликтов драйверов;
  • неизвестных кодов ошибок.

В отличие от:

  • Event Viewer — показывает факт сбоя;
  • ProcMon — показывает поиск файлов;
  • Process Explorer — показывает загруженные DLL;

WinDbg позволяет посмотреть:

что происходило внутри программы в момент падения.


Схема работы:

 
Игра падает

↓

Создание дампа памяти

↓

WinDbg

↓

Анализ стека

↓

Поиск виновного модуля

↓

Исправление
 

🎯 Когда нужен WinDbg

Для обычного отсутствия DLL WinDbg не нужен.

Он используется, когда:

  • игра падает без понятной причины;
  • Event Viewer показывает только 0xc0000005;
  • виновником выглядит системная DLL;
  • конфликтуют моды и фиксы;
  • игра зависает с созданием дампа;
  • нужен точный анализ.

📥 Установка WinDbg

Современная версия:

 
WinDbg Preview
 

устанавливается через:

 
Microsoft Store
 

Старая версия:

 
Windows SDK Debugging Tools
 

Для большинства пользователей достаточно:

 
WinDbg Preview
 

📂 Что такое crash dump

Dump (дамп памяти) — это сохранение состояния программы в момент сбоя.

Он содержит:

  • память процесса;
  • список потоков;
  • загруженные DLL;
  • стек вызовов;
  • информацию об ошибке.

Основные виды:


Минидамп

Файл:

 
.dmp
 

Содержит:

  • основную информацию о падении;
  • стек;
  • модули.

Полный дамп

Содержит:

  • всю память процесса.

Используется для сложного анализа.


🛠 Как получить дамп игры

Есть несколько способов.


Способ 1 — через Windows Error Reporting

Windows иногда автоматически создаёт:

 
Crash dump
 

Папки:

 
C:\ProgramData\Microsoft\Windows\WER
 


Способ 2 — Process Explorer

Process Explorer:

 
ПКМ по игре

↓

Create Dump

↓

Create Minidump
 

Получаем:

 
Game.dmp
 


Способ 3 — ProcDump

Инструмент Sysinternals:

 
procdump.exe
 

Пример:

 
procdump -ma Game.exe
 

Создаёт полный дамп.


▶ Открытие дампа в WinDbg

Запустить:

 
WinDbg Preview
 

Открыть:

 
File

↓

Open dump file
 

Выбрать:

 
Game.dmp
 


🔍 Главная команда — !analyze -v

После загрузки дампа:

ввести:

 
!analyze -v
 

WinDbg покажет:

  • тип ошибки;
  • код исключения;
  • виновный модуль;
  • стек вызовов.

Пример:

 
EXCEPTION_CODE:

c0000005
 

Это:

 
Access Violation
 


🟥 Анализ Exception Code

0xc0000005

Access Violation.

Означает:

программа попыталась:

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

Причины:

  • ошибка игры;
  • старый движок;
  • несовместимый фикс;
  • повреждённая DLL.


0xc000007b

Часто:

архитектурная проблема.

Например:

 
x86

+

x64 DLL
 


0xc0000142

Ошибка загрузки DLL.

Проверять:

  • Runtime;
  • сторонние библиотеки;
  • моды.

📚 Faulting Module

WinDbg показывает:

 
MODULE_NAME:
d3d9
 

Это помогает понять направление поиска.


Примеры:


d3d9.dll

Возможные причины:

  • DirectX;
  • драйвер;
  • d3d9 wrapper;
  • ReShade.

ddraw.dll

Проверять:

  • DirectDraw фикс;
  • cnc-ddraw;
  • DDrawCompat;
  • dgVoodoo.

mss32.dll

Проверять:

  • Miles Sound System;
  • файлы игры.

xinput1_3.dll

Проверять:

  • DirectX Runtime;
  • контроллеры.

🧵 Stack Trace — стек вызовов

Один из самых важных разделов.

Команда:

 
k
 

или:

 
kb
 

Показывает:

какие функции выполнялись перед падением.


Пример:

 
Game.exe

↓

d3d9.dll

↓

nvwgf2umx.dll
 

Вывод:

возможна проблема видеодрайвера NVIDIA.



📦 Просмотр загруженных модулей

Команда:

 
lm
 

Показывает:

  • все DLL;
  • адреса;
  • версии.

Пример:

 
ddraw

7A000000

GameFolder\ddraw.dll
 

Можно увидеть:

какой именно wrapper используется.


🔎 Проверка конкретной DLL

Команда:

 
lmvm ddraw
 

Показывает:

  • путь;
  • версию;
  • компанию.

Пример:

 
Company:

dgVoodoo
 

или:

 
Microsoft Corporation
 

🧪 Практический пример 1

Старая игра падает после установки ddraw.dll

Event Viewer:

 
Faulting module:
ddraw.dll
 

WinDbg:

 
lmvm ddraw
 

Показывает:

 
GameFolder\ddraw.dll
 

Вывод:

используется установленный фикс.

Дальше:

  • менять wrapper;
  • проверять настройки.

🧪 Практический пример 2

Игра падает в драйвере

WinDbg:

 
Stack:

Game.exe

↓

d3d11.dll

↓

nvwgf2umx.dll
 

Вывод:

вероятно:

  • видеодрайвер;
  • GPU;
  • DirectX.


🧪 Практический пример 3

Неизвестный вылет

Event Viewer:

 
0xc0000005
 

WinDbg:

 
!analyze -v
 

Показывает:

 
Module:
mss32.dll
 

Вывод:

проверять:

  • звук;
  • Miles Sound System;
  • оригинальные файлы игры.

⚠ Когда WinDbg не нужен

Не использовать для:

❌ отсутствующего d3dx9_43.dll;
❌ отсутствующего MSVCP140.dll;
❌ установки DirectX;
❌ обычной проверки DLL.

Для этого:

  • Dependencies;
  • ProcMon.

🛠 Правильная цепочка диагностики

 
Игра не запускается

↓

Dependencies

↓

ProcMon

↓

Event Viewer

↓

Process Explorer

↓

WinDbg
 

📊 WinDbg — краткая таблица

КомандаНазначение
!analyze -vобщий анализ сбоя
kстек вызовов
kbстек с параметрами
lmсписок DLL
lmvm имяинформация о DLL
!processинформация о процессе
!threadинформация о потоке

Полное руководство по WinDbg: диагностика сбоев игр 

1. Интерфейс и горячие клавиши

WinDbg Preview имеет современный UI, но вся сила — в командах. Ключевые панели:

  • Command Window — ввод команд и вывод результатов.
  • Disassembly — ассемблер вокруг текущего RIP.
  • Locals/Watch — переменные (в user-mode).
  • Memory — просмотр сырых данных.
  • Modules — список загруженных DLL/EXE с базовыми адресами.
  • Registers — содержимое регистров (критично при крашах).
  • Breakpoints — список точек останова.

Горячие клавиши:

  • Ctrl+S — Symbol File Path.
  • F9 — Toggle Breakpoint (на строке в Disassembly).
  • F5 — Go.
  • Shift+F11 — Step Out.
  • F10 — Step Over.
  • F11 — Step Into.

2. Символы: как не смотреть на «мусор»

Без символов вы видите только адреса. Настройка:

  1. Создайте папку C:\Symbols.
  2. В File → Symbol File Path вставьте:
    SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols
    
  3. Если есть свои PDB: добавьте через точку с запятой:
    ...;C:\Games\MyGame\Symbols
    
  4. Выполните .reload (или .reload /f для принудительной перезагрузки).
  5. Проверьте статус: .symopt +0x40 (чтобы видеть статус загрузки), затем снова .reload.

Проверка: введите lm m kernel32 — если рядом с модулем стоит (deferred) или (private), символы подгрузились. Если (no symbols) — проблема в пути или сети.


3. Сценарии запуска и их применение

СценарийКак сделатьКогда использовать
Игра не стартует вообщеFile → Open ExecutableЧтобы поймать самый первый краш или исключение загрузки DLL.
Игра стартует, но вылетаетFile → Attach to a ProcessЕсли краш происходит через N секунд после запуска.
Есть .dmp файлFile → Open Crash DumpСамый быстрый способ диагностики.

Важно: некоторые античиты (EAC, BattlEye) блокируют Attach. В таких случаях используйте только Open Executable или анализ дампов.


4. Первичный анализ исключения

При краше WinDbg пишет: *** Fatal Error: Exception c0000005 ....

Ключевые команды:

  • .lastevent — последнее событие (исключение) и адрес.
  • .exr -1 — детали исключения (код, информация).
  • k — стек вызовов.
  • kp — стек с аргументами функций (часто раскрывает причину).

Пример разбора:

 
*** Fatal Error: Exception c0000005 (Access Violation)

Выполняем:

 
.lastevent
k
kp

Ищем в стеке имя игры и смотрим, какая функция вызвала краш. Аргументы в kp часто указывают на нулевой указатель или неверный адрес.


5. Глубокий разбор: модули, зависимости, память

Проверка модулей

 
lm

Ищите:

  • Отсутствие DLL, которая должна быть (например, d3d11.dll, vcruntime140.dll).
  • Статус Unloaded или Bad Image.

Таблица импорта и неразрешённые символы

 
!lmi MyGame.exe

Показывает, какие функции игра пытается импортировать. Если функция помечена как unresolved — игра не сможет стартовать.

Просмотр памяти и структур

Если стек указывает на объект, проверьте его:

 
dt MyGame!GraphicsDevice 0x0000012345678900
dq 0x0000012345678900 L10

Если структура показывает мусор или много нулей — объект не инициализирован или уже уничтожен.


6. Разбор типичных кодов ошибок

КодНазваниеЧто означаетКак диагностировать
c0000005Access ViolationЧтение/запись по неверному адресу (чаще всего разыменование NULL)k, kp, r, dt, dq.
c0000094Integer Division by ZeroДеление на нольk, смотреть аргументы.
e06d7363MSVC C++ ExceptionИсключение C++ (try/catch не сработал)!peb, стек, иногда !heap.
80070002File Not FoundНе найден файл (конфиг, ассет, DLL)bp kernel32!CreateFileW, bp kernel32!LoadLibraryExW.

7. Работа с дампами (.dmp)

Если игра создала дамп:

  1. File → Open Crash Dump.
  2. Выполните:
    !analyze -v
    

Результат содержит:

  • FAULTING_CODE — код ошибки.
  • IMAGE_NAME — проблемный модуль.
  • STACK_TEXT — стек.
  • Рекомендации (например, «обновите драйвер видеокарты»).

Для повторяющихся крашей удобно сохранять workspace: File → Save Workspace, чтобы не настраивать символы каждый раз.


8. Продвинутые техники для игр

Точки останова на системные вызовы

Чтобы понять, какой файл или DLL не удаётся загрузить:

 
bp kernel32!CreateFileW
bp kernel32!LoadLibraryExW

Когда игра попытается открыть файл или загрузить библиотеку, отладчик остановится. В регистре RCX будет имя файла/DLL.

Поиск ошибок DirectX

Если краш в рендере:

  • Ищите в стеке dxgkrnl.sys, nvlddmkm.sys, atikmdag.sys.
  • Используйте !dxg (если доступно) или смотрите HRESULT в аргументах.
  • Команда .exr -1 покажет ExceptionInformation, где часто лежит код ошибки DirectX.

Работа с кучей (heap)

Игры активно используют динамическую память. Команды:

 
!heap
!heap -s
!heap -stat

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


9. Автоматизация: скрипты и PYKD

WinDbg поддерживает скрипты и Python (PYKD).

Простой скрипт (.cmd)

Создайте startup.cmd:

 
.symfix
.reload
bp MyGame!GameEngine::Init
g

Запустите WinDbg с флагом -c "$$>a< C:\Scripts\startup.cmd".

PYKD (Python)

Установите PYKD и используйте:

from pykd import *
print(loadModule("MyGame"))

Это полезно для повторяющихся проверок и автоматизации анализа дампов.


10. Пример полного разбора: «Игра не запускается»

Проблема: SpaceWar.exe не стартует, сразу закрывается.

Шаги:

  1. Запустите через Open Executable.
  2. Краш: Exception c0000005.
  3. .lastevent, k, kp → видим, что краш в Player::LoadInventory, который вызывает FileManager::OpenFile.
  4. Ставим точку останова:
    bp SpaceWar!FileManager::OpenFile
    g
    
  5. Игра останавливается на функции. Смотрим аргументы (kp) — функция пытается открыть C:\Users\User\Documents\SpaceWar\savegame.dat.
  6. Проверяем диск — файла нет.
  7. Решение: либо создать пустой файл, либо исправить логику игры, чтобы она корректно обрабатывала отсутствие файла.

11. Античиты, виртуализация и ограничения

  • Античиты (EAC, BattlEye): блокируют отладку. Используйте дампы или запуск через Open Executable (иногда срабатывает).
  • Виртуализация: для безопасной отладки ядра или драйверов используйте виртуальную машину.
  • Драйверы: не отлаживайте ядро на основной системе без крайней необходимости.

12. Шпаргалка по командам

КомандаОписание
.reloadПерезагрузить символы.
lmСписок модулей.
k / kp / kvСтек вызовов (с аргументами, с переменными).
dt <Type> <Address>Показать структуру.
db/dd/dq <Address> L<Count>Просмотр памяти.
bp <Function>Точка останова.
gПродолжить выполнение.
rРегистры.
u <Address>Дизассемблировать.
!analyze -vАнализ дампа.
!heapИнформация о куче.
.exr -1Детали последнего исключения.

13. Где искать дополнительную информацию

  • Microsoft Learn: официальная документация по WinDbg.
  • GitHub: репозитории с готовыми скриптами и расширениями.
  • Stack Overflow / Reddit: типичные кейсы и решения.
  • Документация по DirectX, Vulkan, OpenGL: для разбора ошибок рендера.

Встроенные мета-команды (управление отладчиком)

Эти команды начинаются с точки (.) и управляют самим отладчиком.

КомандаОписаниеПример использования
.help или .hhВызов справки. .hh <команда> — справка по конкретной команде..hh .reload
.sympathЗадать путь к символам (PDB)..sympath SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols
.reloadПерезагрузить символы. Флаг /f — принудительно, /u — выгрузить..reload /f
.symoptУправление опциями загрузки символов. +0x40 показывает статус загрузки..symopt +0x40
.load / .unloadЗагрузить/выгрузить расширение (например, SOS для .NET, PYKD)..load sos.dll
.chainПоказать загруженные расширения.
.logopen / .logcloseНачать/остановить запись лога сессии в файл..logopen C:\Logs\debug.log
.clsОчистить окно команд.
.restartПерезапустить отлаживаемое приложение (без закрытия WinDbg).

Навигация и управление выполнением

Критично для пошаговой отладки.

КомандаОписаниеГорячие клавиши
gGo: продолжить выполнение до следующей точки останова или исключения.F5
pStep Over: выполнить одну инструкцию, не заходя внутрь функций.F10
tStep Into: выполнить инструкцию, заходя внутрь вызовов функций.F11
prStep Out: выполнить до возврата из текущей функции.Shift+F11
guGo Up: выполнить до выхода из текущей функции (быстрее, чем pr).
wtTrace and Watch: трассировать выполнение функции и вывести отчет. Полезно для анализа медленных функций.
~*sПереключить контекст на все потоки (для анализа многопоточных крашей).
~<N>sПереключить контекст на поток с ID N.

Точки останова (Breakpoints)

WinDbg имеет мощную систему точек останова.

КомандаОписание
bp <addr/symbol>Обычная точка останова (срабатывает один раз, затем удаляется).
bu <addr/symbol>Unresolved breakpoint: срабатывает, даже если модуль еще не загружен (идеально для LoadLibrary).
bm <pattern>Break on Match: установить точки по маске (например, bm MyGame!*Init*).
blList: показать список всех установленных точек останова.
bc <ID>Clear: удалить точку останова по ID.
bd <ID> / be <ID>Disable/Enable: отключить/включить точку останова.
ba <access> <size> <addr>Access breakpoint: срабатывает при чтении/записи в память (например, при повреждении данных). ba r 4 <addr> — при чтении 4 байт.

Анализ стека, регистров и памяти

Основа диагностики крашей (Access Violation и т.д.).

КомандаОписаниеНюансы
k / kb / kcCall Stack: показать стек вызовов. k — кратко, kb — с аргументами в регистрах, kc — сжато.Для игр kP (параметры) часто важнее всего.
kpStack with Parameters: показывает аргументы функций (C++).Может показывать мусор, если оптимизация компилятора удалила фреймы.
kvStack with Local Variables: попытка показать локальные переменные.Работает не всегда.
rRegisters: показать содержимое регистров (RAX, RBX, RIP и т.д.).r @$ip — текущий адрес инструкции.
dt <Type> <Address>Display Type: показать структуру данных по адресу.Требует символов. dt -r — рекурсивный вывод.
db / dw / dd / dqDump Bytes/Words/Dwords/Qwords: просмотр сырых данных в памяти.dq <addr> L10 — вывести 10 QWORD.
u <addr>Unassemble: дизассемблировать код по адресу.Показывает ассемблерные инструкции.
ln <addr>List Nearest Symbols: найти ближайший символ по адресу (если не знаете имя функции).Очень полезно при анализе дампов.

Модули, символы и зависимости (для диагностики «не запускается»)

Именно эти команды помогают понять, почему игра не стартует (нет DLL, неверная версия и т.п.).

КомандаОписаниеПрименение
lmList Modules: список всех загруженных DLL/EXE.Ищите отсутствующие или помеченные как Unloaded.
lm m <name>List Module by name: найти конкретный модуль.lm m d3d11 — проверить наличие DirectX.
!lmi <module>List Import/Export: таблица импорта модуля.Показывает, какие функции игра пытается вызвать. Статус unresolved = проблема.
!pebProcess Environment Block: детальная информация о процессе.Секция Ldr покажет статус загрузки всех DLL.
!chkimgCheck Image: проверить целостность бинарного файла (повреждение).Редко, но бывает полезно.

Работа с кучей (Heap) и памятью (для поиска утечек и повреждений)

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

КомандаОписание
!heapПоказать информацию обо всех кучах процесса.
!heap -sСтатистика кучи (сколько свободно/занято).
!heap -statСтатистика по блокам (размер, количество).
!heap -l <handle>Легаси-команда для детального анализа конкретной кучи.
!addressПоказать карту виртуальной памяти процесса.
!verifyВключить проверку кучи в реальном времени (может замедлить игру).

Расширения и специфичные задачи

Команды, начинающиеся с восклицательного знака (!), — это расширения (extensions). Они добавляют функционал.

Для анализа дампов и крашей

КомандаОписание
!analyze -vАвтоматический анализ дампа/краша. Самая важная команда.
.exr -1Показать детали последнего исключения.
.lasteventПоказать последнее событие (исключение).
!threadПоказать информацию о текущем потоке.
!threadsПоказать список всех потоков.

Для .NET приложений (если игра на Unity/C#)

КомандаОписание
.loadby sos clrАвтоматически загрузить расширение SOS, зная, где лежит CLR.
!dumpheap -statПоказать статистику объектов в куче .NET (утечки памяти).
!gcroot <address>Найти ссылки на объект (почему он не удаляется сборщиком мусора).
!clrstackСтек вызовов .NET (понятные имена методов, а не ассемблер).

Для драйверов и ядра (Kernel Mode)

КомандаОписание
!process 0 0Показать все процессы в системе.
!irpПоказать IRP-пакеты (запросы ввода-вывода).
!objectПоиск объектов ядра по имени.
!vmПоказать статистику виртуальной памяти системы.
!pfn <page_number>Информация о физической странице памяти.

Для графики (DirectX/GPU)

КомандаОписание
!dxgДиагностика DirectX Graphics (требует расширения).
!gpuИнформация о состоянии GPU.

Продвинутые и редко используемые команды

КомандаОписание
$<script.txt>Выполнить скрипт (набор команд) из файла.
as <alias> <string>Создать алиас (псевдоним) для длинной команды.
alList Aliases: показать все созданные алиасы.
? <expression>Вычислить выражение (арифметика, адреса).
ed / eb / ew / eqEdit Memory: изменить значение в памяти (байт, слово, dword, qword).
nName: задать имя для текущего контекста (удобно при работе с несколькими процессами).

Специфика для диагностики игр (сводка по кейсам)

Если вы диагностируете сбой игры, вот готовые «наборы» команд под конкретную проблему:

  1. Игра не запускается (сразу крашится):

    • Запустить через Open Executable.
    • Сразу: .lastevent, k, kp.
    • Проверить зависимости: lm, !lmi MyGame.exe.
    • Если ошибка c0000005: проверить аргументы в kp, найти нулевой указатель.
  2. Игра вылетает через 5 минут (утечка памяти):

    • Подключиться (Attach to Process).
    • Периодически выполнять: !heap -s, !address.
    • Для .NET: !dumpheap -stat.
  3. Черный экран / ошибка рендера:

    • Стек: искать dxgkrnl, nvlddmkm.
    • Посмотреть аргументы функции инициализации графики через kp.
    • Проверить HRESULT в .exr -1.
  4. Анализ готового дампа (.dmp):

    • File → Open Crash Dump.
    • Обязательно: !analyze -v.
    • Далее: k, dt, dq по адресам из отчета.

Важные нюансы

  • Синтаксис: В WinDbg регистр букв в командах не важен (BP = bp), но в именах символов (функций, типов) регистр важен.
  • Выражения: Многие команды принимают выражения. Например, dq (esp + 4) L10.
  • Контекст: Некоторые команды (особенно расширения вроде !process) ведут себя по-разному в User Mode и Kernel Mode. WinDbg обычно сам подсказывает, если команда неприменима.
  • Античиты: Команды вроде ba (аппаратные точки останова) или ed (правка памяти) могут быть заблокированы античитами (EAC, BattlEye). В таких случаях анализ возможен только через дампы или пассивное наблюдение.

Итог

WinDbg — самый глубокий уровень диагностики игр.

Он помогает:

✅ анализировать падения;
✅ искать настоящий виновный модуль;
✅ проверять DLL и драйверы;
✅ разбирать сложные ошибки памяти.

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

Главная схема:

 
Crash Dump

↓

WinDbg

↓

!analyze -v

↓

Faulting Module

↓

Stack Trace

↓

Причина ошибки