Skip to content

Commit 19ea857

Browse files
supervacuuskahestvaindbruno-garcia
authored
feat(native): add backend trade-offs to Advanced Usage (#11721)
* feat(native): add backend trade-offs to Advanced Usage * Add hook on macOS exception * Update docs/platforms/native/advanced-usage/backend-tradeoffs/index.mdx Co-authored-by: Karl Heinz Struggl <[email protected]> * Update docs/platforms/native/advanced-usage/backend-tradeoffs/index.mdx Co-authored-by: Karl Heinz Struggl <[email protected]> * Update docs/platforms/native/advanced-usage/backend-tradeoffs/index.mdx Co-authored-by: Karl Heinz Struggl <[email protected]> * Update docs/platforms/native/advanced-usage/backend-tradeoffs/index.mdx Co-authored-by: Karl Heinz Struggl <[email protected]> * Update docs/platforms/native/advanced-usage/backend-tradeoffs/index.mdx Co-authored-by: Ivan Dlugos <[email protected]> * Update docs/platforms/native/advanced-usage/backend-tradeoffs/index.mdx Co-authored-by: Ivan Dlugos <[email protected]> * Update docs/platforms/native/advanced-usage/backend-tradeoffs/index.mdx Co-authored-by: Karl Heinz Struggl <[email protected]> * Highlight inproc macOS breakage * grammar inproc macOS 13 breakage * Update docs/platforms/native/advanced-usage/backend-tradeoffs/index.mdx Co-authored-by: Bruno Garcia <[email protected]> * rewriting some parts for clarity --------- Co-authored-by: Karl Heinz Struggl <[email protected]> Co-authored-by: Ivan Dlugos <[email protected]> Co-authored-by: Bruno Garcia <[email protected]>
1 parent e4a73d6 commit 19ea857

File tree

2 files changed

+81
-6
lines changed
  • docs/platforms/native

2 files changed

+81
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
title: Backend Tradeoffs
3+
description: "How to choose the right crash backend in the Native SDK."
4+
sidebar_order: 1000
5+
---
6+
The Native SDK lets users decide at compile-time between three crash backends:
7+
8+
* `crashpad`
9+
* `breakpad`
10+
* `inproc`
11+
12+
Currently, `crashpad` is the default on all desktop platforms because it
13+
14+
* 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)
15+
* further, snapshotting, report management, and uploading outside the crashed process are safer because the `crashpad_handler` is not affected by any corruptions that led to a crash
16+
* supports more error types on [Linux](/platforms/native/advanced-usage/signal-handling/#signals-of-interest) and Windows (`abort()` and other `fast-fail` crashes, handling of heap corruptions)
17+
* is more maintained upstream (although most changes affect new platforms like Fuchsia)
18+
* is the primary target for Sentry-developed extensions to the upstream implementation of backend handlers (most of which aren't a particular upside vs. the other backends, but changes to reach parity), including
19+
* client-side stack traces (this is currently not available on `breakpad`)
20+
* attachment handling
21+
* HTTP proxy support
22+
* GCC and MinGW support
23+
* `FirstChanceHandler` on Windows and extension of its synchronization to support Sentry hooks
24+
* cooperation with Epic's Easy Anti Cheat
25+
* CMake build scripts (some users use our backend handler forks solely because of this reason)
26+
27+
### When shouldn't I use the `crashpad` backend?
28+
29+
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
30+
31+
* you cannot package or deploy an additional executable (the `crashpad_handler`)
32+
* you cannot allow a secondary process to connect via `ptrace` to your application (AWS Lambda, Flatpak-, Snap-Sandboxes)
33+
* IPC between your process and the `crashpad_handler` is inhibited by security settings or not available in your deployment target
34+
* your deployment scenario cannot wait for the `crashpad_handler` to finish its work before a shutdown-after-crash (systemd, Docker)
35+
* you want to distribute your application via the macOS App Store
36+
* 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
37+
38+
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`).
39+
40+
### How do I decide between `breakpad` or `inproc`?
41+
42+
Both backends are comparable in how they differ from `crashpad`. However, there are also considerable differences between the two:
43+
44+
* `inproc` only provides the backtrace of the crashing thread. `breakpad` records all threads in the minidump.
45+
* 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.
46+
* `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.
47+
* as a result of choosing signal handling on macOS, `inproc` is currently broken on macOS since Apple eliminated unwinding from signal handlers
48+
* `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
49+
* `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 - potentially - extract more information from the provided minidump than from only a stack trace and registers. However, it also means that the crash context inside the minidump will be opaque until 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.
50+
51+
### So when do I choose `inproc`?
52+
53+
`inproc` is currently the backend of choice for `Android` because it allows us to bundle it with our fork of the platform unwinder `libunwindstack` that provides a complete interface for unwinding and symbolication (rather than relying on the minimal user-space interface). This enables us to support a broad range of Android versions. In addition, stack walking on-device on Android is preferred since we don't have all system symbols available for server-side symbolication. A [best-effort symbol collection exists](https://github.com/getsentry/symbol-collector), but that'll never be as reliable as stackwalking on-device.
54+
55+
`inproc` is the right choice if you
56+
57+
* want minimal dependencies
58+
* want the smallest footprint for the resulting artifact
59+
* don't need to support the latest macOS versions
60+
* find the minimal feature set compared to `breakpad` and `crashpad` sufficient for your scenario
61+
62+
### Summary
63+
64+
If you dive into the details, you will find many trade-offs in the selection of backends. The above merely provides a first overview. Further, the above is only a snapshot of the current capabilities, where some trade-offs are incidental and do not follow a particular strategy or technological necessity. The primary reason for providing multiple backends is to cover as many user scenarios as possible, which requires a bit of insight if you decide to deviate from the defaults.
65+
66+
Sentry suggests the following sequence for your backend evaluations:
67+
68+
* `crashpad` (default)
69+
* `breakpad`
70+
* `inproc`
71+
72+
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 that can help you before you start the evaluation of your error reporting scenario.

Diff for: docs/platforms/native/configuration/backends/index.mdx

+9-6
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,22 @@ and libraries. Similar to plugins, they extend the functionality of the Sentry
99
SDK.
1010

1111
The Native SDK can use different backends that are responsible for capturing
12-
crashes. The backend is configured at build-time, using the `SENTRY_BACKEND`
12+
crashes. The backend is configured at build-time using the `SENTRY_BACKEND`
1313
CMake option, with support for the following options:
1414

1515
- [`crashpad`](crashpad/): This uses the out-of-process crashpad handler.
16-
It is used as the default on Windows, macOS and Linux.
16+
It is used as the default on Windows, macOS, and Linux.
1717
- `breakpad`: This uses the in-process breakpad handler.
18-
- `inproc`: A small in-process handler which is supported on all platforms,
19-
and is used as default on Android.
18+
- `inproc`: A small in-process handler supported on all platforms
19+
and used as a default on Android. It has no longer worked on macOS since version 13 ("Ventura").
2020
- `none`: This builds `sentry-native` without a backend, so it does not handle
21-
crashes at all. It is primarily used for tests.
21+
crashes. It is primarily used for tests.
2222

2323
`Breakpad` and `inproc` both run "in-process", so they run in the same process
2424
as the application they capture crashes for. This means these backends can't
2525
send a crash to Sentry immediately after it happens. Instead, the crash report is
2626
written to disk and sent the next time the application is run. Since `Crashpad`
27-
runs in a different process it doesn't have this limitation.
27+
runs in a different process, it doesn't have this limitation.
28+
29+
The [Advanced Usage](/platforms/native/advanced-usage/backend-tradeoffs) section
30+
explains the trade-offs in choosing the correct backend for your use case.

0 commit comments

Comments
 (0)