Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ Both backends are comparable in how they differ from `crashpad`. However, there
* `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` uses signal handling on macOS, meaning you only get a `POSIX` compatibility layer over Mach exception ports. It relies on the same mechanisms as `breakpad` on Windows and Linux.
* as a result of choosing signal handling on macOS, `inproc` is currently broken on macOS since Apple eliminated unwinding from signal handlers
* on all platforms, `inproc` delegates crash processing from the signal handler (or `UnhandledExceptionFilter` on Windows) to a separate handler thread. The signal handler does minimal work (exchanging crash context and waking the handler thread) while the handler thread performs stack walking, event construction, and reporting.
* if the handler thread is unavailable (for example, because synchronization failed, the thread crashed, or never started), `inproc` falls back to processing directly in the signal handler.
* on macOS, the handler thread uses a frame-pointer-based stack walker for arm64 and x86-64, which avoids the limitations that previously made `inproc` unusable on recent macOS versions.
* `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 processing infrastructure can extract more information from the provided minidump than from just a stack trace and registers. However, it also means that the crash context inside the minidump will remain opaque until it is processed in the backend. In contrast, if required, a local `relay` instance (or another application-level proxy) could process an entire `inproc` event with only JSON parsing capabilities.

Expand All @@ -62,8 +64,10 @@ Both backends are comparable in how they differ from `crashpad`. However, there

* want minimal dependencies
* want the smallest footprint for the resulting artifact
* don't need to support the latest macOS versions
* find the minimal feature set compared to `breakpad` and `crashpad` sufficient for your scenario
* want primarily client-side stack traces
* want to inspect the fully available event context in a hook
* look for a backend that runs on all supported platforms with an equivalent support for the user-facing API

### Summary

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ If you use the `crashpad` backend, in addition to the above, on Linux, you will

## What to Consider When Writing `on_crash` Hooks

The callback that you register as an `on_crash` hook runs in the context of a signal handler. (`before_send` also runs in the context of a signal handler, unless you turned it off for crashes.)
The callback that you register as an `on_crash` hook runs in the context of a crash handler. For the `inproc` backend on all platforms, the hook typically runs on a separate handler thread that is woken by the signal handler (or `UnhandledExceptionFilter` on Windows), rather than directly inside the signal handler itself.

Since signal handlers can interrupt the running process (and even each other) at any time, take special care when writing them.
If the handler thread is unavailable, `inproc` falls back to running the hook directly in the signal handler. For `crashpad` and `breakpad`, the hook runs in the context of their respective exception handling mechanisms. (`before_send` also runs in this context, unless you turned it off for crashes.)

Although the `inproc` handler thread is not a signal handler, take special care when writing hooks because thread synchronization and heap allocations are still problematic in the context of a crashed process.

Our developer documentation provides [guidelines for writing signal handlers](https://develop.sentry.dev/sdk/signal-handlers/). If you run on Linux or Android, these guidelines also apply to hooks. Signal handlers are notoriously difficult to work with, so it is crucial to follow these guidelines in order to avoid causing severe faults (like crashes and deadlocks), which can prevent terminating programs and sending reports.

Expand All @@ -58,4 +60,4 @@ Further, it is crucial to understand that this signal handler stack configuratio

This differs from the situation on Android, where the `Bionic libc` `pthread` implementation initializes each thread with a separate signal handler stack. `Bionic` sets the Android stack sizes from above, and the Android Runtime Team recommends _not_ overwriting these settings.

In this scenario, most of the above-defined stack sizes will be fully available to your defined `on_crash` hook. Still, be considerate of stack usage. If you need to fill any large data structures within the hook, we recommend pre-allocating them at initialization and only filling the values within the hook.
In this scenario, most of the above-defined stack sizes will be fully available to your defined `on_crash` hook. Still, be considerate of stack usage. If you need to fill any large data structures within the hook, we recommend pre-allocating them at initialization and only filling the values within the hook.
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ or care than other crashes.

<Alert>
Be aware that, in contrast to Mach exception port usage, signal handlers on macOS run on the same thread that caused the
signal and thus also need a `sigaltstack` to handle any crash from a stack overflow. Only the `inproc` backend on macOS
currently relies entirely on signal handlers, and its signal stack is set up equivalently to Linux or other POSIX platforms.
signal and thus also need a `sigaltstack` to handle any crash from a stack overflow. The `inproc` backend relies on signal
handlers on macOS and Linux but, on all platforms, delegates crash processing to a separate handler thread.

Both the thread on which the SDK was initialized and the handler thread receive a `sigaltstack` if one is not already
configured, which helps prevent stack overflow from interfering with crash reporting.
</Alert>
5 changes: 2 additions & 3 deletions docs/platforms/native/configuration/backends/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ CMake option, with support for the following options:
- [`crashpad`](crashpad/): This uses the out-of-process crashpad handler.
It is used as the default on Windows, macOS, and Linux.
- `breakpad`: This uses the in-process breakpad handler.
- `inproc`: A small in-process handler supported on all platforms
and used as a default on Android. It has no longer worked on macOS since version 13 ("Ventura").
- `inproc`: A small in-process handler supported on all platforms and used as a default on Android.
- `none`: This builds `sentry-native` without a backend, so it does not handle
crashes. It is primarily used for tests.

Expand All @@ -26,5 +25,5 @@ send a crash to Sentry immediately after it happens. Instead, the crash report i
written to disk and sent the next time the application is run. Since `Crashpad`
runs in a different process, it doesn't have this limitation.

The [Advanced Usage](/platforms/native/advanced-usage/backend-tradeoffs) section
The [Advanced Usage](/platforms/native/advanced-usage/backend-tradeoffs) section
explains the trade-offs in choosing the correct backend for your use case.
Loading