diff --git a/docs/platforms/native/advanced-usage/backend-tradeoffs/index.mdx b/docs/platforms/native/advanced-usage/backend-tradeoffs/index.mdx index 2486d3b2b5435..1a5f287e84ce7 100644 --- a/docs/platforms/native/advanced-usage/backend-tradeoffs/index.mdx +++ b/docs/platforms/native/advanced-usage/backend-tradeoffs/index.mdx @@ -3,9 +3,10 @@ title: Backend Tradeoffs description: "How to choose the right crash backend in the Native SDK." sidebar_order: 1000 --- -The Native SDK lets users decide at compile-time between three crash backends: +The Native SDK lets users decide at compile-time between multiple crash backends: * `crashpad` +* `native` * `breakpad` * `inproc` @@ -16,7 +17,7 @@ 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) * 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 * 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) -* on macOS, the `crashpad_handler` will receive `EXC_CRASH` Mach exceptions, which the kernel generates during process exit if a terminal POSIX signal hasn't been handled. None of the two other backends will catch this exception. +* on macOS, the `crashpad_handler` will receive `EXC_CRASH` Mach exceptions, which the kernel generates during process exit if a terminal POSIX signal hasn't been handled. None of the other backends will catch this exception. * is more maintained upstream (although most changes affect new platforms like Fuchsia) * 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 * client-side stack traces (this is currently not available on `breakpad`) @@ -41,11 +42,11 @@ Sentry decided on `crashpad` as the default on all platforms because it offers n * 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`). +In the above cases, if you cannot loosen the requirements of your environment, you have to choose another backend (meaning either `native`, `breakpad`, or `inproc`). -### How do I decide between `breakpad` or `inproc`? +### How do I decide between `native`, `breakpad`, and `inproc`? -Both backends are comparable in how they differ from `crashpad`. However, there are also considerable differences between the two: +`native` is the closest alternative to `crashpad` because it keeps crash handling out of process. If your constraints rule out an additional executable, the remaining options are `breakpad` and `inproc`, which are comparable in how they differ from `crashpad` and `native`. 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. @@ -54,7 +55,15 @@ Both backends are comparable in how they differ from `crashpad`. However, there * 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. +* `breakpad` generates minidumps (like `crashpad` and `native` by default), 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. + +### So when do I choose `native`? + +Since SDK version [0.13.2](https://github.com/getsentry/sentry-native/releases/tag/0.13.2), the Native SDK comes with a new experimental out-of-process backend called `native`. It is implemented as part of the Native SDK and built on the SDK's own event, envelope, transport, attachment, options, and hook infrastructure. + +The main advantages are tighter integration with the Native SDK and no external crash-handler dependency. As an out-of-process backend, `native` runs crash handling in the lightweight `sentry-crash` daemon and can send crash reports at crash time, similar to `crashpad`. Because crash collection is implemented in the SDK, `native` can call SDK-level hooks such as `before_screenshot`, and can [report an event, a minidump, or both](/platforms/native/configuration/backends/native/). The backend is also fully compatible with TSAN and ASAN builds. + +Consider `native` when you want out-of-process crash handling with SDK-managed crash collection, when you need sanitizer compatibility, or when `crashpad` does not fit your deployment model. ### So when do I choose `inproc`? @@ -75,8 +84,26 @@ If you dive into the details, you will find many trade-offs in the selection of Sentry suggests the following sequence for your backend evaluations: -* `crashpad` (default) +* `crashpad` (default on Windows, macOS, and Linux), or `native` (experimental) * `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 to help guide you before you start evaluating your error reporting scenario. +* `inproc` (default on Android) + +from most feature-complete to least, where a step down should only be triggered by environmental inhibitors, as summarized in the following table: + +| Feature | `crashpad` | `native` | `breakpad` | `inproc` | +| ------- | ---------- | -------- | ---------- | -------- | +| Deployment | Library 1 + executable | Library 1 + executable | Library 1 | Library 1 | +| Crash handler | Out-of-process | Out-of-process | In-process | In-process | +| Crash upload | At crash time | At crash time | Next restart | Next restart | +| Crash report | Minidump | Event/minidump/both | Minidump | Event | +| Screenshots | Windows 2 | Windows | Windows | Windows | +| Stack walking | Server-side
+ client-side build option | Client-side
+ server-side minidump mode | Server-side | Client-side | +| Captured threads | All | All | All | Crashing | +| Crash hooks | ✅ Windows/Linux
❌ macOS | ✅ | ✅ Windows/macOS
⚠️ Linux (no context) | ✅ | +| Windows WER / fast-fail | ✅ | ✅ | ❌ | ❌ | +| macOS App Sandbox | ❌ | ✅ | ✅ | ✅ | + +* 1 The library supports shared and static builds. +* 2 The `before_screenshot` hook is not supported with `crashpad`. + +With the above, you now have exemplary decision points to help guide you before you start evaluating your error reporting scenario. diff --git a/docs/platforms/native/common/configuration/options.mdx b/docs/platforms/native/common/configuration/options.mdx index 64f5fbea50cdb..7accebb88c118 100644 --- a/docs/platforms/native/common/configuration/options.mdx +++ b/docs/platforms/native/common/configuration/options.mdx @@ -66,6 +66,18 @@ Whether Crashpad should delay application shutdown until the upload of the crash + + +Controls which crash report format the `native` backend sends when the application crashes. This setting only affects the `native` backend. See [Crash Reporting Modes](/platforms/native/configuration/backends/native/#crash-reporting-modes). + + + + + +Controls how much memory the `native` backend captures in minidumps. This setting only affects the `native` backend and crash reporting modes that send a minidump. See [Minidump Capture Modes](/platforms/native/configuration/backends/native/#minidump-capture-modes). + + + Controls whether the SDK should propagate the W3C `traceparent` HTTP header alongside the `sentry-trace` header for [distributed tracing](https://docs.sentry.io/platforms/native/tracing/trace-propagation/custom-instrumentation/). diff --git a/docs/platforms/native/common/enriching-events/screenshots/index.mdx b/docs/platforms/native/common/enriching-events/screenshots/index.mdx index 55431b7b56fb3..31de5314ae112 100644 --- a/docs/platforms/native/common/enriching-events/screenshots/index.mdx +++ b/docs/platforms/native/common/enriching-events/screenshots/index.mdx @@ -8,7 +8,7 @@ og_image: /og-images/platforms-native-common-enriching-events-screenshots.png Sentry makes it possible to automatically take a screenshot and include it as an attachment when a user experiences an error, an exception, or a crash. -This feature is currently only available on Windows and has a few limitations. For example, the `inproc` and `breakpad` backends use local exception handlers for capturing the screenshot and therefore rely on the exception handler being called. Only the `crashpad` backend with an external handler process is able to capture screenshots of fast-fail crashes that bypass Structured Exception Handling ([`SEH`](https://learn.microsoft.com/en-us/windows/win32/debug/structured-exception-handling)). Another example where a screenshot might not be available is when the event happens before the screen starts to load. So inherently, this feature is a best effort solution. +This feature is currently only available on Windows and has a few limitations. For example, the `inproc` and `breakpad` backends use local exception handlers for capturing the screenshot and therefore rely on the exception handler being called. Only the `crashpad` and `native` backends can capture screenshots of fast-fail crashes that bypass Structured Exception Handling ([`SEH`](https://learn.microsoft.com/en-us/windows/win32/debug/structured-exception-handling)) because screenshot capture happens out-of-process. However, `crashpad` does not support the `before_screenshot` hook, because the screenshot is captured out-of-process and the SDK cannot communicate the hook result to the `crashpad_handler`. The `native` backend calls `before_screenshot` during crash handling and communicates the result to the `sentry-crash` daemon, which captures the screenshot out-of-process. Another example where a screenshot might not be available is when the event happens before the screen starts to load. So inherently, this feature is a best effort solution. ## Enabling Screenshots diff --git a/docs/platforms/native/configuration/backends/crashpad.mdx b/docs/platforms/native/configuration/backends/crashpad.mdx index 32a1e1e963e51..ddee0e63287cb 100644 --- a/docs/platforms/native/configuration/backends/crashpad.mdx +++ b/docs/platforms/native/configuration/backends/crashpad.mdx @@ -47,4 +47,4 @@ locking in place. When using the Crashpad backend on macOS, the status of crashed sessions can not be reliably determined, and may be classified as [`abnormal`](/product/releases/health/release-details/) exits instead. -If you want to deploy your application to the macOS App Store or distribute it "sandboxed" outside, the crashpad client will fail to start the `crashpad_handler` executable (due to sandbox restrictions). For these deployment targets, we recommend using the `breakpad` backend. +If you want to deploy your application to the macOS App Store or distribute it "sandboxed" outside, the crashpad client will fail to start the `crashpad_handler` executable (due to sandbox restrictions). For these deployment targets, use the [`native`](/platforms/native/configuration/backends/native/) backend, or `breakpad`/`inproc` if you cannot ship an additional executable. diff --git a/docs/platforms/native/configuration/backends/index.mdx b/docs/platforms/native/configuration/backends/index.mdx index 3bba19787e47b..c98431c36bf26 100644 --- a/docs/platforms/native/configuration/backends/index.mdx +++ b/docs/platforms/native/configuration/backends/index.mdx @@ -15,17 +15,31 @@ 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. +- [`native`](native/): This uses the out-of-process native handler. It is + available as an experimental backend since SDK version [0.13.2](https://github.com/getsentry/sentry-native/releases/tag/0.13.2). - `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"). + 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. `Breakpad` and `inproc` both run "in-process", so they run in the same process as the application they capture crashes for. This means these backends can't send a crash to Sentry immediately after it happens. Instead, the crash report is -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. +written to disk and sent the next time the application is run. Since `crashpad` +and `native` run in a different process, they don't have this limitation. + +The following table summarizes backend support for each target OS: + +| OS | `crashpad` | `native` | `breakpad` | `inproc` | +| -------- | ---------- | -------- | ---------- | -------- | +| Windows | ✅ Default | ⚠️ Experimental | ✅ | ✅ | +| macOS | ✅ Default | ⚠️ Experimental | ✅ | ✅ | +| Linux | ✅ Default | ⚠️ Experimental | ✅ | ✅ | +| Android | ❌ | ❌ | ⚠️ Untested 1 | ✅ Default | +| iOS | ❌ | ❌ | ⚠️ Untested 1 | ⚠️ Untested 1 | + +1 Builds and should work, but is untested. The [Advanced Usage](/platforms/native/advanced-usage/backend-tradeoffs) section explains the trade-offs in choosing the correct backend for your use case. diff --git a/docs/platforms/native/configuration/backends/native.mdx b/docs/platforms/native/configuration/backends/native.mdx new file mode 100644 index 0000000000000..0b912c466ef90 --- /dev/null +++ b/docs/platforms/native/configuration/backends/native.mdx @@ -0,0 +1,62 @@ +--- +title: Native +description: Learn how to configure the experimental native crash backend. +--- + +The `native` backend is an experimental out-of-process backend available since +SDK version [0.13.2](https://github.com/getsentry/sentry-native/releases/tag/0.13.2). +It is the most actively developed crash backend and is intended to become the +default backend in the future. +To use it, configure the CMake build with the `SENTRY_BACKEND=native` option: + +```shell +cmake -B build -D SENTRY_BACKEND=native +``` + +This builds the `sentry-crash` executable alongside the `sentry` library. Ship +the executable with your application so the SDK can start it during +initialization. + +## Crash Reporting Modes + +Use `sentry_options_set_crash_reporting_mode` before `sentry_init` to configure +which crash report format the backend sends when the application crashes. + +| Mode | Sends | Stack walking | +| ---- | ----- | ------------- | +| `SENTRY_CRASH_REPORTING_MODE_MINIDUMP` | Minidump | Server-side | +| `SENTRY_CRASH_REPORTING_MODE_NATIVE` | Event | Client-side | +| `SENTRY_CRASH_REPORTING_MODE_NATIVE_WITH_MINIDUMP` | Event and minidump | Client-side | + +`SENTRY_CRASH_REPORTING_MODE_NATIVE_WITH_MINIDUMP` is the default. It sends an +event with client-side stack traces and attaches a minidump for deeper crash +analysis. Modes that include a minidump send it as an `event.minidump` +attachment. + +## Minidump Capture Modes + +Use `sentry_options_set_minidump_mode` before `sentry_init` to control how much +memory the backend captures in minidumps. This setting only affects crash +reporting modes that send a minidump. + +| Mode | Captures | Tradeoff | +| ---- | -------- | -------- | +| `SENTRY_MINIDUMP_MODE_STACK_ONLY` | Stack memory | Smallest and fastest, about 100 KB-1 MB | +| `SENTRY_MINIDUMP_MODE_SMART` | Stack memory and heap memory around the crash | Balanced default, about 5-10 MB | +| `SENTRY_MINIDUMP_MODE_FULL` | Full process memory | Most detail, but largest and slowest, tens to hundreds of MB | + +For production builds, use `SENTRY_MINIDUMP_MODE_STACK_ONLY` or +`SENTRY_MINIDUMP_MODE_SMART`. Use `SENTRY_MINIDUMP_MODE_FULL` only when you need +the extra memory for development, staging, or a specific crash investigation. + +For example, to send only a small minidump for server-side stack walking: + +```c +sentry_options_t *options = sentry_options_new(); + +sentry_options_set_crash_reporting_mode( + options, SENTRY_CRASH_REPORTING_MODE_MINIDUMP); +sentry_options_set_minidump_mode(options, SENTRY_MINIDUMP_MODE_STACK_ONLY); + +sentry_init(options); +```