Backend Tradeoffs

How to choose the right crash backend in the Native SDK.

The Native SDK lets users decide at compile-time between three crash backends:

  • crashpad
  • breakpad
  • inproc

Currently, crashpad is the default on all desktop platforms because it

  • has an external handler process that allows for external snapshots and sending crash reports immediately (instead of on the next successful start of your application)
  • is the primary target for extension compared to upstream, including
    • client-side stack traces
    • attachment handling
    • HTTP proxy support
    • CMake build scripts
    • GCC and MinGW support
    • FirstChanceHandler on Windows and extension of its synchronization to support Sentry hooks
    • cooperation with Epic's Easy Anti Cheat
  • supports more error types on Linux and Windows (abort() and other fast-fail crashes, handling of heap corruptions)
  • is more maintained upstream (although most changes affect new platforms like Fuchsia)

Sentry decided on crashpad as the default on all platforms because there are a lot of upsides. However, there are use cases where crashpad cannot be used or makes distribution or deployment much harder. We provide other backends for situations when

  • you cannot package or deploy an additional executable (the crashpad_handler)
  • you cannot allow a secondary process to connect via ptrace to your application (AWS Lambda, Flatpak-, Snap-Sandboxes)
  • IPC between your process and the crashpad_handler is inhibited by security settings or not available in your deployment target
  • your deployment scenario cannot wait for the crashpad_handler to finish its work before a shutdown-after-crash (systemd, Docker)
  • you want to distribute your application via the macOS App Store
  • you want to define crash hooks on macOS, because there, error handling happens entirely in the crashpad_handler whereas on Linux and Windows at least the initial handling happens in your process after which crashpad_handler takes over and snapshots the process to send a crash report

In the above cases, if you cannot loosen the requirements of your environment, you have to choose an in-process backend (meaning either breakpad or inproc).

Both backends are comparable in how they differ from crashpad. However, there are also considerable differences between the two:

  • inproc only provides the backtrace of the crashing thread. breakpad records all threads in the minidump.
  • similar to crashpad, breakpad uses the lowest level error handling mechanism on each platform (macOS: mach exception ports, Windows: UnhandledExceptionFilter, Linux: signal handlers), it does cover a smaller range of errors though as mentioned above.
  • inproc, on the other hand, uses signal handling on Linux and macOS (meaning you only get a POSIX compatibility layer over mach exception ports) and UnhandledExceptionFilter on Windows (solely errors registered by SEH)
  • as a result of choosing signal handling on macOS, inproc is currently broken on macOS since Apple eliminated unwinding from signal handlers
  • inproc is exceptionally lightweight and written entirely in C, meaning it does not rely on a weighty C++ runtime library, which is also more often affected by ABI incompatibilities
  • breakpad generates minidumps (like crashpad does), whereas inproc follows the Sentry event structure and primarily defers to the OS-provided unwinder and symbolication capabilities. Sentry can potentially extract more information from the provided minidump than simply a stack trace and registers. However, it also means that the crash context inside the minidump will be opaque until processed in the backend, whereas a local relay instance could process an entire inproc event if required.

inproc is currently the backend of choice for Android because it allows us to couple it with our own fork of a powerful platform unwinder libunwindstack (rather than relying on a user-space interface). This allows us to support very old Android versions.

inproc is the right choice if you

  • want minimal dependencies
  • want the smallest footprint for the resulting artifact
  • don't need to support the latest macOS versions
  • find the minimal featureset compared to breakpad and crashpad sufficient for your scenario

There are many trade-offs in the selection of backends if you dive into the details. The above merely scratches the surface. Sentry suggests a sequence of evaluations like

  • crashpad (default)
  • breakpad
  • inproc

from most feature-complete to least, where a step down should only be triggered by environmental inhibitors. With the above you now have exemplary decision points for your error reporting scenario.

Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").