CrashCatch

August 12, 2026 · View on GitHub

A cross-platform, lightweight, single-header crash-reporting library for modern C++ applications.

License: MIT Header-only Platform C++ Crash Dumps Single Header CI

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
  • .dmp MiniDump (Windows) and .txt human-readable report (Windows, Linux & macOS)
  • onCrash() and onCrashUpload() callbacks fire after crash files are written to disk
  • Demangled symbols on Linux and macOS, SymFromAddr with 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
  • SymInitialize called 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.hpp for C++11/C++98/C consumers
  • CMake install + find_package support
  • Zero external dependencies

Why CrashCatch?

Most crash reporting solutions require heavyweight SDKs, mandatory cloud uploads, or complex build setups. CrashCatch is different:

CrashCatchCrashpadSentry NativeBacktrace
Single header
No external dependencies
Offline-first
Windows + Linux + macOS
onCrash / onUpload hooks
Free & open sourcePartial

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

OSStatusCrash Handling
Windows 10 / 11✅ SupportedSetUnhandledExceptionFilter + MiniDump + StackWalk64
Linux✅ SupportedPOSIX 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 to module+symbol+offset on stripped/Release builds without it. On Apple Silicon (ARM64), integer divide-by-zero does not raise SIGFPE the 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.dmp Binary MiniDump (Windows only, viewable in WinDbg)
  • crash_YYYY-MM-DD_HH-MM-SS.txt Human-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): dumpFilePath and logFilePath were previously std::string and are now std::filesystem::path, which also fixes dumpFolder requiring a trailing path separator. Code that consumed these fields as strings (e.g. passing them to a function expecting const std::string&) will need to call .string() or update the signature to accept const 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:

ExampleWhat it demonstrates
Example_ZeroConfigAuto-init with CRASHCATCH_AUTO_INIT macro
Example_OneLinerCrashCatch::enable() minimal setup
Example_FullConfigAll config options including callbacks
Example_ThreadCrashCrash on a non-main thread
Example_divideByZeroArithmetic exception handling (note: does not raise SIGFPE on Apple Silicon see Supported Platforms)
Example_UploadCrashonCrashUpload reading and uploading files
StackTraceExampleincludeStackTrace 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 -rdynamic for symbol resolution
  • macOS: Clang (via Xcode Command Line Tools, xcode-select --install); file/line resolution additionally requires atos (included with Command Line Tools) and debug symbols

Roadmap

  • Windows crash capture + MiniDump
  • Linux signal handling + backtrace
  • onCrash and onCrashUpload hooks
  • CMake install support
  • DLL / shared library support (CrashCatchDLL.hpp)
  • Windows stack trace in .txt log with file/line info
  • includeStackTrace flag
  • 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.