CrashCatch
August 12, 2026 · View on GitHub
A cross-platform, lightweight, single-header crash-reporting library for modern C++ applications.
CrashCatch Analyzer is now fully released! A standalone desktop tool for analyzing and understanding your crash reports symbolicated stack traces, plain-English explanations, and more. Download / View on GitHub
CrashCatch is a lightweight, single-header C++ crash-reporting library that generates .dmp and .txt crash logs with accurate stack traces, diagnostics, optional cleanup hooks, and user dialogs all with no external dependencies.
Key Features
- Cross-platform: Windows, Linux & macOS
- Single-header integration just
#include "CrashCatch.hpp" - Accurate crash-site stack traces Windows stack walk uses the actual crash context, not the handler frame
.dmpMiniDump (Windows) and.txthuman-readable report (Windows, Linux & macOS)onCrash()andonCrashUpload()callbacks fire after crash files are written to disk- Demangled symbols on Linux and macOS,
SymFromAddrwith file/line info on Windows - File/line numbers in macOS stack traces via
atos(optional, falls back gracefully without debug symbols) - Thread-safe timestamp generation
SymInitializecalled at startup for faster, more reliable symbol resolution- Portable Debug/Release detection via
NDEBUG, consistent across MSVC, Clang, and GCC - Fully configurable output path, filename, and format
- Unicode-safe paths via
std::filesystem::path— non-ASCII crash file paths work correctly on Windows (C++ API and C API alike) - DLL / shared library support via
CrashCatchDLL.hppfor C++11/C++98/C consumers - CMake install +
find_packagesupport - Zero external dependencies
Why CrashCatch?
Most crash reporting solutions require heavyweight SDKs, mandatory cloud uploads, or complex build setups. CrashCatch is different:
| CrashCatch | Crashpad | Sentry Native | Backtrace | |
|---|---|---|---|---|
| Single header | ✅ | ❌ | ❌ | ❌ |
| No external dependencies | ✅ | ❌ | ❌ | ❌ |
| Offline-first | ✅ | ❌ | ❌ | ❌ |
| Windows + Linux + macOS | ✅ | ✅ | ✅ | ✅ |
| onCrash / onUpload hooks | ✅ | ❌ | ✅ | ✅ |
| Free & open source | ✅ | ✅ | Partial | ❌ |
Quick Start
Zero Config
#define CRASHCATCH_AUTO_INIT
#include "CrashCatch.hpp"
int main() {
int* ptr = nullptr;
*ptr = 42; // CrashCatch catches this and writes a crash report
}
One-Liner
#include "CrashCatch.hpp"
int main() {
CrashCatch::enable();
// your app code
}
Full Configuration
#include "CrashCatch.hpp"
#include <iostream>
int main() {
CrashCatch::Config config;
config.appVersion = "2.0.0";
config.buildConfig = "Release";
config.additionalNotes = "Internal beta build";
config.dumpFolder = "./crash_reports/";
config.includeStackTrace = true;
config.showCrashDialog = false; // Windows only
config.onCrash = [](const CrashCatch::CrashContext& ctx) {
// Called after crash files are written — safe to read them here
std::cout << "Crash detected. Log: " << ctx.logFilePath << "\n";
// flush logs, close handles, etc.
};
config.onCrashUpload = [](const CrashCatch::CrashContext& ctx) {
// Called after onCrash — files are on disk and ready to upload
uploadToMyServer(ctx.dumpFilePath, ctx.logFilePath);
};
CrashCatch::initialize(config);
// your app code
}
Supported Platforms
| OS | Status | Crash Handling |
|---|---|---|
| Windows 10 / 11 | ✅ Supported | SetUnhandledExceptionFilter + MiniDump + StackWalk64 |
| Linux | ✅ Supported | POSIX signals + backtrace() + fork() for safe I/O |
| macOS | ✅ Supported (Intel & Apple Silicon) | POSIX signals + backtrace() + fork() for safe I/O; file/line via atos (optional) |
macOS notes: Message boxes and Mach exception interception are not yet implemented see Roadmap. File/line numbers require Xcode Command Line Tools (
atos) and debug symbols; falls back gracefully tomodule+symbol+offseton stripped/Release builds without it. On Apple Silicon (ARM64), integer divide-by-zero does not raiseSIGFPEthe way it does on x86_64, since ARM64 doesn't trap on this in hardware — this is a platform-level limitation, not a CrashCatch bug.
Windows and Linux builds run in CI on every push, including crash-handler tests that trigger a real crash and verify the resulting log/dump.
Installing with CMake
mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=./install
cmake --build . --target install
Then in your project:
find_package(CrashCatch REQUIRED)
target_link_libraries(MyApp PRIVATE CrashCatch::CrashCatch)
Or copy CrashCatch.hpp directly into your project no build system required.
Crash Output
When a crash occurs, CrashCatch writes to ./crash_dumps/ by default:
crash_YYYY-MM-DD_HH-MM-SS.dmpBinary MiniDump (Windows only, viewable in WinDbg)crash_YYYY-MM-DD_HH-MM-SS.txtHuman-readable crash summary
Example .txt output (Windows)
Crash Report
============
Timestamp: 2026-03-20_09-15-23
Environment Info:
App Version: 2.0.0
Build Config: Release
Platform: Windows
Executable: C:\MyApp\MyApp.exe
Stack Trace:
[0]: MyApp::GameLoop (C:\MyApp\src\game.cpp:142)
[1]: main (C:\MyApp\src\main.cpp:28)
[2]: invoke_main (exe_common.inl:79)
[3]: __scrt_common_main_seh (exe_common.inl:288)
[4]: mainCRTStartup (exe_main.cpp:17)
[5]: BaseThreadInitThunk
[6]: RtlUserThreadStart
Example .txt output (Linux)
Crash Report
============
Signal: Segmentation fault (11)
Timestamp: 2026-03-20_09-15-23
Environment Info:
App Version: 2.0.0
Build Config: Release
Platform: Linux
Executable: /home/user/MyApp
Stack Trace:
[0]: ./MyApp(MyApp::GameLoop()+0x42) [0x401234]
[1]: ./MyApp(main+0x1f) [0x401100]
[2]: libc.so.6(__libc_start_main+0xf3) [0x7f...]
Stack frames on Linux show demangled C++ names when compiled with
-rdynamic.
Example .txt output (macOS)
Crash Report
============
Signal: Segmentation fault: 11
Timestamp: 2026-03-20_09-15-23
Environment Info:
App Version: 2.0.0
Build Config: Release
Platform: macOS
Executable: /Users/user/MyApp
Stack Trace:
[0]: MyApp CrashCatch::writeCrashLog(...) + 676 (CrashCatch.hpp:408)
[1]: MyApp CrashCatch::posixSignalHandler(int) + 304 (CrashCatch.hpp:510)
[2]: libsystem_platform.dylib _sigtramp + 29
[3]: MyApp main + 52
[4]: dyld start + 6076
File/line numbers require debug symbols and Xcode Command Line Tools; system library frames (e.g.
dyld,libsystem_platform.dylib) won't resolve file/line since Apple doesn't ship debug info for them.
Crash Context API
Both onCrash and onCrashUpload receive a CrashContext populated after files are written:
struct CrashContext {
std::filesystem::path dumpFilePath; // path to .dmp (Windows) or empty (Linux/macOS)
std::filesystem::path logFilePath; // path to .txt crash report
std::string timestamp; // YYYY-MM-DD_HH-MM-SS
int signalOrCode; // POSIX signal number or Windows exception code
};
Both callbacks fire after crash files are on disk. It is safe to open, read, or upload them from within either callback.
Breaking change (v1.5.0):
dumpFilePathandlogFilePathwere previouslystd::stringand are nowstd::filesystem::path, which also fixesdumpFolderrequiring a trailing path separator. Code that consumed these fields as strings (e.g. passing them to a function expectingconst std::string&) will need to call.string()or update the signature to acceptconst std::filesystem::path&.
DLL / Shared Library Support
For projects that cannot use C++17, CrashCatchDLL.hpp provides a plain C interface:
#include "CrashCatchDLL.hpp"
int main() {
// Zero config
crashcatch_enable();
// Or with configuration
CrashCatch_Config cfg = crashcatch_default_config();
cfg.app_version = "2.0.0";
cfg.include_stack_trace = 1;
cfg.on_crash = my_crash_callback;
crashcatch_init(&cfg);
}
Build the DLL once with C++17. Consumers link against the compiled binary — no C++17 required on their end.
dump_path and log_path passed to on_crash/on_crash_upload are UTF-8 encoded, so crash file paths containing non-ASCII characters round-trip correctly on Windows even though the callback signature stays const char*.
Configuration Reference
struct Config {
std::filesystem::path dumpFolder = "./crash_dumps/"; // output directory
std::string dumpFileName = "crash"; // base filename
bool enableTextLog = true; // write .txt report
bool autoTimestamp = true; // append timestamp to filename
bool showCrashDialog = false; // Windows: show MessageBox
bool includeStackTrace = true; // include stack trace in .txt
std::string appVersion = "unknown";
std::string buildConfig = "Release"; // or "Debug" — auto-detected from NDEBUG
std::string additionalNotes = ""; // appended to crash report
std::function<void(const CrashContext&)> onCrash = nullptr;
std::function<void(const CrashContext&)> onCrashUpload = nullptr;
};
Examples
Working examples are in the /examples folder:
| Example | What it demonstrates |
|---|---|
Example_ZeroConfig | Auto-init with CRASHCATCH_AUTO_INIT macro |
Example_OneLiner | CrashCatch::enable() minimal setup |
Example_FullConfig | All config options including callbacks |
Example_ThreadCrash | Crash on a non-main thread |
Example_divideByZero | Arithmetic exception handling (note: does not raise SIGFPE on Apple Silicon see Supported Platforms) |
Example_UploadCrash | onCrashUpload reading and uploading files |
StackTraceExample | includeStackTrace flag |
Requirements
- C++17 or later (or C++11/C++98/C via
CrashCatchDLL.hpp) - Windows: MSVC (Visual Studio 2019+) or MinGW
- Linux: GCC or Clang, link with
-rdynamicfor symbol resolution - macOS: Clang (via Xcode Command Line Tools,
xcode-select --install); file/line resolution additionally requiresatos(included with Command Line Tools) and debug symbols
Roadmap
- Windows crash capture + MiniDump
- Linux signal handling + backtrace
-
onCrashandonCrashUploadhooks - CMake install support
- DLL / shared library support (
CrashCatchDLL.hpp) - Windows stack trace in
.txtlog with file/line info -
includeStackTraceflag - Accurate crash-site stack context (v1.4.0)
- Async-signal-safe Linux crash handler via
fork()(v1.4.0) - Thread-safe timestamp generation (v1.4.0)
- vcpkg and Conan package registry support
- macOS support POSIX signals, stack traces, file/line via
atos(v1.5.0) - macOS Mach exception interception (research in progress)
- macOS message box support (blocked on Objective-C dependency for single-header goal)
Understand Your Crashes — CrashCatch Analyzer
CrashCatch generates the report. CrashCatch Analyzer tells you what it means.
Drop in a crash report and get:
- Symbolicated stack traces
- Plain-English root cause explanation (Explain Mode)
- Deep technical analysis for engineers (Engineer Mode)
- PDF export for sharing with your team
Currently in Beta. View on GitHub to download.
Contributing
Contributions are welcome. See CONTRIBUTING.md for guidelines.
License
CrashCatch is licensed under the MIT License. Free to use, modify, and distribute.