Every C++ developer has been here.
Your app crashed in production. A user sends you a .dmp file. You open it in WinDbg, spend 45 minutes configuring symbol paths, fight with .symfix, and eventually get a stack trace that may or may not be symbolicated correctly.
Most developers just skip the dump entirely and ask the user to describe what they were doing when it crashed.
That's not debugging. That's guessing.
The Problem With Crash Dumps Today
Crash dumps are genuinely useful. A minidump contains the exception type, the faulting address, the full call stack at the moment of the crash, every loaded module and its base address, and thread state. Everything you need to find the bug.
But the tooling is terrible for most developers:
- WinDbg powerful but has a steep learning curve and requires significant setup
- Visual Studio better UX but still needs symbol paths configured correctly
- Manual DbgHelp you're writing your own tooling from scratch
For game developers especially, Unreal Engine crashes add another layer UE has its own crash reporter, its own log format, and its own symbol conventions that don't map cleanly to standard Windows tooling.
So, I built my own solution.
Step 1: Automatic Crash Dumps With One Line of Code
The first problem is actually getting the crash dump. A lot of C++ apps don't write one by default.
I built CrashCatch a free, open-source, header-only C++ library that hooks Windows structured exception handling and writes a minidump automatically when your app crashes.
#include "CrashCatch.hpp"
int main() {
CrashCatch::enable();
// your application code
}
That's it. No dependencies. No config required. Drop the header in, add one line, and from that point on every crash writes a .dmp file to disk.
The SDK is on GitHub (Apache 2.0): github.com/keithpotz/CrashCatch
It uses SetUnhandledExceptionFilter under the hood and calls MiniDumpWriteDump from DbgHelp. You can configure the dump type (MiniDumpNormal, MiniDumpWithFullMemory, etc.) and the output path.
Step 2: Reading the Dump The Interesting Part
Once you have the .dmp file, you need to actually read it. This is where I spent most of my engineering time.
I built an analysis engine in C++ using:
-
DbgHelp for stack walking (
StackWalk64) and symbol resolution (SymFromAddr) - DIA SDK for reading PDB files and resolving symbols to source file + line number
- MINIDUMP_EXCEPTION_STREAM for parsing the exception record
- MINIDUMP_MODULE_LIST for enumerating loaded modules
The result is a structured CrashReport object that contains:
exception_code: 0xC0000005 (ACCESS_VIOLATION)
exception_address: 0x00007FF6A3B2C140
faulting_module: MyGame.exe
access_violation: read at 0x0000000000000000
stack_trace:
[0] AEnemy::Tick(float) — AEnemy.cpp:247
[1] UActorComponent::TickComponent(float, ...) — ActorComponent.cpp:412
[2] FActorTickFunction::ExecuteTick(...) — Actor.cpp:88
That null pointer read at frame 0 tells you everything.
The Intel Engine
One thing I'm particularly happy with is what I call the Intel engine a pattern-matching layer that runs before any AI.
It looks at the exception code, faulting module, access violation address, and stack signatures and produces a structured diagnosis:
-
0xC0000005read at0x0→ null pointer dereference, points at frame 0 as likely cause -
0xC0000005write at a high address → stack corruption or buffer overflow -
0xC0000409→ stack overflow, check for infinite recursion - Exception in a known UE module → UE-specific context added automatically
This means even without an internet connection or API key, you get a useful diagnosis immediately. The AI layer builds on top of this it doesn't replace it.
Explain Mode
Once the Intel engine has run, you can hit Explain Mode. This sends the structured crash report to Claude (Anthropic) and gets back:
- Plain-English explanation of what happened
- Root cause analysis
- Specific suggestions for what to fix
For the null pointer crash above it comes back with something like:
"The crash occurred in AEnemy::Tick at line 247 of AEnemy.cpp. The access violation at address 0x0 indicates a null pointer dereference — something the Tick function is trying to read from is null. Check that any UObject references or pointers used in Tick are validated before access, particularly any references that could be destroyed between frames."
That's the kind of answer that takes a junior developer 20 minutes to arrive at. It's there in 3 seconds.
Unreal Engine Support
Unreal Engine deserves its own mention. CrashCatch Analyze detects UE projects automatically and:
- Parses UE log output alongside the dump
- Identifies UE-specific exception patterns
- Shows a dedicated UE context tab with engine version, project name, and relevant log lines
- Handles UE's symbol conventions correctly
If you're shipping an Unreal Engine game, you can point CrashCatch at your project folder and it handles the rest.
The Desktop App
I wrapped all of this in a native Windows desktop app built with Tauri 2 a Rust backend with a TypeScript/WebView2 frontend. The analysis engine is a C++ DLL called via Rust FFI.
The workflow:
- Drag a
.dmpfile onto the drop zone - (Optional) Set your symbol paths
- Analysis runs in under a second
- Navigate the tabs: Stack Trace, Exception, Modules, Intel, UE Context, Explain, Raw
- Export to PDF if you need to share it with your team
Where To Get It
CrashCatch SDK free, open source, Apache 2.0:
github.com/keithpotz/CrashCatch
CrashCatch Analyze native Windows desktop app, currently in beta:
crashcatchlabs.com
If you're shipping a C++ app on Windows and you're not collecting crash dumps, start with the SDK. It's one line of code and costs you nothing.
If you already have .dmp files piling up and no good way to read them — that's what the analyzer is for.
Questions about the DbgHelp / DIA SDK internals, the Tauri + native DLL architecture, or the Unreal Engine integration? Ask in the comments.


Top comments (0)