How to Read a Windows Minidump File (Without WinDbg)

Your app crashed and you have a .dmp file. Here's what's actually inside it, why WinDbg is painful, and how to get useful information out without the setup overhead.

A user sends you a crash report. Attached is a file with a .dmp extension. You open it in a text editor and see binary garbage. You try Windows Event Viewer and get a hex offset and a module name. You install WinDbg, spend an hour configuring symbol paths, and eventually get a stack trace but half the frames just say ??? 0x00000000.

This is the standard experience. It doesn't have to be. Let's start with what a minidump actually is, then work through how to get something useful out of it.

What is a Windows minidump?

A minidump is a structured binary snapshot of a Windows process at a specific moment typically the moment it crashed. It is written by the operating system automatically for some crash types (via Windows Error Reporting), or by your own application using the MiniDumpWriteDump Win32 API when an unhandled exception occurs.

Despite the "mini" prefix, a minidump contains a significant amount of information. It is divided into streams typed sections, each containing a specific category of data. The streams present in any given dump depend on which flags were passed to MiniDumpWriteDump, but a typical crash dump includes:

  • SystemInfo stream OS version, build number, processor architecture, processor count
  • ExceptionInfo stream the exception record: code, flags, faulting address, and for access violations, the read/write type and target address
  • ThreadList stream every thread active at crash time, with its ID, suspend count, and stack memory
  • ModuleList stream every DLL and EXE loaded in the process, with base address, size, version string, and a pointer to the matching PDB file (path, GUID, and age)
  • Memory64List stream raw memory regions captured at crash time, used during stack walking to resolve addresses

The raw data in all of these streams is binary and not human-readable. To get function names, file names, and line numbers from the addresses in the thread stacks, you need symbolication the process of mapping addresses back to source code using PDB files.

What the raw output looks like

If you open a .dmp in Windows Event Viewer or look at what Windows Error Reporting captures, you typically get something like this:

Windows Event Viewer — Application Error
Faulting application name: MyGame.exe
Faulting module name: MyGame-Win64-Shipping.dll
Exception code: 0xc0000005
Fault offset: 0x0000000001a2f4c1

Stack:
  ntdll.dll
  KERNELBASE.dll
  MyGame-Win64-Shipping.dll + 0x1a2f4c1
  ...

You know it crashed in your game DLL. You have an offset. You have nothing else.

The traditional approach: WinDbg

WinDbg is the authoritative Windows debugging tool and it can fully parse a minidump. Getting it to produce useful output requires:

  1. Installing the Windows SDK or WinDbg Preview from the Microsoft Store
  2. Configuring a symbol path — a semicolon-delimited list of local PDB directories and/or symbol server URLs
  3. Opening the dump file (File > Open Crash Dump)
  4. Running .sympath srv*C:\Symbols*https://msdl.microsoft.com/download/symbols to add the Microsoft public symbol server
  5. Running .reload /f to force-load symbols
  6. Running !analyze -v to get an automated analysis

When it works when the PDB that exactly matches your binary is on the symbol path — WinDbg produces a fully symbolicated stack. When it doesn't work, you get a wall of ??? 0x00000000 frames and you're left guessing why symbols didn't load.

The PDB matching requirement is strict. WinDbg validates the PDB GUID and age against the binary. A PDB from a slightly different build even a recompile with the same source won't match. For crashes from user machines running Shipping builds, you need to have archived the exact PDB from that specific build. If you haven't, you're working blind.

The symbol path problem

Assuming you have the right PDB, you still need to tell DbgHelp (the Windows symbolication API that WinDbg uses under the hood) where to find it. Symbol paths can be:

  • A local directory: C:\MyGame\Build\Symbols
  • A symbol server with local cache: srv*C:\SymCache*https://msdl.microsoft.com/download/symbols
  • Multiple paths chained together with semicolons

For system DLLs (ntdll.dll, KERNELBASE.dll, etc.), the Microsoft public symbol server works automatically and fills in those frames. For your own code, you need your PDB on a path that DbgHelp can reach. Getting this right for a crash from a user machine where the build may be months old requires deliberate symbol archiving as part of your build pipeline.

What the output looks like when it works

WinDbg — !analyze -v (symbolicated)
EXCEPTION_CODE: (NTSTATUS) 0xc0000005
ACCESS_VIOLATION

FAULTING_IP:
MyGame_Win64!AEnemyCharacter::TakeDamage+0x34
00007ff6`1a2f4c35 488b4810  mov     rcx,qword ptr [rax+10h]

STACK_TEXT:
MyGame_Win64!AEnemyCharacter::TakeDamage+0x34
MyGame_Win64!UCombatComponent::ApplyDamage+0x118
MyGame_Win64!AGameMode::HandleHit+0x2c
UE4Editor_Engine!UWorld::Tick+0x4a1
ntdll!RtlUserThreadStart+0x21

This is genuinely useful. You can see the faulting function, the line context, and the call chain that led there. But you still need to interpret what happened the access violation is at [rax+10h], which means rax was null or invalid. You'd need to look at the register state and reason about what rax was pointing to in order to form a hypothesis.

Getting the same result without the setup

CrashCatch Analyze uses the same DbgHelp and DIA SDK APIs under the hood the identical symbolication stack as WinDbg but wraps it in a drag-and-drop interface. Open a .dmp file, add your PDB directories in Tools > Symbol Paths, and you get a fully symbolicated stack immediately.

Beyond symbolication, the Intel Engine runs automatically on every dump and classifies the crash null pointer, heap corruption, stack overflow, race condition with a confidence score and a list of the specific indicators that led to the classification. No command-line flags. No .reload commands.

If you want a plain-English explanation "here's what caused this crash and where to look" Explain Mode sends a structured summary to Claude and returns a root cause, evidence list, and suggested fix.

Stop reading raw hex. Start reading crashes.

Download CrashCatch Analyze free beta, Windows x64.

Download Beta
← All posts
More from the blog
Why C++ Crash Dumps Are Still Unreadable Unreal Engine Crash Analysis: What the Crash Folder Actually Contains Access Violation 0xC0000005: What It Means and How to Find the Cause