From 1e99ad122fefcc2016e09f996178037128a536f2 Mon Sep 17 00:00:00 2001 From: Bobby Galli Date: Fri, 11 Sep 2026 23:41:09 -0400 Subject: [PATCH] docs: BugSplat Native (9.0) section, per-platform guides, migration, and the native commit fields New "BugSplat Native (9.0)" group under Integrations: overview, Windows (verified), macOS, Linux, Android, iOS/tvOS (each with a status line), hang detection, structured reports, user feedback, crash data format, migration from bugsplat-windows 8.x / bugsplat-apple 2.x / bugsplat-android 1.x. Pointers from the Welcome page, the integrations indexes, the existing platform guides and Downloads. Crash Post Endpoints documents infoUrl timing and the fields the native SDKs send (environment, crashSignature, crashHash, reportKind annotation); User Feedback points at the SDK APIs; the support-response FAQ no longer says other platforms are coming soon. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01HHo6UdKBQXDABUhRgHWdW2 --- README.md | 4 + SUMMARY.md | 11 ++ ...esponses-for-windows-c++-.net-and-macos.md | 2 +- .../development/web-services/crash.md | 14 ++ .../development/web-services/user-feedback.md | 4 + .../getting-started/integrations/README.md | 8 + .../integrations/desktop/README.md | 4 + .../integrations/desktop/cplusplus/README.md | 4 + .../integrations/desktop/linux.md | 4 + .../integrations/desktop/macos.md | 4 + .../getting-started/integrations/downloads.md | 1 + .../integrations/mobile/README.md | 4 + .../integrations/mobile/android.md | 4 + .../integrations/mobile/ios.md | 4 + .../integrations/native/README.md | 99 +++++++++++ .../integrations/native/android.md | 56 ++++++ .../integrations/native/crash-data-format.md | 69 ++++++++ .../integrations/native/hang-detection.md | 56 ++++++ .../integrations/native/ios.md | 60 +++++++ .../integrations/native/linux.md | 75 ++++++++ .../integrations/native/macos.md | 74 ++++++++ .../integrations/native/migration.md | 59 +++++++ .../integrations/native/structured-reports.md | 89 ++++++++++ .../integrations/native/user-feedback.md | 44 +++++ .../integrations/native/windows.md | 160 ++++++++++++++++++ 25 files changed, 912 insertions(+), 1 deletion(-) create mode 100644 introduction/getting-started/integrations/native/README.md create mode 100644 introduction/getting-started/integrations/native/android.md create mode 100644 introduction/getting-started/integrations/native/crash-data-format.md create mode 100644 introduction/getting-started/integrations/native/hang-detection.md create mode 100644 introduction/getting-started/integrations/native/ios.md create mode 100644 introduction/getting-started/integrations/native/linux.md create mode 100644 introduction/getting-started/integrations/native/macos.md create mode 100644 introduction/getting-started/integrations/native/migration.md create mode 100644 introduction/getting-started/integrations/native/structured-reports.md create mode 100644 introduction/getting-started/integrations/native/user-feedback.md create mode 100644 introduction/getting-started/integrations/native/windows.md diff --git a/README.md b/README.md index e7dd733c..b67b8a32 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,10 @@ Ready to wire up your own application? The **Full Setup Guide** walks you throug Pick your platform and follow its SDK guide. (Each guide assumes you've already [created a database](introduction/getting-started/create-a-new-database-in-bugsplat.md), which takes about 30 seconds.) +{% content-ref url="introduction/getting-started/integrations/native/" %} +[native](introduction/getting-started/integrations/native/) +{% endcontent-ref %} + {% content-ref url="introduction/getting-started/integrations/desktop/" %} [desktop](introduction/getting-started/integrations/desktop/) {% endcontent-ref %} diff --git a/SUMMARY.md b/SUMMARY.md index 9ca30558..061f048d 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -32,6 +32,17 @@ ## 🧩 Integrations * [Choose Your Platform](introduction/getting-started/integrations/README.md) +* [🧬 BugSplat Native (9.0)](introduction/getting-started/integrations/native/README.md) + * [Windows](introduction/getting-started/integrations/native/windows.md) + * [macOS](introduction/getting-started/integrations/native/macos.md) + * [Linux](introduction/getting-started/integrations/native/linux.md) + * [Android](introduction/getting-started/integrations/native/android.md) + * [iOS and tvOS](introduction/getting-started/integrations/native/ios.md) + * [Hang Detection](introduction/getting-started/integrations/native/hang-detection.md) + * [Structured Reports](introduction/getting-started/integrations/native/structured-reports.md) + * [User Feedback](introduction/getting-started/integrations/native/user-feedback.md) + * [Crash Data Format](introduction/getting-started/integrations/native/crash-data-format.md) + * [Migrating to 9.0](introduction/getting-started/integrations/native/migration.md) * [💻 Desktop Software](introduction/getting-started/integrations/desktop/README.md) * [BugSplat for Windows (C++)](introduction/getting-started/integrations/desktop/cplusplus/README.md) * [Full Memory Dumps](introduction/getting-started/integrations/desktop/cplusplus/full-memory-dumps.md) diff --git a/education/faq/localized-support-responses-for-windows-c++-.net-and-macos.md b/education/faq/localized-support-responses-for-windows-c++-.net-and-macos.md index cffe0965..6733caa8 100644 --- a/education/faq/localized-support-responses-for-windows-c++-.net-and-macos.md +++ b/education/faq/localized-support-responses-for-windows-c++-.net-and-macos.md @@ -1,6 +1,6 @@ # Localized Support Responses for Windows C++, .NET, and macOS -BugSplat's Support Response feature allows developers to display a localized message to their users at the time of a crash. The Support Response feature is currently supported by our [Windows C++](../../introduction/getting-started/integrations/desktop/cplusplus/), [.NET Framework](../../introduction/getting-started/integrations/desktop/windows-dot-net-framework.md), and [macOS](../../introduction/getting-started/integrations/desktop/macos.md) integrations and support for other platforms is coming soon. The following steps will allow you to create a localized Support Response message for all crashes in your database. These same steps can be applied to create localized [stack key specific Support Response](../../introduction/production/setting-up-custom-support-responses.md#creating-a-crash-specific-support-response) messages as well. +BugSplat's Support Response feature allows developers to display a localized message to their users at the time of a crash. The Support Response feature is supported by our [Windows C++](../../introduction/getting-started/integrations/desktop/cplusplus/), [.NET Framework](../../introduction/getting-started/integrations/desktop/windows-dot-net-framework.md), and [macOS](../../introduction/getting-started/integrations/desktop/macos.md) integrations, and by [BugSplat Native 9.0](../../introduction/getting-started/integrations/native/) on every platform it runs on: the dialog opens the response after an interactive upload on Windows, macOS and Linux, and the mobile prompts hand your app the response URL (`infoUrl`). The following steps will allow you to create a localized Support Response message for all crashes in your database. These same steps can be applied to create localized [stack key specific Support Response](../../introduction/production/setting-up-custom-support-responses.md#creating-a-crash-specific-support-response) messages as well. ## Step 1 diff --git a/introduction/development/web-services/crash.md b/introduction/development/web-services/crash.md index 820bced2..e84aba44 100644 --- a/introduction/development/web-services/crash.md +++ b/introduction/development/web-services/crash.md @@ -126,6 +126,20 @@ Commits the uploaded crash file for processing by BugSplat. {% endtab %} {% endtabs %} +`infoUrl` is returned whenever a [support response](../../production/setting-up-custom-support-responses.md) is configured, even before the crash has been processed: the page shows a processing state and resolves once the stack key is known, so a client can open it as soon as the commit succeeds. + +#### Fields sent by BugSplat Native 9.0 + +The [BugSplat Native](../../getting-started/integrations/native/) SDKs use exactly the three calls above on every platform and send, on the commit call, `appKey`, `user`, `email`, `description`, `notes`, `attributes`, `environment`, `crashSignature` and `crashHash`: + +| Field | What it carries | +| --- | --- | +| `environment` | The OS and hardware the app ran on, detected by the SDK and overridable (`Windows 11 10.0.26200 x64`, `Android 14 (API 34) arm64-v8a; Google Pixel 8`). Stored on the crash and shown on the crash page; every Crashpad platform posts with `crashTypeId=5`, so this is how platforms are told apart. Up to 255 characters. | +| `crashSignature` | The crashing thread's application frames as `module:0xrva` joined with `\|` (or `function\|file\|line` per frame for XML/JSON reports), computed before upload. | +| `crashHash` | SHA-256 of `crashSignature`. When BugSplat has processed the same hash recently for the database, the new crash reuses that stack key and skips the stack analyzer; the empty-input digest (`e3b0c442...b855`) means "no signature". | + +Hang reports and non-fatal captures from these SDKs post under the platform's normal crash type; the kind of report (`crash`, `hang`, `capture`) travels inside the dump as the Crashpad annotation `bugsplat.reportKind`, together with `bugsplat.hangDurationMs`. + ### Crash Type Reference Use the following `crashType` and `crashTypeId` values when committing uploads. diff --git a/introduction/development/web-services/user-feedback.md b/introduction/development/web-services/user-feedback.md index 97be2e9e..b4f80809 100644 --- a/introduction/development/web-services/user-feedback.md +++ b/introduction/development/web-services/user-feedback.md @@ -46,6 +46,10 @@ Special XML characters in title and description (`&`, `<`, `>`, `"`, `'`) must b \* At least one of `title` or `description` must be provided. +## From the SDKs + +You do not need to speak this protocol yourself when you use a BugSplat SDK: [BugSplat Native 9.0](../../getting-started/integrations/native/user-feedback.md) (`bugsplat_post_feedback`, C++ `PostFeedback`, .NET `PostFeedback`), [macOS and iOS](../../getting-started/integrations/desktop/macos.md#user-feedback) (`postFeedback`) and [BugSplat for Windows](../../getting-started/integrations/desktop/cplusplus/#user-feedback) (`PostFeedback`) build and upload the report for you and return the crash id and support-response URL. + ## Uploading via Presigned URL User feedback reports are uploaded using the same presigned URL flow as crash reports. See [Crash Post Endpoints](crash.md) for full details on Steps 1-3. diff --git a/introduction/getting-started/integrations/README.md b/introduction/getting-started/integrations/README.md index 740eb3a8..85ebda59 100644 --- a/introduction/getting-started/integrations/README.md +++ b/introduction/getting-started/integrations/README.md @@ -14,6 +14,14 @@ If you are creating a new account, you'll have an option to access these documen ### Integrations +{% hint style="success" %} +**New: BugSplat Native 9.0** is one out-of-process SDK for Windows, macOS, Linux, Android and iOS/tvOS, with the same dialog, upload and support response everywhere. Windows is verified; the other platforms are being brought up. Start at [BugSplat Native](native/). +{% endhint %} + +{% content-ref url="native/" %} +[native](native/) +{% endcontent-ref %} + {% content-ref url="desktop/" %} [desktop](desktop/) {% endcontent-ref %} diff --git a/introduction/getting-started/integrations/desktop/README.md b/introduction/getting-started/integrations/desktop/README.md index 2a2faf42..b2ff403f 100644 --- a/introduction/getting-started/integrations/desktop/README.md +++ b/introduction/getting-started/integrations/desktop/README.md @@ -1,5 +1,9 @@ # 💻 Desktop Software +{% hint style="info" %} +Starting a new Windows, macOS or Linux integration? [BugSplat Native 9.0](../native/) is the successor to the Windows C++ and macOS SDKs below: one out-of-process crash reporter with the same dialog and support response on every desktop platform. +{% endhint %} + BugSplat provides best-in-class support for desktop software: native Windows [C++](cplusplus/) and [.NET Framework](windows-dot-net-framework.md) applications, [.NET Standard](dot-net-standard.md), [macOS](macos.md) 11.5+ (including ARM Macs), and [Linux](linux.md). It also covers cross-platform desktop frameworks and languages ([Electron](electron.md), [Qt](qt.md), [Java](java.md), and [Python](python.md)), plus the native [Crashpad](crashpad) and [Breakpad](breakpad.md) crash handlers. Take a look at the guides below to configure crash reporting in your app. {% page-ref page="cplusplus/" %} diff --git a/introduction/getting-started/integrations/desktop/cplusplus/README.md b/introduction/getting-started/integrations/desktop/cplusplus/README.md index 2b4e08de..dca23ba8 100644 --- a/introduction/getting-started/integrations/desktop/cplusplus/README.md +++ b/introduction/getting-started/integrations/desktop/cplusplus/README.md @@ -4,6 +4,10 @@ Need help upgrading from an older version of BugSplat? Check out our [upgrade guide](bugsplat-for-windows-upgrade-guide.md) to get started. {% endhint %} +{% hint style="success" %} +This is the 8.x SDK. Its successor, [BugSplat Native 9.0](../../native/windows.md), keeps the same concepts and runtime file names on a cross-platform, out-of-process core; see [Migrating to 9.0](../../native/migration.md). 8.x keeps working and receives critical fixes. +{% endhint %} + ### Overview 👀 This document explains how to modify your Microsoft Visual C++ application to provide full debug information to the BugSplat web application when it crashes. diff --git a/introduction/getting-started/integrations/desktop/linux.md b/introduction/getting-started/integrations/desktop/linux.md index c7da783b..0effcc31 100644 --- a/introduction/getting-started/integrations/desktop/linux.md +++ b/introduction/getting-started/integrations/desktop/linux.md @@ -1,5 +1,9 @@ # Linux +{% hint style="info" %} +This guide integrates Crashpad by hand. [BugSplat Native 9.0 for Linux](../native/linux.md) packages the same capture with a monitor, a dialog, attachments, hang detection and the support response, and is being brought up now. +{% endhint %} + ## Overview BugSplat recommends using [Crashpad](https://chromium.googlesource.com/crashpad/crashpad) for Linux crash reporting. Crashpad is Google's latest open-source crash reporting tool. It is the successor to the popular Breakpad crash reporter and allows you to submit minidumps to a configured URL after a crash occurs in your product. diff --git a/introduction/getting-started/integrations/desktop/macos.md b/introduction/getting-started/integrations/desktop/macos.md index 46c35e73..d5c029b8 100644 --- a/introduction/getting-started/integrations/desktop/macos.md +++ b/introduction/getting-started/integrations/desktop/macos.md @@ -1,5 +1,9 @@ # macOS +{% hint style="info" %} +This is bugsplat-apple 2.x, the shipping macOS SDK. Its successor on the cross-platform, out-of-process core is [BugSplat Native 9.0 for macOS](../native/macos.md) (bugsplat-apple 9.0), currently being brought up. +{% endhint %} + ### Introduction 👋 BugSplat.xcframework enables posting crash reports from iOS, macOS, and Mac Catalyst applications to BugSplat. Visit [bugsplat.com](https://www.bugsplat.com/) for more information and to sign up for an account. diff --git a/introduction/getting-started/integrations/downloads.md b/introduction/getting-started/integrations/downloads.md index c12d1f37..9a2f6bf7 100644 --- a/introduction/getting-started/integrations/downloads.md +++ b/introduction/getting-started/integrations/downloads.md @@ -10,6 +10,7 @@ description: >- | | | | ------------------------ | ------------------------------------------------------------------------- | +| BugSplat Native 9.0 (Windows, macOS, Linux, Android, iOS) | [GitHub releases](https://github.com/BugSplat-Git/bugsplat-native/releases), `BugSplatDotNet` on NuGet; see [platform docs](native/) | | Windows (Native C++) | [Download](https://app.bugsplat.com/browse/download_item.php?item=native) | | Windows (.NET Framework) | [Download](https://app.bugsplat.com/browse/download_item.php?item=dotnet) | | macOS | See platform docs ([here](desktop/macos.md)) | diff --git a/introduction/getting-started/integrations/mobile/README.md b/introduction/getting-started/integrations/mobile/README.md index 15a8fecb..3cc96122 100644 --- a/introduction/getting-started/integrations/mobile/README.md +++ b/introduction/getting-started/integrations/mobile/README.md @@ -2,6 +2,10 @@ Mobile is the most popular software development platform and continues to grow. In a ruthlessly competitive environment, your team cannot ship buggy code. Your mobile developers need a crash reporting solution to ensure the utmost quality in your application. BugSplat has you covered for all your mobile crash reporting needs. +{% hint style="info" %} +[BugSplat Native 9.0](../native/) brings the Android and iOS/tvOS SDKs onto the same core as desktop (bugsplat-android 9.0 and bugsplat-apple 9.0). Those releases are being brought up; the guides below are the shipping SDKs today. +{% endhint %} + {% content-ref url="android.md" %} [android.md](android.md) {% endcontent-ref %} diff --git a/introduction/getting-started/integrations/mobile/android.md b/introduction/getting-started/integrations/mobile/android.md index 4a60b784..3342c03a 100644 --- a/introduction/getting-started/integrations/mobile/android.md +++ b/introduction/getting-started/integrations/mobile/android.md @@ -1,5 +1,9 @@ # Android +{% hint style="info" %} +This is bugsplat-android 1.x, the shipping Android SDK. Its successor on the cross-platform core is [BugSplat Native 9.0 for Android](../native/android.md) (bugsplat-android 9.0), currently being brought up. +{% endhint %} + ### Introduction 👋 The `bugsplat-android` library enables posting native crash reports, Application Not Responding (ANR) events, and user feedback to BugSplat from Android devices. Visit [bugsplat.com](https://www.bugsplat.com/) for more information and to sign up for an account. diff --git a/introduction/getting-started/integrations/mobile/ios.md b/introduction/getting-started/integrations/mobile/ios.md index b37e0dad..52350aeb 100644 --- a/introduction/getting-started/integrations/mobile/ios.md +++ b/introduction/getting-started/integrations/mobile/ios.md @@ -1,5 +1,9 @@ # iOS +{% hint style="info" %} +This is bugsplat-apple 2.x, the shipping iOS SDK. Its successor on the cross-platform core is [BugSplat Native 9.0 for iOS and tvOS](../native/ios.md) (bugsplat-apple 9.0), currently being brought up. +{% endhint %} + ### Introduction 👋 BugSplat.xcframework enables posting crash reports from iOS, macOS, and Mac Catalyst applications to BugSplat. Visit [bugsplat.com](https://www.bugsplat.com/) for more information and to sign up for an account. diff --git a/introduction/getting-started/integrations/native/README.md b/introduction/getting-started/integrations/native/README.md new file mode 100644 index 00000000..d36e1d6c --- /dev/null +++ b/introduction/getting-started/integrations/native/README.md @@ -0,0 +1,99 @@ +--- +description: >- + BugSplat Native 9.0 is one out-of-process crash reporter for Windows, macOS, + Linux, Android, iOS and tvOS: the same dialog, upload path, support response + and crash-report format on every platform. +--- + +# 🧬 BugSplat Native (9.0) + +BugSplat Native is the successor to BugSplat for Windows 8.x, bugsplat-apple 2.x and bugsplat-android 1.x: one open-source SDK ([BugSplat-Git/bugsplat-native](https://github.com/BugSplat-Git/bugsplat-native), MIT) with a C API, a header-only C++ wrapper, and .NET, Swift and Kotlin bindings, built on Google's Crashpad. + +{% hint style="info" %} +**Status.** Windows is complete and verified end to end. macOS, Linux, Android and iOS/tvOS build in CI and are being brought up platform by platform; each platform page carries a status line at the top. Until your platform's page says "verified", keep using the existing integration for production and evaluate 9.0 alongside it. +{% endhint %} + +### How it works + +Every desktop platform gets the same two helper processes next to your application: + +| Component | Role | +| --- | --- | +| `BugSplatMonitor` | Watches your process from outside. When it crashes, writes the dump (normal, heap or full), computes the crash signature, copies your attachments, and hands the report to the reporter. Same name on every platform. | +| `BugSplatReporter` | The crash dialog (themeable, translatable) and the upload. Opens the support response when there is one. | +| `BugSplat.dll` / `libbugsplat.dylib` / `libbugsplat.so` | The library your app links: the C API, the report store, the uploader, structured reports, feedback, hang detection. | +| `BugSplatWer.dll` | Windows only: the Windows Error Reporting helper for fail-fast crashes. | + +Capture, dump writing, the dialog and the upload all happen **out of your process**, so a crash that corrupts the heap, exhausts the stack or takes out the C runtime is still reported. On iOS and tvOS, where the OS forbids a helper process, capture is in process and the report is sent on the next launch. + +Initialization refuses to run without the monitor and reporter (`BUGSPLAT_ERR_MONITOR_NOT_FOUND`, `BUGSPLAT_ERR_REPORTER_NOT_FOUND`): a packaging mistake shows up on the developer's machine, not as silently missing crashes in the field. + +### Ten lines + +```c +#include + +int main(void) { + bugsplat_options* o = bugsplat_options_new("fred", "MyApp", "1.0.0"); /* database, app, version */ + bugsplat_init(o); /* starts BugSplatMonitor out of process */ + bugsplat_set_user("fred@bugsplat.com"); /* every property can change at any time */ + bugsplat_set_attribute("branch", "main"); + bugsplat_add_attachment("app.log"); + volatile int* p = 0; *p = 42; /* dialog, upload, support response */ +} +``` + +C++: `bugsplat::BugSplat bs("fred", "MyApp", "1.0.0"); bs.SetUser("fred");`\ +.NET: `using var bs = new BugSplat("fred", "MyApp", "1.0.0"); bs.HandleApplicationExceptions();` + +### What every platform shares + +* **Report properties, changeable at any time**: key (selects the [support response](../../../production/setting-up-custom-support-responses.md)), user, email, description, notes, up to 64 attributes and up to 24 attachments. Whatever the values are at the instant of the crash is what the report carries. +* **Environment**: a new first-class property, detected automatically (`Windows 11 10.0.26200 x64`, `macOS 14.5 (23F79) arm64`, `Android 14 (API 34) arm64-v8a; Google Pixel 8`), overridable, shown on the crash page. It is how BugSplat tells platforms apart now that every Crashpad platform posts the same crash type. +* **Upload policies**: `DIALOG` (ask the user, then send), `QUIET` (send without UI), `MANUAL` (leave the report pending and let the app decide). +* **The presigned upload** every BugSplat platform uses, with a retry on the next launch for server errors. +* **Client-side crash signature** so repeat crashes group instantly and the support response resolves at once. +* [**Hang detection**](hang-detection.md), [**structured reports**](structured-reports.md) for engines and managed code, [**user feedback**](user-feedback.md), non-fatal captures, and heap/full memory dumps on every desktop platform. +* One [**crash-report store**](crash-data-format.md) format, so a pending report from any platform looks the same. + +### Platforms + +| Platform | Capture | Dialog | Guide | +| --- | --- | --- | --- | +| Windows (x64, x86, ARM64) | out of process; WER for fail-fast | `BugSplatReporter.exe`, Win32 | [Windows](windows.md) | +| macOS 13+ | out of process | `BugSplatReporter.app`, AppKit | [macOS](macos.md) | +| Linux (glibc 2.31+) | out of process | `BugSplatReporter`, GTK 3 or headless | [Linux](linux.md) | +| Android | out of process, at crash time | in-app prompt on next launch | [Android](android.md) | +| iOS, tvOS | in process (OS rule) | in-app prompt on next launch | [iOS and tvOS](ios.md) | +| Xbox | private bolt-on for certified developers | | [Xbox](../game-development/xbox.md) | + +### Guides + +{% content-ref url="hang-detection.md" %} +[hang-detection.md](hang-detection.md) +{% endcontent-ref %} + +{% content-ref url="structured-reports.md" %} +[structured-reports.md](structured-reports.md) +{% endcontent-ref %} + +{% content-ref url="user-feedback.md" %} +[user-feedback.md](user-feedback.md) +{% endcontent-ref %} + +{% content-ref url="crash-data-format.md" %} +[crash-data-format.md](crash-data-format.md) +{% endcontent-ref %} + +{% content-ref url="migration.md" %} +[migration.md](migration.md) +{% endcontent-ref %} + +### Reference + +The full API reference, the crash-data format, the upload protocol and the theme and strings formats live with the code: + +* [API reference](https://github.com/BugSplat-Git/bugsplat-native/blob/main/docs/API.md) +* [Crash data format](https://github.com/BugSplat-Git/bugsplat-native/blob/main/docs/CRASH-DATA-FORMAT.md) and [upload protocol](https://github.com/BugSplat-Git/bugsplat-native/blob/main/docs/UPLOAD-PROTOCOL.md) +* [Theming the dialog](https://github.com/BugSplat-Git/bugsplat-native/blob/main/reporter/docs/THEME.md) and [translating it](https://github.com/BugSplat-Git/bugsplat-native/blob/main/reporter/docs/STRINGS.md) +* [Architecture](https://github.com/BugSplat-Git/bugsplat-native/blob/main/docs/ARCHITECTURE.md) diff --git a/introduction/getting-started/integrations/native/android.md b/introduction/getting-started/integrations/native/android.md new file mode 100644 index 00000000..51ac1bc2 --- /dev/null +++ b/introduction/getting-started/integrations/native/android.md @@ -0,0 +1,56 @@ +--- +description: >- + BugSplat Native 9.0 on Android: at-crash out-of-process capture with + libBugSplatMonitor.so, an in-app prompt on next launch, ANR import, Kotlin API. +--- + +# Android + +{% hint style="warning" %} +**Status: bring-up.** The Android backend and the Kotlin binding (bugsplat-android 9.0) are being built on the shared core. For production today use [BugSplat for Android](../mobile/android.md) (bugsplat-android 1.x), which keeps working against the server until you upgrade. Everything on this page is the shipping design; API names are final at the C level and may still change in Kotlin. +{% endhint %} + +### How capture works on Android 🤖 + +Android does not allow a long-running helper process, so Crashpad's at-crash model is used: `libBugSplatMonitor.so` ships inside your APK as a native library and is executed as the monitor **at the moment of the crash**, from the crashing process, over a socket pair. It writes the dump, computes the signature and imports the report into the app's store; there is no dialog at crash time. On the next launch the SDK drains the store: with the `DIALOG` policy the app shows a Material prompt (Send / Don't Send / Always Send, name, email, description), with `QUIET` it uploads in the background, with `MANUAL` your code decides. + +Java and Kotlin exceptions are handled by an `UncaughtExceptionHandler` that posts a [structured report](structured-reports.md) with the JVM stack; native (JNI/NDK) crashes produce minidumps. ANRs are imported from `ApplicationExitInfo` on the next launch as crash type 37. + +### What ships in the APK 📦 + +* `libbugsplat.so` and `libBugSplatMonitor.so` for each ABI you ship (`arm64-v8a`, `armeabi-v7a`, `x86_64`), 16 KB page-aligned. +* The Kotlin binding `com.bugsplat:bugsplat-android:9.x` on Maven Central bundles both and the prompt UI. + +### Initialize (Kotlin, bugsplat-android 9.0) 🏗️ + +```kotlin +BugSplat.init(context, BugSplatOptions(database = "fred", application = "MyApp", version = "1.0.0") + .uploadPolicy(UploadPolicy.Dialog) + .hangDetection(timeoutMs = 5000)) +BugSplat.user = "ada@example.com" +BugSplat.setAttribute("branch", "main") +BugSplat.addAttachment(File(filesDir, "app.log")) +``` + +The C API is available to NDK code through `bugsplat/bugsplat.h` when the binding has initialized (or directly, passing the app's files directory as the store). + +### What is different on Android 📱 + +* The **environment** string includes the API level and the device: `Android 14 (API 34) arm64-v8a; Google Pixel 8`. +* **Hang detection** pings the main `Looper`; a message that is not processed within the timeout is a hang (the ANR the OS would eventually report, caught earlier and with a full dump). +* The **support response** is not opened automatically (`open_support_url` defaults to off); the prompt exposes `infoUrl` so your app can show it. +* Heap and full memory dumps are not available (`BUGSPLAT_CAP_FULL_MEMORY_DUMP` is 0). + +### Symbols 🔣 + +Native crashes are symbolicated from Breakpad `.sym` files generated from your unstripped `.so` files (Gradle keeps them under `build/intermediates/merged_native_libs` or your CMake build directory): + +```bash +symbol-upload-linux -b your-database -a MyApp -v 1.0.0 -i your-client-id -s your-client-secret -d app/build -f "**/*.so" -m +``` + +JVM stacks in structured reports need no symbols; keep mapping files if you obfuscate with R8 so BugSplat can de-obfuscate them (upload as today, see [Android](../mobile/android.md#symbol-upload)). + +### Where things are 🔍 + +Reports and `BugSplat.log`: `/bugsplat/-/` inside the app's private storage. diff --git a/introduction/getting-started/integrations/native/crash-data-format.md b/introduction/getting-started/integrations/native/crash-data-format.md new file mode 100644 index 00000000..486cfb91 --- /dev/null +++ b/introduction/getting-started/integrations/native/crash-data-format.md @@ -0,0 +1,69 @@ +--- +description: >- + Where BugSplat Native stores reports on the machine, what BugSplatCrashData.json + contains, and how pending reports, retries and preferences work. +--- + +# Crash Data Format + +BugSplat Native keeps every report as a folder on disk until it is uploaded or discarded. The folder is the contract between the library, the monitor and the reporter, and it is what you get from `bugsplat_pending_reports()`. The complete field-by-field reference is [CRASH-DATA-FORMAT.md](https://github.com/BugSplat-Git/bugsplat-native/blob/main/docs/CRASH-DATA-FORMAT.md) in the repository; this page is the tour. + +### Where the store is + +| Platform | Store directory | +| --- | --- | +| Windows | `%LOCALAPPDATA%\BugSplat\-\` | +| macOS | `~/Library/Application Support/BugSplat/-/` | +| Linux | `$XDG_STATE_HOME/bugsplat/-/` (default `~/.local/state/...`) | +| Android, iOS | the app's private files / Application Support directory, under `bugsplat/-/` | + +`bugsplat_options_set_store_dir` overrides it; `bugsplat_log_file_path()` returns the `BugSplat.log` inside it, the first file support will ask for. + +### Layout + +``` +/ + BugSplat.log the SDK's log for this app and version + preferences.json alwaysSend, persistedUser, persistedEmail (replaces the 8.x registry keys) + sessions/-.json the attachment list of a running process + / + BugSplatCrashData.json the report's metadata (schema 2) + .dmp the dump; or bsCrashReport.xml / .json, bsAsanReport.xml, feedback.json + + BugSplat.log what happened to this report + result.json written once someone tried to upload it +``` + +### `BugSplatCrashData.json` + +The report's identity (`database`, `appName`, `appVersion`, `crashTypeId`), the first-class properties (`key`, `user`, `email`, `userDescription`, `notes`, `environment`, `attributes`), what was captured (`reportKind`: `crash`, `hang`, `capture`, `structured`, `feedback`; `dumpFile`, `dumpType`: `normal`/`heap`/`full`; `dumpFormat`; `attachments`; `crashTime`; `signalOrExceptionCode`; `hangDurationMs`; `platform`, `arch`, `osVersion`), the client-side `crashSignature` and `crashSignatureHash`, and how the reporter should behave (`uploadPolicy`: `dialog`/`quiet`/`manual`, `openSupportUrl`, `themeDir`). Readers tolerate missing keys, so a report written by a newer SDK is never lost to an older reporter. + +```json +{ + "schemaVersion": 2, + "database": "fred", "appName": "MyApp", "appVersion": "1.0.0", "crashTypeId": "1", + "user": "ada@example.com", "email": "", "key": "level-3", "userDescription": "", "notes": "", + "environment": "Windows 11 10.0.26200 x64", + "attributes": { "branch": "main" }, + "reportKind": "crash", "dumpFile": "3f2c9d1e-....dmp", "dumpType": "heap", "dumpFormat": "minidump", + "attachments": ["app.log"], + "crashTime": "2026-09-11T22:10:31Z", "signalOrExceptionCode": "0xc0000005", + "crashSignature": "myapp.exe:0x1215|myapp.exe:0x14cf", + "crashSignatureHash": "1db7fa4b...", + "uploadPolicy": "dialog", "openSupportUrl": true +} +``` + +### `result.json` + +Written by whoever uploaded (the reporter, or your call to `bugsplat_send_report`): `status` (`uploaded`, `cancelled`, `failed`, `rejected`, `deferred`), `errorCode`, `httpStatus`, `crashId`, `stackKeyId`, `infoUrl`, `cancelled`. Once it exists the report is no longer pending. + +### Pending reports and retries + +A report is pending when it has metadata, no `result.json`, and no live process working on it: a crash whose upload was interrupted, a report left by the `MANUAL` policy, a machine that was offline. On the next launch the monitor and the SDK retry; `bugsplat_pending_reports()` lists them for your own UI, `bugsplat_send_report()` uploads one (optionally with a new user, email or description), `bugsplat_discard_report()` deletes one, `bugsplat_post_pending_reports_async()` drains them in the background. + +Retry policy: an upload that succeeded, a permanent refusal (size limit, rate limit, 4xx) or three failed attempts delete the folder; a server error (500, 502, 503, 504) keeps it for the next launch. + +### What is uploaded + +The dump or report file, the attachments and the report's log, zipped; the metadata travels as the fields of the commit call (`appKey`, `user`, `email`, `description`, `notes`, `attributes`, `environment`, `crashSignature`, `crashHash`). `BugSplatCrashData.json` and `result.json` never leave the machine. Protocol details: [Crash Post Endpoints](../../../development/web-services/crash.md). diff --git a/introduction/getting-started/integrations/native/hang-detection.md b/introduction/getting-started/integrations/native/hang-detection.md new file mode 100644 index 00000000..bfe5a29c --- /dev/null +++ b/introduction/getting-started/integrations/native/hang-detection.md @@ -0,0 +1,56 @@ +--- +description: >- + Detect main-thread hangs on every platform and report them as full dumps + through the same pipeline as crashes, with non-fatal and fatal policies. +--- + +# Hang Detection + +A hang is a crash the operating system never reports: the main thread stops making progress and the user eventually force-quits. BugSplat Native detects hangs the same way on every platform and reports them as an out-of-process dump of the whole process, tagged `reportKind=hang`, through the same store, dialog and upload as a crash. + +### Enable + +```c +bugsplat_options_set_hang_detection(o, 5000, BUGSPLAT_HANG_REPORT); /* timeout in ms; 0 = off */ +``` + +C++: `Options(...).HangDetection(5000)`. .NET: `Options { HangTimeoutMs = 5000 }`. + +### How progress is observed + +A watchdog thread in your process checks every quarter of the timeout (at least every 100 ms) how long ago the main thread last showed progress: + +| Platform | What counts as progress | +| --- | --- | +| Windows | one of your visible top-level windows answered a `WM_NULL` sent with `SendMessageTimeout`, so its thread is pumping messages | +| macOS, iOS, tvOS | a block queued on the main dispatch queue ran, so the run loop turned | +| Android | the main `Looper` processed the ping (bugsplat-android 9.0) | +| Linux, services, console tools, game loops | you called `bugsplat_heartbeat()` | + +Applications without a message loop or run loop, and engines that own their main loop, call `bugsplat_heartbeat()` from the loop they consider alive, at least once per timeout. Calling it when detection is off is harmless. + +### Watching more threads + +```c +/* on the render thread */ +bugsplat_watch_thread("render"); +for (;;) { render_frame(); bugsplat_heartbeat(); } +bugsplat_unwatch_thread(); +``` + +Each watched thread is judged against the same timeout, and the report names the thread that stalled (`main`, `render`, ...). + +### What a hang report looks like + +The same minidump as a crash, with every thread's stack and the hung thread frozen where it is, plus `reportKind: hang` and the hang duration. The dialog shows the "not responding" copy (`hangTitle`, `hangHeadline`, `hangBody` in `strings..json`) instead of the crash copy. Repeated hangs at the same place share a crash signature and group together, and at most one hang is reported per five minutes per process. + +### Policies + +| Policy | Behaviour | +| --- | --- | +| `BUGSPLAT_HANG_REPORT` (default) | non-fatal: report, keep running; the user may never notice | +| `BUGSPLAT_HANG_REPORT_AND_TERMINATE` | fatal: the dialog offers **Wait** and **Close**; on Close the monitor ends the application after the dump (the BugSplat for Windows 8.x behaviour). *Status: the Wait/Close step is being finished with the Windows monitor-side hang probe; until then this policy behaves like the non-fatal one and is recorded in the report.* | + +### Choosing a timeout + +Pick a value comfortably above the longest legitimate main-thread stall in your application (asset loading, large JSON parses, first-frame shader compilation): 2-5 seconds for interactive apps, 30 seconds or more for tools that block on purpose. A too-short timeout reports ordinary slowness as hangs; because reports are deduplicated and carry the duration, a false positive costs one report, not a storm. Breakpoints under a debugger look like hangs, so consider leaving detection off in debug builds. diff --git a/introduction/getting-started/integrations/native/ios.md b/introduction/getting-started/integrations/native/ios.md new file mode 100644 index 00000000..dc19a85c --- /dev/null +++ b/introduction/getting-started/integrations/native/ios.md @@ -0,0 +1,60 @@ +--- +description: >- + BugSplat Native 9.0 on iOS and tvOS: in-process Crashpad capture, reports sent + on the next launch through the same store and upload as every other platform. +--- + +# iOS and tvOS + +{% hint style="warning" %} +**Status: bring-up.** The iOS/tvOS backend and the Swift-first API (bugsplat-apple 9.0) are being built on the shared core; tvOS ships as a beta. For production today use [BugSplat for iOS](../mobile/ios.md) (bugsplat-apple 2.x). Everything on this page is the shipping design. +{% endhint %} + +### How capture works on iOS 📱 + +iOS and tvOS do not allow a helper process, so this is the one place BugSplat Native captures **in process**: Crashpad's in-process handler writes an intermediate dump at crash time, and on the next launch the SDK converts it to a minidump, imports it into the store, computes the crash signature, and either prompts (`DIALOG`: a UIKit/SwiftUI alert with Send / Don't Send / Always Send) or uploads in the background (`QUIET`). The dump, the report store, the upload and the support response are the same as on every other platform; only the capture differs. + +Exceptions caught by the Objective-C runtime (`NSException`) and Swift fatal errors are captured with their stacks; `EXC_BAD_ACCESS`, `abort`, stack overflows and signals produce minidumps. Mac Catalyst is not supported. + +### What ships in your app 📦 + +`BugSplat.xcframework` (arm64 device, arm64 and x86-64 simulator, tvOS) through Swift Package Manager or as a manual embed; nothing else. There is no monitor or reporter on iOS. + +### Initialize (Swift, bugsplat-apple 9.0) 🏗️ + +```swift +import BugSplat + +BugSplat.start(database: "fred", application: "MyApp", version: "1.0.0") { options in + options.uploadPolicy = .dialog + options.hangDetection = .init(timeout: 3.0, policy: .report) +} +BugSplat.user = "ada@example.com" +BugSplat.setAttribute("branch", "main") +BugSplat.addAttachment(logURL) +``` + +The C API is available to C and C++ code in the same app through `bugsplat/bugsplat.h`. + +### What is different on iOS 🍏 + +* **In process**: a crash inside the handler itself, or one that corrupts memory the handler needs, may not produce a report. This is the platform's constraint, not a policy choice; everywhere a helper process is allowed, BugSplat uses one. +* **Crash callback**: none on Apple platforms. +* **Hang detection** pings the main dispatch queue; `hangDetection` produces a non-fatal report with a full dump while the app keeps running. +* **Heap and full dumps** are not available; `dump_type` is ignored with a logged warning. +* The **support response** is not opened automatically; the prompt exposes `infoUrl`. +* The **environment** string names the device: `iOS 17.5 (21F79) arm64; iPhone15,3`. + +### Symbols 🔣 + +iOS and tvOS reports are processed with Breakpad `.sym` files generated from your dSYMs (`dump_syms` runs inside `symbol-upload -m`): + +```bash +symbol-upload-macos -b your-database -a MyApp -v 1.0.0 -i your-client-id -s your-client-secret -d "$DWARF_DSYM_FOLDER_PATH" -f "**/*.dSYM" -m +``` + +Keep Bitcode off so the dSYMs you build match the binary Apple distributes. + +### Where things are 🔍 + +Reports and `BugSplat.log`: `/BugSplat/-/` in the app's container. diff --git a/introduction/getting-started/integrations/native/linux.md b/introduction/getting-started/integrations/native/linux.md new file mode 100644 index 00000000..e2169944 --- /dev/null +++ b/introduction/getting-started/integrations/native/linux.md @@ -0,0 +1,75 @@ +--- +description: >- + Add BugSplat Native 9.0 to a Linux application: the monitor and reporter next + to your binary, headless uploads, .sym symbols. +--- + +# Linux + +{% hint style="warning" %} +**Status: bring-up.** The Linux build compiles and passes the unit tests in CI; the crash-through-monitor path and the GTK reporter are being verified on real distributions. For production today see the [Crashpad integration](../desktop/linux.md). Details marked *planned* are not yet in a release. +{% endhint %} + +### Requirements 📋 + +* glibc 2.31 or later (Ubuntu 20.04, Debian 11, RHEL 9 and newer), x86-64 and aarch64. +* Runtime dependencies are loaded with `dlopen` and are optional: `libcurl.so.4` for uploads (present on every desktop distribution) and GTK 3 for the dialog. Without a display or GTK the reporter uploads headlessly, as if the policy were `QUIET`. +* CMake 3.24+ and GCC 11+ or Clang 14+ to build. + +### What ships next to your binary 📦 + +| File | Purpose | +| --- | --- | +| `libbugsplat.so` | the library you link | +| `BugSplatMonitor` | out-of-process capture over a socket pair; no libcurl, no GTK | +| `BugSplatReporter` + `theme/` | the dialog (GTK 3, loaded at run time) and the upload | + +```cmake +find_package(bugsplat CONFIG REQUIRED) +target_link_libraries(my_app PRIVATE bugsplat::bugsplat) +bugsplat_install_runtime(TARGET my_app) +``` + +Tarballs per architecture are published with each release (*planned*: `bugsplat-9.x-linux-x86_64.tar.gz`, `-aarch64`). + +### Initialize 🏗️ + +```c +bugsplat_options* o = bugsplat_options_new("fred", "MyApp", "1.0.0"); +bugsplat_options_set_upload_policy(o, BUGSPLAT_UPLOAD_DIALOG); /* QUIET for servers and daemons */ +bugsplat_options_set_hang_detection(o, 5000, BUGSPLAT_HANG_REPORT); +if (bugsplat_init(o) != BUGSPLAT_OK) { /* BugSplatMonitor / BugSplatReporter not next to the binary */ } +``` + +Report properties, attachments, feedback, structured reports and pending reports work as on [Windows](windows.md). + +### What is different on Linux 🐧 + +* **Hang detection** has no built-in main-loop pinger (there is no one main loop on Linux): call `bugsplat_heartbeat()` from your main loop at least once per timeout, or leave detection off. +* **Hosts with their own signal handlers** (.NET, Mono, the JVM): `bugsplat_options_set_chain_previous_signal_handlers(o, 1)` lets the runtime's handler see the fault first, so managed null references stay managed and only real native faults produce dumps. `BugSplatDotNet` sets this for you. +* **`kill -SEGV`** and other externally delivered fatal signals are captured like any crash. +* **Support response** opens with `xdg-open` after an interactive upload; nothing opens in `QUIET` mode or without a display. +* **Heap and full dumps** are standard minidumps with memory regions appended (`lldb`, `minidump_stackwalk` read them). + +### Symbols 🔣 + +Build with `-g` and link with `-Wl,--build-id` (the build id matches the module to its symbols); `-fno-omit-frame-pointer` on x86-64 improves the client-side crash signature. Upload the unstripped binaries or `.debug` files, converted to Breakpad `.sym`: + +```bash +symbol-upload-linux -b your-database -a MyApp -v 1.0.0 -i your-client-id -s your-client-secret -d ./build -f "**/*.{so,debug}" -m +``` + +Ship stripped binaries; keep the unstripped ones for the upload. + +### Where things are 🔍 + +Reports and `BugSplat.log`: `$XDG_STATE_HOME/bugsplat/-/`, i.e. `~/.local/state/bugsplat/-/` by default. + +### Troubleshooting 🛠️ + +| Symptom | Cause | +| --- | --- | +| `BUGSPLAT_ERR_MONITOR_NOT_FOUND` | `BugSplatMonitor` is not next to the binary or `libbugsplat.so` | +| Reports stay pending, log says the upload failed at the transport level | `libcurl.so.4` is not installed, or no network; pending reports retry on the next launch | +| No dialog | no `DISPLAY`/`WAYLAND_DISPLAY`, or GTK 3 is not installed; the report was uploaded headlessly | +| Dumps but no useful stack for a .NET app | the runtime's handler and BugSplat's are competing; make sure signal-handler chaining is on | diff --git a/introduction/getting-started/integrations/native/macos.md b/introduction/getting-started/integrations/native/macos.md new file mode 100644 index 00000000..e3637c50 --- /dev/null +++ b/introduction/getting-started/integrations/native/macos.md @@ -0,0 +1,74 @@ +--- +description: >- + Add BugSplat Native 9.0 to a macOS application: the out-of-process monitor and + reporter inside your bundle, signing and notarization, .sym symbols. +--- + +# macOS + +{% hint style="warning" %} +**Status: bring-up.** The macOS build compiles and passes the unit tests in CI; the crash-through-dialog path is being verified on hardware, and the AppKit reporter is being finished. This page describes the design that ships; details marked *planned* are not yet in a release. For production today use [BugSplat for macOS](../desktop/macos.md) (bugsplat-apple 2.x), which will be replaced by bugsplat-apple 9.0 on this core. +{% endhint %} + +### Requirements 📋 + +* macOS 13 or later, Apple silicon and Intel (universal binaries). +* Xcode 16 or later to build; CMake 3.24+ for the CMake package. +* Hardened runtime and notarization for anything you distribute outside the App Store; see below. + +### What ships inside your bundle 📦 + +``` +MyApp.app/Contents/ + MacOS/MyApp + Frameworks/libbugsplat.dylib (or BugSplat.framework) + Helpers/BugSplatMonitor out-of-process capture + Helpers/BugSplatReporter.app the crash dialog and upload +``` + +`bugsplat_install_runtime(TARGET my_app)` puts the helpers in `Contents/Helpers` for a `MACOSX_BUNDLE` target (next to the executable for a command-line tool) and, when `BUGSPLAT_CODESIGN_IDENTITY` is set, signs `BugSplatMonitor` with the hardened runtime. `bugsplat_init()` also looks in `BugSplat.framework/Helpers/` so the Swift package can carry the helpers itself. + +### Initialize 🏗️ + +```c +bugsplat_options* o = bugsplat_options_new("fred", "MyApp", "1.0.0"); +bugsplat_options_set_upload_policy(o, BUGSPLAT_UPLOAD_DIALOG); +bugsplat_options_set_hang_detection(o, 3000, BUGSPLAT_HANG_REPORT); +if (bugsplat_init(o) != BUGSPLAT_OK) { /* helpers missing from the bundle */ } +``` + +The C++ wrapper and the report properties, attachments, feedback, structured reports and pending-report calls are the same as on [Windows](windows.md); the Swift-first API arrives with bugsplat-apple 9.0. + +### What is different on macOS 🍎 + +* **Crash callback**: there is no in-process crash callback on Apple platforms (`BUGSPLAT_CAP_ON_CRASH_CALLBACK` is 0). Put state into attributes ahead of time. +* **Hang detection** pings the main dispatch queue; a run loop that stops turning is a hang. Command-line tools that block on stdin should call `bugsplat_heartbeat()` or leave detection off. +* **Heap and full dumps** are standard minidumps with the process's memory regions appended, readable by `lldb` and `minidump_stackwalk`. +* **Support response** opens with `open ` after an interactive upload. +* **App Sandbox**: an out-of-process handshake inside the sandbox is being validated. If no sandbox-compatible mechanism passes App Review, sandboxed apps fall back automatically to in-process capture with the same store, reporter and upload (*planned*; see the architecture document's risk register). + +### Signing and notarization 🔏 + +Sign `BugSplatMonitor`, `BugSplatReporter.app` and `libbugsplat.dylib` with your Developer ID and the hardened runtime as part of your app's signing, then notarize the app as usual. The helpers are plain executables and need no entitlements of their own; the app needs `Outgoing network connections (client)` only when it is sandboxed. + +### Symbols 🔣 + +macOS reports are processed with Breakpad `.sym` files; dSYMs are the input. Set `DEBUG_INFORMATION_FORMAT = dwarf-with-dsym` for release builds, keep Bitcode off, and after every build: + +```bash +symbol-upload-macos -b your-database -a MyApp -v 1.0.0 -i your-client-id -s your-client-secret -d "$BUILT_PRODUCTS_DIR" -f "**/*.dSYM" -m +``` + +`-m` runs `dump_syms` and uploads the `.sym`. See [Upload Symbols with symbol-upload](../../../development/working-with-symbol-files/upload-symbols-with-symbol-upload.md). + +### Where things are 🔍 + +Reports and `BugSplat.log`: `~/Library/Application Support/BugSplat/-/`. The dialog's remembered name and email are in `preferences.json` there. + +### Troubleshooting 🛠️ + +| Symptom | Cause | +| --- | --- | +| `BUGSPLAT_ERR_MONITOR_NOT_FOUND` | `Contents/Helpers/BugSplatMonitor` is missing, or the target is not a bundle and the helper is not next to the executable | +| Gatekeeper blocks the helper | the helper was not signed with the app's identity, or the app was not notarized after the helpers were added | +| No symbols on the crash page | `.sym` files were not uploaded for this application and version (upload the dSYMs with `-m`) | diff --git a/introduction/getting-started/integrations/native/migration.md b/introduction/getting-started/integrations/native/migration.md new file mode 100644 index 00000000..ba1d2613 --- /dev/null +++ b/introduction/getting-started/integrations/native/migration.md @@ -0,0 +1,59 @@ +--- +description: >- + Moving to BugSplat Native 9.0 from BugSplat for Windows 8.x, bugsplat-apple + 2.x and bugsplat-android 1.x: same concepts, new names, no shims. +--- + +# Migrating to 9.0 + +BugSplat Native keeps the concepts you already use (database/application/version, user, email, key, description, notes, attributes, attachments, quiet mode, the dialog, the support response) and changes the names and the packaging. There is deliberately **no compatibility layer** in the client: the old headers, exports and store formats are gone, and the server keeps accepting reports from the old SDKs for as long as you need to switch. Upgrade an application in one step, on your own schedule. + +### From BugSplat for Windows 8.x (C++ and C) + +**Files.** `BugSplat.h`/`BugSplatC.h` (UTF-16) become `bugsplat/bugsplat.h` (UTF-8 C API) and `bugsplat/bugsplat.hpp` (C++ wrapper). `BugSplatRc.dll` is gone. What ships next to your executable keeps its names: `BugSplat.dll`, `BugSplatMonitor.exe`, `BugSplatWer.dll`, `BugSplatReporter.exe` (plus its `theme\`). The static `BugSplat.lib` build is gone; link the import library and ship `BugSplat.dll`, which removes the `/MT` vs `/MD` coupling. + +**Methods.** The C++ wrapper keeps the 8.x names where they made sense: + +| 8.x | 9.0 C++ (`bugsplat::BugSplat`) | 9.0 C | +| --- | --- | --- | +| `BugSplat g(db, app, ver)` | `bugsplat::BugSplat g(db, app, ver)` or `g(bugsplat::Options(db, app, ver)...)` | `bugsplat_options_new` + `bugsplat_init` | +| `SetUser` / `SetEmail` / `SetUserDescription` / `SetNotes` | same | `bugsplat_set_user` / `_email` / `_user_description` / `_notes` | +| `SetKey` (app key) | `SetKey` | `bugsplat_set_key` | +| `SetAttribute(name, value)` | `SetAttribute` / `RemoveAttribute` | `bugsplat_set_attribute(name, value \| NULL)` | +| `AddAttachment(path)` | `AddAttachment` / `RemoveAttachment` | `bugsplat_add_attachment` / `_remove_attachment` | +| `SetQuietMode(true)` | `SetQuietMode` or `Options::UploadPolicy(Quiet)` | `bugsplat_set_quiet_mode` | +| `SetMiniDumpType(MINIDUMP_TYPE)` | `Options::DumpType(Heap \| Full)` or `MinidumpFlags(...)` | `bugsplat_options_set_dump_type` / `_minidump_flags` | +| `SetHangDetectionTimeout(seconds)` | `Options::HangDetection(ms, policy)` | `bugsplat_options_set_hang_detection` | +| `CreateXmlReport(xml)` | `bugsplat::Report` builder + `Post()` | `bugsplat_report_*` + `bugsplat_report_post` | +| `CreateAsanReport(text)` | `PostAsanReport` | `bugsplat_post_asan_report` | +| `PostFeedback` / `PostFeedbackWithResult` | `PostFeedback` returning `UploadResult` | `bugsplat_post_feedback` | +| `IsWerEnabled()` | `HasCapability(BUGSPLAT_CAP_WER)` | `bugsplat_has_capability` | +| `AllocGuardMemory` | not needed (capture is out of process; nothing is allocated at crash time) | | +| global exception filter callbacks | `Options::OnCrash(fn)` (async-signal-safe, no BugSplat calls) or `CrashCompletion(ContinueSearch)` to run your own filter after the dump | `bugsplat_options_set_on_crash` / `_crash_completion` | + +**Behaviour changes.** + +* Attributes and attachments can now be changed **at any time**, not only before a crash is possible; the value at the crash instant is what is sent. +* Heap and full dumps no longer consult the server before writing (`/api/fullDumpFlag` is gone); the server enforces the upload size limit when the report is sent. +* The user's remembered name and email moved from `HKCU\Software\BugSplat\UserCredentials` to `preferences.json` in the store; the store moved to `%LOCALAPPDATA%\BugSplat\-\`. +* The dialog is themed with `theme.json` and translated with `strings..json`; resource-DLL customization is gone. +* `Environment` is new: detected automatically, shown on the crash page, overridable. +* Symbols: still PDBs, uploaded exactly as before. + +### From bugsplat-apple 2.x (macOS, iOS, tvOS) + +* PLCrashReporter is replaced by Crashpad: out of process on macOS (`BugSplatMonitor` and `BugSplatReporter.app` inside your bundle), in process on iOS/tvOS with the report sent on the next launch, as before. +* `BugSplat.shared().start()` with `Info.plist` keys becomes `BugSplat.start(database:application:version:)` with an options closure; `BugSplatDelegate` callbacks for attachments become `addAttachment` at any time; `autoSubmitCrashReport` becomes the upload policy; `askUserDetails`, `persistUserDetails` and the banner image become theme and preference settings; `postFeedback(...)` keeps its shape. +* Hang detection is the shared watchdog: non-fatal reports with a full dump while the app runs, in addition to the fatal case. +* Symbols: still dSYMs, uploaded with `symbol-upload -m` as Breakpad `.sym` (the same command as before). +* Reports post as crash type 5 with the `environment` field naming the platform; the `.crashlog` types are no longer produced. + +### From bugsplat-android 1.x + +* The Crashpad handler you built and the `crashpad.php` URL are replaced by `libBugSplatMonitor.so` and the presigned upload, with an in-app prompt, ANR import and JVM exception reports as structured reports. +* `BugSplat.init(...)` keeps its role; user, email, description, attributes and attachments become properties settable at any time; the `BugSplatBridge` JNI names are kept for NDK code. +* Symbols: unchanged (`.sym` from your unstripped `.so` files with `symbol-upload -m`). + +### What you do not have to change + +Your database, application names and versions, symbol uploads, support responses, alerts and defect-tracker integrations, attribute searches: the server sees the same reports with a few new fields (`environment`, the client-side `crashHash`). diff --git a/introduction/getting-started/integrations/native/structured-reports.md b/introduction/getting-started/integrations/native/structured-reports.md new file mode 100644 index 00000000..0bf6f043 --- /dev/null +++ b/introduction/getting-started/integrations/native/structured-reports.md @@ -0,0 +1,89 @@ +--- +description: >- + Post crashes the client already understands (script exceptions, managed + exceptions, engine asserts) as BugSplat XML reports or their JSON mirror. +--- + +# Structured Reports + +A structured report is a crash your code already understands: a script exception, an unhandled managed exception, an engine assert, an AddressSanitizer failure. Instead of a memory dump it carries the stack the runtime knows, in BugSplat's `bsCrashReport.xml` schema (crash type 21) or a JSON mirror of it, and goes through the same store and upload as everything else. `BugSplatDotNet` uses it for unhandled managed exceptions; engine and scripting integrations use it for theirs. + +### Build and post + +```c +bugsplat_report* r = bugsplat_report_new(BUGSPLAT_REPORT_XML); /* or BUGSPLAT_REPORT_JSON */ +bugsplat_report_set_platform(r, "Lua", "Windows 11 10.0.26200 x64"); /* prefilled from the environment */ +bugsplat_report_set_exception(r, "runtime error", "attempt to index a nil value"); +bugsplat_report_add_module(r, "game.dll", "C:/app/game.dll", 0x7ff600000000, 0x20000, "1.0.0.0", "1.0"); +int32_t t = bugsplat_report_add_thread(r, "main", /*is_crashing_thread=*/1); +bugsplat_report_add_frame(r, t, "Player:update", "scripts/player.lua", 42, "", 0); +bugsplat_report_add_frame(r, t, "Game:tick", "scripts/game.lua", 118, "", 0); +bugsplat_report_add_attachment(r, "C:/app/logs/game.log"); + +bugsplat_upload_result out = BUGSPLAT_UPLOAD_RESULT_INIT; +bugsplat_result rc = bugsplat_report_post(r, &out); /* blocks until uploaded, unless the policy is MANUAL */ +/* out.crash_id, out.info_url */ +bugsplat_upload_result_free(&out); +bugsplat_report_free(r); +``` + +C++: `bugsplat::Report rep; int t = rep.Thread("main", true); rep.Frame(t, "Player:update", "scripts/player.lua", 42); auto result = rep.Post();` + +The **crashing thread** is the one added with `is_crashing_thread = 1` (or the first thread). Its first frame becomes the report's function, file and line on the crash page; its frames feed the crash signature (`function|file|line` per frame, hashed), so identical stacks group instantly. + +The report's own attachments and the session's attachments (`bugsplat_add_attachment`) are both included. User, email, key, description, notes, environment and attributes come from the current values, as for a crash. + +### The XML the server receives + +```xml + + Lua + Windows 11 10.0.26200 x64 + + + runtime error + attempt to index a nil value + + scripts/player.lua + 42 + + + game.dll1
00007ff600000000-00007ff600020000
+ C:/app/game.dlldeferred + 1.0.0.01.0 + 00000000
+
+ + + scripts/player.lua42 + scripts/game.lua118 + + +
+
+``` + +The JSON form (`bsCrashReport.json`) has the same fields (`schemaVersion`, `platform`, `os`, `exception{code, explanation, registers}`, `modules[]`, `threads[{id, crashing, frames[{function, file, line, module, address}]}]`). Server-side acceptance of the JSON file under type 21 is being added; use XML until it is announced. + +### Managed exceptions in .NET + +```csharp +using var bugsplat = new BugSplat("fred", "MyApp", "1.0.0"); +bugsplat.HandleApplicationExceptions(); // AppDomain.UnhandledException, TaskScheduler.UnobservedTaskException +// or explicitly: +var result = bugsplat.Post(exception); // result.CrashId, result.InfoUrl +``` + +Each managed frame becomes a report frame with the method, file and line; inner exceptions become extra threads named `inner-0`, `inner-1`, ... Native faults in the same process are still captured as dumps by the monitor. + +### AddressSanitizer + +```c +bugsplat_post_asan_report(asan_output_text, &out); /* crash type 25 */ +``` + +Stores the sanitizer output verbatim as `bsAsanReport.xml`; the server parses it. See also [Address Sanitizer Reports](../../posting-a-test-crash/myconsolecrasher-c-plus-plus/address-sanitizer-reports.md). + +### Policies + +`DIALOG` and `QUIET` both upload a structured report immediately, without a dialog (the report was produced by code, not by a crash the user saw). `MANUAL` leaves it pending for `bugsplat_send_report` / `bugsplat_post_pending_reports_async`. diff --git a/introduction/getting-started/integrations/native/user-feedback.md b/introduction/getting-started/integrations/native/user-feedback.md new file mode 100644 index 00000000..0bcce1b3 --- /dev/null +++ b/introduction/getting-started/integrations/native/user-feedback.md @@ -0,0 +1,44 @@ +--- +description: >- + Let users send bug reports and feature requests from inside your app with + BugSplat Native 9.0; they appear next to crashes, grouped by title. +--- + +# User Feedback + +Feedback is a report a user chose to send: a bug they noticed, a feature they want, a screenshot of something that looks wrong. BugSplat Native posts it through the same store and upload as a crash, as crash type 36 (`User.Feedback`), and it appears in the BugSplat app with the platform "User Feedback", grouped by title. The wire format is the one in [User Feedback (web services)](../../../development/web-services/user-feedback.md). + +### Post feedback + +```c +const char* files[] = { "C:/app/screenshot.png" }; +bugsplat_upload_result r = BUGSPLAT_UPLOAD_RESULT_INIT; +bugsplat_result rc = bugsplat_post_feedback("Login button does nothing", + "Tapping Login on the welcome screen has no effect.", + files, 1, &r); +if (rc == BUGSPLAT_OK) { /* r.crash_id; r.info_url is the support response, if any */ } +bugsplat_upload_result_free(&r); +``` + +C++: + +```cpp +auto result = bugsplat.PostFeedback("Login button does nothing", "Tapping Login has no effect.", {"C:/app/screenshot.png"}); +``` + +.NET: + +```csharp +var result = bugsplat.PostFeedback("Login button does nothing", "Tapping Login has no effect.", new[] { screenshotPath }); +``` + +* **title** becomes the crash group (stack key); **description** becomes the exception message. +* Attachments are the files you pass; the session's crash attachments are not added automatically. +* User, email, key, environment and attributes come from the current values, so set them before posting if the form collected a name or email. +* With the `MANUAL` policy the report is left pending (result OK, crash id 0) for a later `bugsplat_send_report`. + +### Building the form + +The SDK has no feedback dialog of its own: your settings or help screen already has the right place for a form. Collect a title, a description, optionally name and email, and call `bugsplat_post_feedback` from a background thread (it blocks for the upload). Show `info_url` when it is returned; it is the [support response](../../../production/setting-up-custom-support-responses.md) configured for the key, so it can thank the user or point them at a workaround. + +See also [Send Feedback](../../../../education/how-tos/sending-feedback.md) for how feedback looks in the app. diff --git a/introduction/getting-started/integrations/native/windows.md b/introduction/getting-started/integrations/native/windows.md new file mode 100644 index 00000000..83e6f7b6 --- /dev/null +++ b/introduction/getting-started/integrations/native/windows.md @@ -0,0 +1,160 @@ +--- +description: >- + Add BugSplat Native 9.0 to a Windows application: ship the runtime, initialize, + describe the report, capture hangs and feedback, register WER, upload symbols. +--- + +# Windows + +{% hint style="success" %} +**Status: verified.** Windows is the reference platform for 9.0: access violations, stack overflows, C++ exceptions, `abort`, heap corruption, fail-fast through WER, heap dumps, hangs, structured reports and feedback have all been driven through the monitor and reporter against a live database. +{% endhint %} + +### Requirements 📋 + +* Windows 10 or later, x64, x86 or ARM64. +* The Visual C++ 2015-2022 runtime on the end user's machine (`vcruntime140.dll`, `msvcp140.dll`, `vcruntime140_1.dll` on x64). Chain the matching `vc_redist` into your installer or ship the DLLs next to the BugSplat files. +* Build tools: CMake 3.24+ and Visual Studio 2022 or 2026 for the CMake package; any compiler for the C API through `BugSplat.dll`. + +### What ships next to your executable 📦 + +| File | Purpose | +| --- | --- | +| `BugSplat.dll` | the library you link (import library `BugSplat.lib`) | +| `BugSplatMonitor.exe` | out-of-process capture, dump writing, crash signature, import into the store | +| `BugSplatReporter.exe` + `theme\` | the crash dialog, upload, support response; `theme.json` and `strings..json` | +| `BugSplatWer.dll` | Windows Error Reporting helper (fail-fast, `/GS`, .NET runtime fail-fast) | + +With CMake this is one line: + +```cmake +find_package(bugsplat CONFIG REQUIRED) +target_link_libraries(my_app PRIVATE bugsplat::bugsplat) +bugsplat_install_runtime(TARGET my_app) # copies the four files and theme\ next to my_app.exe +``` + +Without CMake, copy them from the release zip; `bugsplat_init()` looks next to your executable and next to `BugSplat.dll`, or wherever `bugsplat_options_set_monitor_path` / `set_reporter_path` point. + +### Initialize 🏗️ + +```c +#include + +bugsplat_options* o = bugsplat_options_new("fred", "MyApp", "1.0.0"); +bugsplat_options_set_upload_policy(o, BUGSPLAT_UPLOAD_DIALOG); /* or QUIET, MANUAL */ +bugsplat_options_set_dump_type(o, BUGSPLAT_DUMP_NORMAL); /* HEAP or FULL for more memory */ +bugsplat_options_set_hang_detection(o, 5000, BUGSPLAT_HANG_REPORT); /* optional */ +if (bugsplat_init(o) != BUGSPLAT_OK) { + /* a packaging problem: BugSplatMonitor.exe or BugSplatReporter.exe is missing; + details in bugsplat_log_file_path() */ +} +``` + +The same in C++ (`bugsplat.hpp`): + +```cpp +#include + +bugsplat::BugSplat g_bugsplat(bugsplat::Options("fred", "MyApp", "1.0.0") + .UploadPolicy(bugsplat::UploadPolicy::Dialog) + .HangDetection(5000)); +``` + +And in .NET (`BugSplatDotNet` on NuGet; the package lays the runtime out per runtime identifier): + +```csharp +using var bugsplat = new BugSplat("fred", "MyApp", "1.0.0"); +bugsplat.HandleApplicationExceptions(); // managed exceptions become structured reports +``` + +Use the same application name and version you upload symbols under. `bugsplat_init` may be called once per process; it takes ownership of the options. + +### Describe the report ✏️ + +Everything below can be called at any time after `bugsplat_init`, from any thread, and the value at the instant of the crash is what the report carries: + +```c +bugsplat_set_user("ada@example.com"); +bugsplat_set_email("ada@example.com"); +bugsplat_set_key("level-3"); /* selects the support response */ +bugsplat_set_user_description("what the user was doing"); +bugsplat_set_attribute("branch", "main"); /* up to 64; NULL value removes */ +bugsplat_add_attachment("C:\\ProgramData\\MyApp\\app.log"); /* up to 24; copied at crash time */ +printf("%s\n", bugsplat_get_environment()); /* "Windows 11 10.0.26200 x64"; override with bugsplat_set_environment */ +``` + +Attributes appear on the crash page and in searches ([Using the Crash Attribute Feature](../../../../education/how-tos/using-the-crash-attribute-feature.md)); attachments are downloadable from the crash page. + +### Reports that are not crashes 📝 + +```c +bugsplat_capture_report(); /* dump the live process, keep running */ + +bugsplat_upload_result r = BUGSPLAT_UPLOAD_RESULT_INIT; +bugsplat_post_feedback("Title", "What the user typed", NULL, 0, &r); /* r.crash_id, r.info_url */ +bugsplat_upload_result_free(&r); +``` + +See [User Feedback](user-feedback.md) and [Structured Reports](structured-reports.md) (engines, scripting runtimes, managed exceptions, ASan output). + +### Hang detection ⏱️ + +With a timeout set, the SDK pings your application's top-level windows every quarter of the timeout; an unanswered window is a hang, reported as a full dump with `reportKind=hang` and the "not responding" dialog. Console tools, services and game loops call `bugsplat_heartbeat()` instead. Details, policies and extra threads: [Hang Detection](hang-detection.md). + +### Fail-fast crashes and WER 🪟 + +Some crashes never reach an in-process handler: `__fastfail`, `/GS` stack-buffer overruns, `RaiseFailFastException`, and the .NET runtime's own fail-fast after an unhandled managed exception. Windows Error Reporting handles those, and only calls a helper whose full path is allow-listed under `HKLM`. Your installer (running elevated) adds it once: + +``` +reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModules" /v "C:\Program Files\MyApp\BugSplatWer.dll" /t REG_DWORD /d 0 +``` + +`bugsplat_has_capability(BUGSPLAT_CAP_WER)` answers 1 when the registration is in place. WinUI 3 applications need this for every crash, not just fail-fast. + +### Heap and full memory dumps 🧠 + +```c +bugsplat_options_set_dump_type(o, BUGSPLAT_DUMP_HEAP); /* private writable memory: CLR/GC/native heaps */ +bugsplat_options_set_dump_type(o, BUGSPLAT_DUMP_FULL); /* every readable region */ +bugsplat_options_set_minidump_flags(o, MiniDumpWithFullMemory | MiniDumpWithHandleData); /* raw MINIDUMP_TYPE */ +``` + +The dump is written by DbgHelp while your process is suspended, so Visual Studio, WinDbg and BugSplat's .NET analysis see exactly what they see today. There is no client-side size gate: the server enforces your database's upload limit (100 MB by default; larger limits on Enterprise plans) when the reporter asks for the upload URL, and a refused report is logged as `rejected`. `BugSplatDotNet` defaults to `Heap` on Windows so managed frames resolve. + +### Symbols 🔣 + +Windows reports are processed with your PDBs. Build release configurations with `/Zi` and `/DEBUG`, then upload after every build: + +```batch +symbol-upload-windows.exe -b your-database -a MyApp -v 1.0.0 -i your-client-id -s your-client-secret -d "$(OutDir)" -f "**/*.{pdb,exe,dll}" +``` + +or, in CMake, `bugsplat_upload_symbols(TARGET my_app DATABASE your-database APPLICATION MyApp VERSION 1.0.0)` with `BUGSPLAT_CLIENT_ID`/`BUGSPLAT_CLIENT_SECRET` in the environment. See [Upload Symbols with symbol-upload](../../../development/working-with-symbol-files/upload-symbols-with-symbol-upload.md). + +### Branding the dialog 🎨 + +`theme\theme.json` next to `BugSplatReporter.exe` controls colours, logo, layout and features such as "Always send"; `theme\strings..json` holds every string, per language. Preview without crashing anything: + +``` +BugSplatReporter.exe --preview --theme "C:\work\my-theme" +``` + +Reference: [THEME.md](https://github.com/BugSplat-Git/bugsplat-native/blob/main/reporter/docs/THEME.md) and [STRINGS.md](https://github.com/BugSplat-Git/bugsplat-native/blob/main/reporter/docs/STRINGS.md). + +### Where things are 🔍 + +* Reports and the log: `%LOCALAPPDATA%\BugSplat\-\`. `BugSplat.log` there is the first place to look; each report folder has its own log too. +* Pending reports (the `MANUAL` policy, or a machine that was offline) are retried on the next launch, up to three attempts for server errors. +* The user's name and email are remembered in `preferences.json` in that folder, not in the registry. + +### Troubleshooting 🛠️ + +| Symptom | Cause | +| --- | --- | +| `bugsplat_init` returns `BUGSPLAT_ERR_MONITOR_NOT_FOUND` / `_REPORTER_NOT_FOUND` | the helper executables are not next to your exe or `BugSplat.dll`; run `bugsplat_install_runtime` or fix the installer | +| Crash dialog appears, then "MSVCP140.dll was not found" | the Visual C++ runtime is missing on the machine | +| Fail-fast crashes (`0xC0000409`) are not reported | `BugSplatWer.dll` is not allow-listed under `HKLM`; `bugsplat_has_capability(BUGSPLAT_CAP_WER)` is 0 | +| No dialog when crashing from a CI or agent shell | the shell runs children in a Job Object that kills them on an unhandled exception; launch the crasher outside it (for example through WMI `Win32_Process.Create`) | +| Report uploaded but shows no symbols | upload PDBs under the same application name and version; see [Why are Crashes Missing Symbols](../../../../education/faq/why-are-crashes-missing-symbols-function-names-and-or-line-numbers.md) | + +Upgrading from BugSplat for Windows 8.x? See [Migrating to 9.0](migration.md).