> This is part 1 of 3 of the full documentation (pages 1–100 of 226).
> The content is paginated: fetch every part to see all of it.
> Next part: https://docs.bugsplat.com/llms-full.txt/1
> Page index: https://docs.bugsplat.com/llms.txt

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
This site has an agentic ask interface you may use to query the documentation dynamically by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.bugsplat.com/index.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

---

# Welcome

BugSplat is the developer's toolbox for finding, understanding, and fixing crashes. Start here to integrate crash reporting and see your first report in minutes.

When your application crashes in the field, BugSplat captures what you need to understand it: a symbolicated call stack, the runtime environment, and the custom attributes you attach, all presented in a familiar debugger view. You can triage a production crash as if it happened on your own machine, ship more stable software, and spend less time supporting it.

## 🚀 Start here

The fastest way to see BugSplat in action is to post a **sample crash**, no code required. It takes about five minutes.

{% content-ref url="/pages/0DGT78982RCgYcQQhoeL" %}
[Post Your First Crash in Five Minutes](/getting-started/quickly-submitting-your-first-crash-in-under-5-minutes)
{% endcontent-ref %}

Ready to wire up your own application? The **Full Setup Guide** walks you through it: sign up, create a database, integrate your platform, and verify your first real crash.

{% content-ref url="/pages/-Mg6V7Zai2FmOmqKtaa6" %}
[Full Setup Guide](/getting-started/getting-started)
{% endcontent-ref %}

## 💻 Integrate your platform

Pick your platform and follow its SDK guide. (Each guide assumes you've already [created a database](/getting-started/create-a-new-database-in-bugsplat), which takes about 30 seconds.)

{% content-ref url="/pages/-Mea-SlchKzvwrdVln6G" %}
[Desktop Software](/integrations/desktop)
{% endcontent-ref %}

{% content-ref url="/pages/-Mea-X1-H07xFKLyAN\_c" %}
[Game Development](/integrations/game-development)
{% endcontent-ref %}

{% content-ref url="/pages/-Mea-d-9QYPHoBmcZa9d" %}
[Mobile Apps](/integrations/mobile)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg28TSi1S9pMZcEkQEl" %}
[Web](/integrations/web)
{% endcontent-ref %}

## 🛠️ Fix a problem

Crashes not showing up, or arriving without symbols? Start with Troubleshooting.

{% content-ref url="/pages/-MiM8ZpQHQssItl-R4eW" %}
[Troubleshooting](/getting-started/troubleshooting)
{% endcontent-ref %}

* [My crash isn't showing up](/getting-started/troubleshooting#missing-crashes)
* [My crashes are missing symbols, function names, or line numbers](/getting-started/troubleshooting#missing-symbols)

## 🔌 API Reference

Automate BugSplat and pull your crash data programmatically.

{% content-ref url="/pages/-MeaxO\_O0epKcEbLw-E9" %}
[Using the API](/api-reference/web-services)
{% endcontent-ref %}

## 📖 Using the app

Once crashes are flowing, learn to triage them, group them, and route them to your team.

{% content-ref url="/pages/-MekgqzpG96G7o6jtqAp" %}
[Using the App](/guides/using-the-app)
{% endcontent-ref %}

{% content-ref url="/pages/-Mea2Z4cJcljg-U7hRLA" %}
[Alerts & Issue Trackers](/guides/integrating-with-tools)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg6XZ9eAhoKpSXw8iFu" %}
[Production](/guides/production)
{% endcontent-ref %}

## 🍎 Learn the concepts

New to crash reporting, or want a reference for the terms and workflows?

{% content-ref url="/pages/-MeampuRcf0d\_ugjyR-K" %}
[BugSplat Terminology](/education/bugsplat-terminology)
{% endcontent-ref %}

{% content-ref url="/pages/-Me\_x5ZmA2mxm4xS-P7F" %}
[How-Tos](/education/how-tos)
{% endcontent-ref %}

{% content-ref url="/pages/-Me\_sxW8GdjzQIgt1tdD" %}
[FAQs](/education/faq)
{% endcontent-ref %}

## 🏢 Admin & billing

{% content-ref url="/pages/wUHupuY5KeyodORrPBdO" %}
[Billing](/administration/billing)
{% endcontent-ref %}

{% content-ref url="/pages/-Me\_tm\_Z4hNrESPVWxG5" %}
[Account](/administration/account-managment)
{% endcontent-ref %}

## 🐛 About BugSplat

{% content-ref url="/pages/-MftJzU3yBbTu147AxXX" %}
[What is BugSplat?](/about/what-is-bugsplat)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg6eBQZ8JZZbsC0RJZF" %}
[Who is BugSplat?](/about/who-is-bugsplat)
{% endcontent-ref %}

***

Stuck or have a question? Email <support@bugsplat.com>, use the in-app chat, or ping us on [Discord](https://discord.gg/K4KjjRV5ve). You can also search these docs from the bar in the top right.


# Full Setup Guide

Getting up and running with BugSplat is a well-documented, straightforward process that thousands of developers have followed. There are two ways to start:

* **Just want to see it work?** [Post a sample crash in about 5 minutes](/getting-started/quickly-submitting-your-first-crash-in-under-5-minutes), no code required.
* **Ready to integrate your own app?** Follow the six steps below. It takes about as long as it does to drink a [large mug](https://shop.spacex.com/collections/accessories/products/occupy-mars-heat-sensitive-terraforming-mug-new) of coffee.

{% embed url="<https://bugsplat.wistia.com/medias/qp13mure3h>" %}

## ✍️ The BugSplat 6-Step Checklist

1. [Sign up for a BugSplat account](/getting-started/signing-up-for-an-account-with-bugsplat)
2. [Create a database](/getting-started/create-a-new-database-in-bugsplat)
3. [Add your team and tools](/getting-started/adding-uses-to-your-account)
4. [Integrate your platform](/integrations/integrations)
5. [Submit your first report](/getting-started/posting-a-test-crash)
6. [Learn to use the app](/guides/development)

## 🖇️ More Details

Following the above steps takes new users from [creating an account](/getting-started/signing-up-for-an-account-with-bugsplat) and [database](/getting-started/create-a-new-database-in-bugsplat), through [adding your team and tools](/getting-started/adding-uses-to-your-account), to [integrating your application](/integrations/integrations) and [posting your first report](/getting-started/posting-a-test-crash). Crash reporting is more fun with friends, so bring your team along early. It mirrors the in-app Onboarding Tool.

Once these steps are complete, users should learn more about using the BugSplat app in the [Development](/guides/development) section which has a handy [walkthrough of the BugSplat application](/guides/using-the-app), 3rd party integration guides, and much more.

If at any point you get stuck and want some help, please reach out to us via our [Discord](https://discord.gg/K4KjjRV5ve) or by sending us an [email](mailto:support@bugsplat.com).

{% hint style="success" %}
🧙‍♂️ **Attention new accounts**: You will also have the opportunity to follow these steps via the Onboarding Tool that's visible to new users right after they [create an account](/getting-started/signing-up-for-an-account-with-bugsplat).
{% endhint %}


# Post Your First Crash in Five Minutes

{% hint style="success" %}
This is the **fast lane**: you'll post a *sample* crash using the in-app Onboarding Tool, without writing any code, just to see BugSplat in action. When you're ready to send crashes from your own application, follow the full [Getting Started](/getting-started/getting-started) guide.
{% endhint %}

Submitting a sample crash to your new BugSplat account is a quick and straightforward process that can be completed in under 5 minutes. Follow the steps below to get started easily:

1. [Sign up ](https://app.bugsplat.com/v2/sign-up)for a new account
2. Use the Onboarding Tool to create a new database
3. Add tools and team members
4. Select your first platform or SDK from our list of 25+ SDKs
5. Select the "Post sample crash" button to skip the full integration process for now and post a sample crash
6. Explore your new BugSplat account and see the data you can get from a crashed app

### Step 1: Sign Up for a New Account

First, sign up for a free BugSplat account at <https://app.bugsplat.com/v2/sign-up>. Fill in the required information, including your email address and a secure password. Once you've successfully signed up, you'll be ready to proceed to the next step.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-199f2f66969d0293fd4f4c9c811ccadd123c1d7e%2Fpost_sample_crash-1.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

### Step 2: Use the Onboarding Tool to Create a New Database

After signing up, you'll be directed to the BugSplat Onboarding Tool. This tool is designed to make the setup process as seamless as possible. Follow the prompts to create a new database for your application, ensuring you have all the necessary information to set up crash reporting effectively.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-9ce158ebe59b960a2b5fdae56aff812c42eb17d0%2Fpost_sample_crash-2.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

### Step 3: Add Tools and Team Members

Before selecting a platform or SDK, use the Onboarding Tool to add your development tools and team members.

### Step 4: Select Your First Platform or SDK

BugSplat supports [a wide range of platforms and SDKs](/integrations/integrations), providing comprehensive crash reporting capabilities. Choose your platform or SDK from our extensive list of over 25 options. Select the one that matches your application's development environment.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-a9fdaa72076b560e763f10156579abbbe1e41a9e%2Fpost_sample_crash-3.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

### Step 5: Submitting a Sample Crash

Once you've selected your platform or SDK, you'll be taken to our documentation page. To quickly submit a sample crash without going through the full integration process, click the "**Post sample crash**" button in the sidebar status card. This allows you to skip the full integration process for now and submit a sample crash directly.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-0046e7fc489194e3ec07dc7ff7a5a842bf3eccdb%2Fpost_sample_crash-4.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

### Step 6: Explore Your New BugSplat Account

Congratulations! You've successfully submitted a sample crash to your new BugSplat account. Take a moment to explore your BugSplat account and discover the valuable data you can obtain from a crashed application. This data will empower you to identify and resolve issues in your software more efficiently, saving you time and energy in the long run.

Remember, if you want to navigate back to the Onboarding Tool and complete the full integration process with BugSplat, you can do so at any time by clicking this link --> <https://app.bugsplat.com/v2/welcome>

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-5a9e2de0a6b42bc5313e389168963337decc32f4%2Fpost_sample_crash-5.png?alt=media" alt="" width="563"><figcaption></figcaption></figure>

### Additional Resources

If you want to learn more about integrating your application fully with BugSplat, we recommend visiting our SDK integration documentation on our [Platforms and SDK's page](/integrations/integrations). These resources provide in-depth guides and step-by-step instructions to help you seamlessly integrate BugSplat into your development workflow.

If you ever hit a bump - please reach out to our responsive support team at <support@bugsplat.com>


# Signing Up

To register an account with BugSplat, visit the [Sign Up](https://app.bugsplat.com/v2/sign-up) page and enter your first name, last name, company email (or another email you wish to be associated with your account), and a password. Passwords must be 14-64 characters and include an uppercase letter, a lowercase letter, a number, and a symbol. You'll be asked to re-enter your password to confirm it.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-Mhsry3Daa46xoUCh1bT%2F-Mhss5Lqm82wNBZg9qqU%2FScreen%20Shot%202021-08-24%20at%209.55.33%20AM.png?alt=media\&token=4c8fd5bc-217d-41a4-805b-60213e6e7e79)

Once you've hit **Sign Up** you'll be a registered user of BugSplat.

Then, you'll be presented with a screen welcoming you to BugSplat. Here you can either use the Onboarding Tool, which helps you quickly configure new accounts, or skip it and go directly to the [Dashboard](/guides/using-the-app#dashboard) page.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-Mea2IX8w97RbwZ_HsgS%2F-Meal8PFMv8OTXR_O0aa%2Fwelcome-to-bugsplat.png?alt=media\&token=7923e17d-fbb9-44e6-ab83-0529c4ba9d60)

{% hint style="info" %}
🤝 **Looking to get access to an existing team?** You can request access from a team member using this form [here](https://app.bugsplat.com/v2/sign-up/team-access). Learn more about requesting access [here](/administration/user-management/requesting-access-to-your-teams-accounts).
{% endhint %}


# Creating a Database

In BugSplat, a database is the top-level container for crashes and can be considered a standalone workspace for your application. Generally, a database holds all crashes and errors from a single application or logical group of applications, such as a client and server. To learn more about the hierarchy of BugSplat information, please view this [document](/guides/using-the-app#navigating-with-breadcrumbs).

To start using BugSplat, you'll need to create a database. You can create a database through one of two methods: via the [Onboarding Tool](https://app.bugsplat.com/v2/welcome) or the [Databases page](https://app.bugsplat.com/v2/database/general).

### Create a Database via the Onboarding Tool 🧑‍🏫

For new BugSplat users, creating a new database can be accomplished via the Onboarding Tool. After creating a new account, users will be prompted to create a database. You can return to it any time by navigating to the [Onboarding Tool](https://app.bugsplat.com/v2/welcome).

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2F2Im29pFgd1z0U0xBO2eR%2Fonboarding-create-database.png?alt=media&amp;token=eed40d8d-8602-4b99-8ea6-c5d1bf9e0f59" alt=""><figcaption><p>Create a Database via the Onboarding Tool</p></figcaption></figure>

### Create a Database via the Database Page ⚙️

Alternatively, a database can be created on the [Databases](https://app.bugsplat.com/v2/database/general) page. At the top of the page, enter your new database's name under the **New Database** section and click **Create**. The Database's page is helpful when setting up multiple databases under an account.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FhptpR4Qphn3ENO2Tmx7d%2Fcreate-database.gif?alt=media&amp;token=ab2b86ea-8551-4054-b14e-981d4fbc2a96" alt=""><figcaption><p>Create a Database via the Databases Page</p></figcaption></figure>

### Naming your Database 🪪

Pick something descriptive and easy to remember when choosing a database name. Please note that spaces, periods, and symbols other than `-` are prohibited. Some examples of database names are: `DeliciousDonutsApp` or `Super-Strong-Coffee-App`.


# Platform Samples

Sample applications to produce a test crash for testing BugSplat implementations.

Questions? Please get in touch with us via [Discord](https://discord.gg/K4KjjRV5ve) or at <support@bugsplat.com>.

### 💻 Desktop Software

| Platform                       | Sample                                                                                             |
| ------------------------------ | -------------------------------------------------------------------------------------------------- |
| Windows (C++)                  | [my-console-crasher](/getting-started/posting-a-test-crash/myconsolecrasher-c-plus-plus)           |
| .NET Framework                 | [MyDotNetFrameworkWpfCrasher](/getting-started/posting-a-test-crash/mydotnetframeworkwpfcrasher)   |
| .NET Framework (hosted by C++) | [MyDotNetFrameworkHostCrasher](/getting-started/posting-a-test-crash/mydotnetframeworkhostcrasher) |
| .NET                           | [MyDotNetCrasher](/getting-started/posting-a-test-crash/mydotnetcrasher)                           |
| .NET (WinUI 3)                 | [MyDotNetWinUI3Crasher](/getting-started/posting-a-test-crash/mydotnetwinui3crasher)               |
| macOS                          | [BugSplatTester](https://github.com/BugSplat-Git/bugsplat-apple/tree/main/Example_Apps)            |
| Electron                       | [my-electron-crasher](https://github.com/BugSplat-Git/my-electron-crasher)                         |
| Qt                             | [my-qt-crasher](https://github.com/BugSplat-Git/my-qt-crasher)                                     |
| Java                           | [my-java-crasher](https://github.com/BugSplat-Git/bugsplat-java/tree/main/my-java-crasher)         |
| Python                         | [my-python-crasher](https://github.com/BugSplat-Git/my-python-crasher)                             |
| CMake                          | [bugsplat-crashpad](https://github.com/BugSplat-Git/bugsplat-crashpad)                             |

### 🎮 Game Development

| Platform | Sample                                                                 |
| -------- | ---------------------------------------------------------------------- |
| Unreal   | [my-unreal-crasher](https://github.com/BugSplat-Git/my-unreal-crasher) |
| Unity    | [my-unity-crasher](https://github.com/BugSplat-Git/my-unity-crasher)   |

### 📱 Mobile Apps

| Platform | Sample                                                                                  |
| -------- | --------------------------------------------------------------------------------------- |
| Android  | [my-android-crasher](https://github.com/BugSplat-Git/my-android-crasher)                |
| iOS      | [BugSplatTester](https://github.com/BugSplat-Git/bugsplat-apple/tree/main/Example_Apps) |

### 🕸️ Web

| Platform | Sample                                                             |
| -------- | ------------------------------------------------------------------ |
| Angular  | [my-angular-crasher](https://github.com/BugSplat-Git/bugsplat-ng)  |
| React    | [bugsplat-react](https://github.com/BugSplat-Git/bugsplat-react)   |
| Node.js  | [my-node-crasher](https://github.com/BugSplat-Git/my-node-crasher) |


# MyConsoleCrasher (C++)

Testing Windows Native C++ crashes with the sample application 'MyConsoleCrasher'

Before you enable BugSplat in your Windows C++ application, you may want to take a moment to experiment with our `MyConsoleCrasher` sample application.

To get started, download the BugSplat SDK for Windows by clicking [here](https://app.bugsplat.com/browse/download_item.php?item=native). Download and unzip the contents of `BugSplat.zip`. After extracting the downloaded SDK, open the `MyConsoleCrasher.sln` file with Visual Studio.

1. Open `MyConsoleCrasher.sln` with Visual Studio 2022+
2. Define values for `BUGSPLAT_DATABASE`, `APPLICATION_NAME`, and `APPLICATION_VERSION` in `Samples\MyConsoleCrasher\MyConsoleCrasher.h`
3. Create a Client ID and Client Secret pair for your BugSplat database on the [Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page
4. Create a file `Samples\MyConsoleCrasher\Scripts\env.ps1` and populate it with the following (being sure to substitute your `your-client-id` and `your-client-secret` values from the previous step):

```powershell
$BUGSPLAT_CLIENT_ID = "your-client-id"
$BUGSPLAT_CLIENT_SECRET = "your-client-secret"
```

5. Set the command-line arguments for the project to `/MemoryException`, or one of the other supported arguments from the sample's source code, to test various crashes. To set the command-line arguments, right-click the `MyConsoleCrasher` project and select **Properties > Debugging > Command Arguments**.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2F8gwidwEUy5MBM0IIf0eF%2Fimage.png?alt=media&amp;token=0729700f-8d71-4861-ad7d-ad1158991ffc" alt=""><figcaption></figcaption></figure>

6. Rebuild the project and run it outside of the Visual Studio debugger (Ctrl+F5). This is important since the debugger interferes with the BugSplat library’s exception handling. You should see a dialog such as that shown below:

![BugSplat Crash Dialog](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-6fe17e3405665d40734fb68db535b203168313dd%2Fwindows-crash-dialog-light.png?alt=media)

7. Enter some descriptive text to help you identify the crash you are about to upload. Click the `Send report` button, and voilà! The report will be sent! In the BugSplat web app, look for the crash report with the description you entered.
8. Navigate to the BugSplat [Dashboard](https://app.bugsplat.com/v2/dashboard) and click the link in the ID column to view details about your crash, including the full symbolicated stack trace and various crash metadata.

Finally, experiment with other features of the library by examining the `MyConsoleCrasher` source code and supplying different command-line arguments.

#### Additional Info

{% content-ref url="/pages/-MgDD2HBaxz6ZRHcUPQ8" %}
[Address Sanitizer Reports](/getting-started/posting-a-test-crash/myconsolecrasher-c-plus-plus/address-sanitizer-reports)
{% endcontent-ref %}


# Address Sanitizer Reports

BugSplat integrates with the Windows Address Sanitizer (Asan) complier option allowing you to capture memory error reports and send them to your BugSplat database. Here are some instructions for modifying myConsoleCrasher (or your application) so that it captures Address Sanitizer exceptions.

## Modify Visual Studio Compiler Options

Enable the Address Sanitizer by choosing the Enable Address Sanitizer (/fsanitize=address) C/C++ General option:

![Visual Studio Enable Address Sanitizer](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-MgDDjgONbKzjJbQilpe%2F-MgDI0B7Ol5GznfWeRa6%2FScreen%20Shot%202021-08-03%20at%205.14.10%20PM.png?alt=media\&token=6b548018-6a33-4770-8364-39d627546d53)

Modify the Visual Studio Include Directories so that the Address Sanitizer header files can be located:

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-MgDDjgONbKzjJbQilpe%2F-MgDKvHRDfEl9SEHMn5Q%2FScreen%20Shot%202021-08-03%20at%205.27.05%20PM.png?alt=media\&token=33b17319-c811-4105-801d-c8e0dc9e240f)

## Modify Initialization Code

To hook into the Address Sanitizer you will call **\_\_asan\_set\_error\_report\_callback** with the BugSplat **CreateAsanReport** method. To do this, we'll need a global instance of the BugSplat object and a new asanCallback function. See below for how you would modify our myConsoleCrasher sample program:

```cpp
...
#include "sanitizer/asan_interface.h"
...

// Global BugSplat initialization. 
BugSplat g_BugSplat(L"YourDatabase", L"YourAppName", L"YourAppVersion");

void asanCallback(const char* message)
{
   g_BugSplat.CreateAsanReport(message);
}

int wmain(int argc, wchar_t** argv)
{
	if (IsDebuggerPresent())
	{
		exit(0);
	}

	__asan_set_error_report_callback(asanCallback);
	
	...
}
```

## Create Memory Corruption Test

The only step left is to generate a memory corruption that Address Sanitizer will catch. Here's one way to do that:

```
void HeapCorruption() {
	void* pointerArray[20];
	struct simple_struct {
		double b;
		double c;
		char d;
	};

	{
		auto a = new simple_struct;
		auto b = new simple_struct;

		pointerArray[0] = a;
		pointerArray[1] = b;
	}

	// Function attempts to use pointer from array.
	// Encounters an error and deletes the pointer without removing it from array
	{
		auto item = reinterpret_cast<simple_struct*>(pointerArray[1]);
		delete item;
	}

	// Program continues, address is reused
	constexpr auto numInts = 40;
	auto intArray = reinterpret_cast<int*>(pointerArray[1]);
	for (int i = 0; i < numInts; i++) {
		intArray[i] = 10;
	}

	// Function called again, encounters the same error and tries to delete the same memory again
	{
		auto item = reinterpret_cast<simple_struct*>(pointerArray[1]);

		__try {
			delete item;
		}
		__except (EXCEPTION_EXECUTE_HANDLER) {
			wprintf(L"exception handling test successful.\n");

		}		
	}
```

Calling HeapCorruption (or your own memory error code) will generate the Address Sanitizer report and send a crash report to BugSplat.

## Crash Report Result

You'll see the crash report show up just like other crash exceptions. Here's what our modified version of the myConsoleCrasher sample program produced:

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-MgG4mw0mDxdNu4a5RjG%2F-MgG6iGah6a52I3V6tug%2FScreen%20Shot%202021-08-04%20at%206.23.13%20AM.png?alt=media\&token=a39ffd55-b616-449f-9c07-7dbbeada1360)


# MyDotNetFrameworkWpfCrasher (.NET Framework)

Testing .NET Framework crashes, hangs, and handled exceptions with the sample WPF application 'MyDotNetFrameworkWpfCrasher'

Before you enable BugSplat in your .NET Framework application, you may want to take a moment to experiment with our `MyDotNetFrameworkWpfCrasher` sample, a WPF (.NET Framework 4.7.2) app with a button for each kind of report [BugSplat for .NET](/integrations/desktop/bugsplat-for-dot-net) sends.

To get started, clone [my-dotnet-crasher](https://github.com/BugSplat-Git/my-dotnet-crasher), where the sample installs BugSplat from the [`BugSplat`](https://www.nuget.org/packages/BugSplat) NuGet package. You can also [download the BugSplat SDK for .NET](https://app.bugsplat.com/browse/download_item.php?item=dotnet) and unzip it.

1. Open `MyDotNetFrameworkWpfCrasher.sln` with Visual Studio 2022+.
2. Set your database in `Samples\MyDotNetFrameworkWpfCrasher\App.xaml.cs` (`App.Database`), and optionally `App.AppName` and `App.Version`.
3. Create a Client ID and Client Secret pair for your BugSplat database on the [Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page.
4. Create a file `Samples\MyDotNetFrameworkWpfCrasher\Scripts\env.ps1` and populate it with the following (being sure to substitute your `your-client-id` and `your-client-secret` values from the previous step):

```powershell
$BUGSPLAT_CLIENT_ID = "your-client-id"
$BUGSPLAT_CLIENT_SECRET = "your-client-secret"
```

5. Build the solution for **x64**. A post-build step uploads the sample's executable, DLLs, and `.pdb` files to BugSplat, so its crashes show file names and line numbers. The solution also builds `MyDotNetCrasherNative`, the small C++ library the Mixed-Mode and Heap Corruption buttons call into.
6. Run the sample outside of the Visual Studio debugger (Ctrl+F5). This is important since the debugger interferes with BugSplat's exception handling.
7. Click a button:

| Button               | What it does                                                                                                                                                                                    |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Crash**            | Throws an unhandled exception on the UI thread. BugSplat captures a minidump and shows its crash dialog.                                                                                        |
| **Non-Crash Error**  | Catches an exception and reports it with `BugSplat.Post`. The app keeps running.                                                                                                                |
| **User Feedback**    | Sends a note with `BugSplat.PostFeedback` and shows the resulting report id.                                                                                                                    |
| **Hang**             | Freezes the UI thread until BugSplat's hang detection reports the hang (within about 10 seconds) and ends the app.                                                                              |
| **Mixed-Mode Crash** | Calls into C++ code that crashes, so the report has one call stack that crosses from C# into C++.                                                                                               |
| **Heap Corruption**  | Calls into C++ code that frees the same memory twice. Windows fail-fasts the app through Windows Error Reporting, so this button is disabled until `BugSplatWer.dll` is registered (see below). |

8. When the crash dialog appears, enter some descriptive text to help you identify the crash and click **Send report**.
9. Navigate to the BugSplat [Dashboard](https://app.bugsplat.com/v2/dashboard) and click the link in the ID column to view details about your crash, including the full symbolicated call stack and various crash metadata.

### Heap Corruption and Windows Error Reporting

Heap corruption bypasses the application's exception handlers, so BugSplat captures it through its Windows Error Reporting helper, `BugSplatWer.dll`, which Windows loads only when its path is in the registry. From an elevated prompt, register the copy next to the sample's executable, then restart the sample:

```
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModules" /v "<path to the sample's bin folder>\BugSplatWer.dll" /t REG_DWORD /d 0 /f
```

Until the entry exists, the Heap Corruption button is dimmed, and hovering over it explains why.

Finally, explore how each button is implemented in the sample's source code, and see [BugSplat for .NET](/integrations/desktop/bugsplat-for-dot-net) to integrate BugSplat into your own application.


# MyDotNetFrameworkHostCrasher (C++ hosting .NET Framework)

Testing crashes in .NET Framework code hosted by a native C++ application with the sample 'MyDotNetFrameworkHostCrasher'

`MyDotNetFrameworkHostCrasher` is for applications that are native C++ programs which load the .NET Framework and call into C# code. The sample's C++ program initializes the [BugSplat native SDK](/integrations/desktop/cplusplus), starts the .NET Framework 4.7.2 runtime, and calls into a C# library that crashes. The report's call stack shows the C# frames on top of the C++ program's own frames.

To get started, download the BugSplat SDK for .NET by clicking [here](https://app.bugsplat.com/browse/download_item.php?item=dotnet), then unzip it.

1. Open `MyDotNetFrameworkHostCrasher.sln` with Visual Studio 2022+.
2. Define a value for `BUGSPLAT_DATABASE` in `Samples\MyDotNetFrameworkHostCrasher\MyDotNetFrameworkHostCrasher.h`.
3. Create a Client ID and Client Secret pair for your BugSplat database on the [Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page.
4. Create a file `Samples\MyDotNetFrameworkHostCrasher\Scripts\env.ps1` and populate it with the following (being sure to substitute your `your-client-id` and `your-client-secret` values from the previous step):

```powershell
$BUGSPLAT_CLIENT_ID = "your-client-id"
$BUGSPLAT_CLIENT_SECRET = "your-client-secret"
```

5. Build the solution for **x64**. It builds the C# library (`MyDotNetFrameworkHostCrasherManaged`) and the C++ program, and a post-build step uploads their executables, DLLs, and `.pdb` files to BugSplat.
6. Run the program from a command prompt with one of the crash options below, outside of the Visual Studio debugger, for example:

```
MyDotNetFrameworkHostCrasher.exe /DeepThrow
```

| Option             | What happens in the C# code                                                       |
| ------------------ | --------------------------------------------------------------------------------- |
| `/Throw`           | Throws an unhandled exception.                                                    |
| `/DeepThrow`       | Throws an unhandled exception four methods deep.                                  |
| `/Thread`          | Throws an unhandled exception on a worker thread.                                 |
| `/AccessViolation` | Writes to an invalid address.                                                     |
| `/NativeCallback`  | Calls back into a C++ function in the host program that crashes (C++ → C# → C++). |
| `/NoCrash`         | Returns to the C++ program without crashing.                                      |

Add `/Quiet` to skip the crash dialog. Run the program with no arguments to see every option.

7. When the crash dialog appears, click **Send report**, then open the crash from the BugSplat [Dashboard](https://app.bugsplat.com/v2/dashboard) to see the combined C# and C++ call stack with file names and line numbers.

### How It Works

BugSplat is initialized in the C++ program, before the .NET Framework runtime starts, so its exception handling is in place when the C# code runs. The program calls `SetCrashType(8)`, which tells BugSplat to resolve the managed (C#) frames in its minidumps. To report crashes from your own C++ application that hosts .NET, follow [BugSplat for Windows (C++)](/integrations/desktop/cplusplus) and add that same call. If your application is a managed .NET Framework or .NET 10 program instead, use [BugSplat for .NET](/integrations/desktop/bugsplat-for-dot-net).

A stack overflow in the C# code isn't reported: the .NET Framework ends the process without running any exception handlers, and reports it only through its own Windows Error Reporting event.


# MyDotNetCrasher (.NET)

Testing .NET crashes, handled exceptions, and mixed C#/C++ crashes with the sample console application 'MyDotNetCrasher'

Before you enable BugSplat in your .NET application, you may want to take a moment to experiment with our `MyDotNetCrasher` sample, a .NET 10 console app that triggers each kind of crash [BugSplat for .NET](/integrations/desktop/bugsplat-for-dot-net) reports, chosen from the command line. Its mixed-mode crashes call into a small C++ library, `MyDotNetCrasherNative`, so you can see BugSplat report one call stack that crosses from C# into C++.

To get started, clone [my-dotnet-crasher](https://github.com/BugSplat-Git/my-dotnet-crasher), where the sample installs BugSplat from the [`BugSplat`](https://www.nuget.org/packages/BugSplat) NuGet package. You can also [download the BugSplat SDK for .NET](https://app.bugsplat.com/browse/download_item.php?item=dotnet) and unzip it. You'll need the [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) and Visual Studio with the C++ desktop workload, which builds `MyDotNetCrasherNative`; the SDK download's copy also needs the `v143` build tools.

1. Open `MyDotNetCrasher.sln` with Visual Studio.
2. Set your database at the top of `Samples\MyDotNetCrasher\Program.cs`, and optionally the application name and version. Keep the line's shape: the symbol upload script reads the three values from it.

   ```csharp
   var bugsplat = new BugSplatDotNet.BugSplat("your-database", "MyDotNetCrasher", "1.0.0")
   {
       User = "sample-user",
       Email = "sample-user@example.com",
       Description = $"MyDotNetCrasher {mode} crash",
   };
   ```
3. Create a Client ID and Client Secret pair for your BugSplat database on the [Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page.
4. Create a file `Samples\MyDotNetCrasher\Scripts\env.ps1` and populate it with the following (being sure to substitute your `your-client-id` and `your-client-secret` values from the previous step), or set the `BUGSPLAT_CLIENT_ID` and `BUGSPLAT_CLIENT_SECRET` environment variables instead:

```powershell
$BUGSPLAT_CLIENT_ID = "your-client-id"
$BUGSPLAT_CLIENT_SECRET = "your-client-secret"
```

5. Build the solution (`Debug`, `x64`). It builds `MyDotNetCrasherNative` first, then the console app, which copies the BugSplat runtime and `MyDotNetCrasherNative.dll` next to its executable. A post-build step uploads the sample's executable, DLLs, and `.pdb` files (managed and native) to BugSplat with `Scripts\SymbolUpload.ps1`, so its crashes show file names and line numbers. If the upload fails, so does the build; to build without uploading, pass `/p:BugSplatSymbolUpload=false`.
6. From `Samples\MyDotNetCrasher`, run the sample with a crash mode:

```
dotnet run -- managed
```

The sample sets `QuietMode`, so it uploads each report without showing the crash dialog. Run it from a terminal rather than under the Visual Studio debugger, which intercepts the exceptions BugSplat would report.

7. Navigate to the BugSplat [Dashboard](https://app.bugsplat.com/v2/dashboard) and click the link in the ID column to view details about your crash, including the full symbolicated call stack and various crash metadata.

### Crash Modes

Every crash runs a few frames deep, through `SampleStackFrame0`, `SampleStackFrame1`, and `SampleStackFrame2`, and then happens in a method named after it, such as `ThrowUnhandledManagedException` or `CrashNativeAccessViolation`, so each report shows a real call stack whose top frame says what happened.

| Mode                                 | What it does                                                                                                                                       |
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `managed`                            | Throws an unhandled C# exception from `ThrowUnhandledManagedException`. BugSplat captures a minidump.                                              |
| `handled`                            | Catches an exception and reports it with `BugSplat.Post` from inside the `catch`. The app keeps running.                                           |
| `native`                             | Writes to an invalid address from C# (`CrashAccessViolation`), an access violation the runtime never turns into a managed exception.               |
| `feedback`                           | Sends a note with `BugSplat.PostFeedback` and prints the resulting report id and link.                                                             |
| `deep`, `generic`, `lambda`, `async` | Crash several managed frames deep, in a generic method, in a LINQ lambda, and in an `async` method, to show how BugSplat names each kind of frame. |

#### Mixed C#/C++ crashes

These call into `MyDotNetCrasherNative.dll`, so the report has one call stack with both C# and C++ frames:

| Mode                   | What it does                                                                                                                                                                |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `native-av`            | C# calls C++ code that causes an access violation (`CrashNativeAccessViolation`).                                                                                           |
| `native-deep`          | The access violation happens several C++ frames below the C# caller (`CrashNativeDeep`).                                                                                    |
| `native-callback`      | C# calls C++, which calls back into C# code that throws (`CrashNativeCallback`).                                                                                            |
| `cpp-throw`            | C++ code throws an exception nothing catches (`CrashCppThrow`).                                                                                                             |
| `native-so`            | C# and C++ call each other until the stack overflows (`CrashNativeStackOverflow`).                                                                                          |
| `native-thread`        | A C++ background thread with no C# frames crashes (`CrashNativeThread`).                                                                                                    |
| `native-fastfail`      | C++ code calls `__fastfail` (`CrashNativeFastFail`). Requires Windows Error Reporting; see below.                                                                           |
| `native-overrun`       | C++ code overruns a stack buffer and fails its `/GS` check (`CrashNativeStackOverrun`). Requires Windows Error Reporting.                                                   |
| `native-double-delete` | C++ code frees the same memory twice (`CrashNativeDoubleDelete`). Requires Windows Error Reporting, and a `Release` build: in `Debug` the debug C runtime reports it first. |

### Fail-Fast Crashes and Windows Error Reporting

The `native-fastfail`, `native-overrun`, and `native-double-delete` modes fail-fast the process straight through Windows Error Reporting, bypassing the application's exception handlers, so BugSplat captures them through its Windows Error Reporting helper, `BugSplatWer.dll`, which Windows loads only when its path is in the registry. On .NET, the runtime can also end some access violations and stack overflows with a fail-fast, which only this helper captures. From an elevated prompt, register the copy next to the sample's executable:

```
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModules" /v "<path to the sample's bin folder>\BugSplatWer.dll" /t REG_DWORD /d 0 /f
```

The other modes are captured by BugSplat's application exception handler. Your own application should always register `BugSplatWer.dll`, because crashes like these can only be captured through it.

Finally, explore how each mode is implemented in the sample's `Program.cs`, and see [BugSplat for .NET](/integrations/desktop/bugsplat-for-dot-net) to integrate BugSplat into your own application.


# MyDotNetWinUI3Crasher (.NET)

Testing .NET crashes, hangs, handled exceptions, and user feedback with the sample WinUI 3 application 'MyDotNetWinUI3Crasher'

Before you enable BugSplat in your .NET application, you may want to take a moment to experiment with our `MyDotNetWinUI3Crasher` sample, a WinUI 3 (.NET 10) app with a button for each kind of report [BugSplat for .NET](/integrations/desktop/bugsplat-for-dot-net) sends. It's the windowed companion of the [MyDotNetCrasher](/getting-started/posting-a-test-crash/mydotnetcrasher) console sample, and the .NET counterpart of the .NET Framework [MyDotNetFrameworkWpfCrasher](/getting-started/posting-a-test-crash/mydotnetframeworkwpfcrasher).

To get started, clone [my-dotnet-crasher](https://github.com/BugSplat-Git/my-dotnet-crasher), where the sample installs BugSplat from the [`BugSplat`](https://www.nuget.org/packages/BugSplat) NuGet package. You can also [download the BugSplat SDK for .NET](https://app.bugsplat.com/browse/download_item.php?item=dotnet) and unzip it. You'll need the [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0) and Visual Studio with the WinUI application development workload, plus the C++ desktop workload for the Mixed-Mode Crash button's `MyDotNetCrasherNative` library; the SDK download's copy also needs the `v143` build tools.

1. Open `MyDotNetWinUI3Crasher.sln` with Visual Studio.
2. Set your database in `Samples\MyDotNetWinUI3Crasher\App.xaml.cs` (`App.Database`), and optionally `App.Application` and `App.Version`.
3. Create a Client ID and Client Secret pair for your BugSplat database on the [Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page.
4. Create a file `Samples\MyDotNetWinUI3Crasher\Scripts\env.ps1` and populate it with the following (being sure to substitute your `your-client-id` and `your-client-secret` values from the previous step), or set the `BUGSPLAT_CLIENT_ID` and `BUGSPLAT_CLIENT_SECRET` environment variables instead:

```powershell
$BUGSPLAT_CLIENT_ID = "your-client-id"
$BUGSPLAT_CLIENT_SECRET = "your-client-secret"
```

5. Build the solution for **x64**. It builds `MyDotNetCrasherNative` first, then the app. A post-build step uploads the sample's executable, DLLs, and `.pdb` files to BugSplat with `Scripts\SymbolUpload.ps1`, so its crashes show file names and line numbers. If the upload fails, so does the build; to build without uploading, pass `/p:BugSplatSymbolUpload=false`. The app is unpackaged and self-contained, so it runs without an MSIX package, a certificate, or a separate Windows App SDK runtime install.
6. Register `BugSplatWer.dll` with Windows Error Reporting (see below). A WinUI 3 app's crashes are reported only through it, so until it's registered the app warns you at startup.
7. Run the sample outside of the Visual Studio debugger (Ctrl+F5, or `dotnet run -c Debug -p:Platform=x64` from `Samples\MyDotNetWinUI3Crasher`). This is important since the debugger interferes with BugSplat's exception handling.
8. Click a button:

| Button               | What it does                                                                                                                                |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **Crash**            | Throws an unhandled exception on the UI thread. WinUI fail-fasts the app, and BugSplat captures a minidump through Windows Error Reporting. |
| **Non-Crash Error**  | Catches an exception and reports it with `BugSplat.Post` from inside the `catch`. The app keeps running.                                    |
| **User Feedback**    | Sends a note with `BugSplat.PostFeedback` and shows the resulting report id and a link to it.                                               |
| **Hang**             | Freezes the UI thread until BugSplat's hang detection reports the hang (within about 10 seconds) and ends the app.                          |
| **Mixed-Mode Crash** | Calls into C++ code that crashes, so the report has one call stack that crosses from C# into C++.                                           |

9. Navigate to the BugSplat [Dashboard](https://app.bugsplat.com/v2/dashboard) and click the link in the ID column to view details about your crash, including the full symbolicated call stack and various crash metadata.

### Windows Error Reporting

WinUI turns an unhandled exception into a fail-fast that bypasses the application's exception handlers, so BugSplat captures a WinUI 3 app's crashes through its Windows Error Reporting helper, `BugSplatWer.dll`, which Windows loads only when its path is in the registry. From an elevated prompt, register the copy next to the sample's executable, then restart the sample:

```
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModules" /v "<path to the sample's bin folder>\BugSplatWer.dll" /t REG_DWORD /d 0 /f
```

The app checks `BugSplat.IsWerEnabled` at startup and shows a warning until the entry exists.

### Shipping as MSIX

To package the app instead, remove `<WindowsPackageType>None</WindowsPackageType>` and `<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>` from the project file and add a Windows Application Packaging Project. The project declares the BugSplat runtime files as `Content` items, so they're included in the package unchanged; `BugSplatMonitor.exe` is packaged as a plain file, not listed as an `<Executable>` in the manifest.

Finally, explore how each button is implemented in the sample's source code (`MainWindow.xaml.cs` and `Crashers.cs`), and see [BugSplat for .NET](/integrations/desktop/bugsplat-for-dot-net) to integrate BugSplat into your own application.


# Inviting Team Members

After signing up for a BugSplat account, it’s important to add your team members to your company so that they can access the team's crash data. Crash reporting is better with friends.

## Add Team Members to all Company Databases 🏀

To add a team member to all your company's databases, simply add them via the [Company](https://app.bugsplat.com/v2/company) page. They will receive an email providing a prompt about setting up their account.

## Adding Team Members to Specific Databases ⚽

Only need to add a team member to a specific subset of databases? Select the desired database, then navigate to its [Users](https://app.bugsplat.com/v2/database/users) page in Settings.

![Adding Team Members](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2Fsync%2F2738367f8d40b6dc8f6b29229c2d4b8012286c66.png?generation=1631200982718582\&alt=media)

Once you've navigated to the Users page for the right database, click the `Add Users` button. This will prompt you to insert an email address of your team member. Once invited, they will receive an email allowing them to set up their account.

Repeat this process for all desired databases.

## Requesting Access to Team Databases 🗣️

If your team or company already has an account with BugSplat, you can request access from your team member.

BugSplat has a tool that allows you to [Request Access](https://app.bugsplat.com/v2/sign-up/team-access/) to join an account from a team member who already has access to your team's account.

Note that, for security reasons, there will be no warning if the email you send to a team member isn't received. If you do not receive an email granting you access that you double-check to make sure you submitted the right email and try again.

{% hint style="info" %}
**Managing User Permissions**: Looking for a doc about limiting a team member's permissions inside of a BugSplat account? Click [here](/administration/user-management/user-permissions).
{% endhint %}


# Importing Crashes

If you are trying out BugSplat and would like to migrate crashes from your old solution you can do so by using the handy [Import](https://app.bugsplat.com/v2/import) page.

You will need to make sure you've uploaded the corresponding symbols on the [Versions](https://app.bugsplat.com/v2/versions?database=Fred) page.

![Upload Minidump Files to BugSplat](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-25e6fa3bc666d9dbbf6d6f1b4117e7c9a1ab6ec9%2Fimage.png?alt=media)


# Troubleshooting

BugSplat helps troubleshoot crash reporting issues, including why crashes are rejected, such as exceeding size limits or frequent submissions.

We try our best to make it easy to integrate with BugSplat. However, sometimes problems do arise, and not everything goes as planned. The following is a self-service troubleshooting guide that can help you fix common problems that occur when integrating with BugSplat.

## Missing Crashes

There are a few reasons why crashes might not make it to BugSplat. Below you will find some common reasons why crashes might be missing from BugSplat.

### The crashing program is running inside a debugger

Running your application inside of a debugger will block BugSplat's ability to intercept and upload the crash report. When testing your BugSplat integration ensure the debugger is not attached so that the crash report can be caught and uploaded by BugSplat.

### Your corporate internet has prevented BugSplat from upload

Corporate firewalls or network policies can prevent connections to BugSplat. Please ensure that the machine uploading the crash report can connect to BugSplat via https. BugSplat crash reports are uploaded to the domain .bugsplat.com where is replaced with the name of your BugSplat database.

### The crash being uploaded is too large

By default BugSplat accounts are limited to posting crash uploads that are no larger than 100MB (compressed), with an additional 10MB allowance for .NET applications. Abnormally large minidump, log files, and/or other attachments can cause crash uploads to be larger than your account's crash upload size limit. You can view BugSplat's [Errors](https://app.bugsplat.com/v2/errors) page to see if crash reports are being rejected due to size limit restrictions.

### Crashes are being posted too frequently

Occasionally BugSplat will reject crashes that are being posted in rapid succession. This is done to prevent BugSplat from being overrun as well as to allow customers to protect themselves from exceeding their subscription allotments. BugSplat may reject crash reports when they are incoming at a rate greater than 1,000,000 per month. Additionally, BugSplat can reject repeated crashes coming from the same IP address via a setting on the ‘[Settings](https://app.bugsplat.com/v2/database)’ page. A list of rejected crashes can be found on BugSplat's [Errors](https://app.bugsplat.com/v2/errors) page.

### BugSplat has been configured incorrectly

Many of our sample programs are configured to post crashes to the Fred database in BugSplat. If you are using one of our samples to test BugSplat, ensure that the database you used to configure the BugSplat SDK matches the value of the database you're viewing in the BugSplat web application. Additionally, if your application name or version is missing or cannot be decoded crash reports will be rejected by BugSplat.

## Incorrect Call Stacks

In order to get call stacks that match the function names, file names, and line numbers in your application's source code, many of our integrations require uploading debug symbols. More information about symbol files can be found [here](/guides/working-with-symbol-files).

### Missing Symbols

You may see a red warning on certain crashes that indicate a crash is missing symbols. C++, .NET, Crashpad, macOS, iOS, and some JavaScript crashes might display this warning. For more information about uploading symbols please see the documentation that corresponds to your application's [platform](/integrations/integrations).

**Code Signing**

Code signing will change the timestamp of the executable being signed. If you are signing your executable be sure to upload the signed version of the executable to BugSplat so that our backend can load the correct executable in order to calculate the call stack.

### Anti-Cheat and Copy Protection

Applications that are protected by anti-cheat or copy protection software sometimes require additional software to be run on the BugSplat backend. BugSplat supports VMProtect by using their MiniDumpFixer tool. However, this support must be configured by our team on the backend. Please contact <support@bugsplat.com> to set up the configuration for your database, or to request support for other anti-cheat or copy protection solutions.

### Deleted Symbols

BugSplat may automatically delete your symbols under certain circumstances. If your database has less than 5 GB of data, you won't be affected. Larger stores that have new symbol files uploaded, but not referenced by a crash within the first 15 days, will be deleted. Additionally, symbol stores for versions that haven't had a crash posted within the configured expiry period (default 90 days) will be deleted. You can configure the symbol expiry period on the [Symbols](https://app.bugsplat.com/v2/database/symbols) settings page. For more information regarding symbol cleanup please see this [doc](/guides/working-with-symbol-files/managing-symbol-storage).

## Symbol Size Limit Exceeded

Older versions of symbol-upload and SendPdbs upload symbols to a location with size limits and will throw errors when these limits are exceeded. For Windows and Crashpad symbols, newer versions of symbol-upload and SendPdbs do not have this restriction and an update that lifts the restriction for macOS symbols is coming soon.

{% hint style="info" %}
Newer versions of symbol-upload and SendPdbs can be found on our [Downloads](/integrations/downloads#symbols) page.
{% endhint %}

### Max File Size Limit Exceeded

By default, BugSplat will reject a request to upload any symbol file larger than 25 GB. This is a soft limit that our support team can raise. If you need to support an application with a symbol file greater than 25 GB please contact <support@bugsplat.com>.

**Table Max Size Limit Exceeded**

By default, BugSplat will reject a request to upload symbols to a symbol store that will cause it to exceed a size of 100 GB. We reject symbol stores over 100 GB to encourage users to upload each build to a new symbol store (instead of uploading all builds to the same symbol store). You can create as many symbol stores as you like.


# Choose Your Platform

BugSplat works in a wide range of environments and languages to give developers the best possible data on their application defects, no matter where they are occurring.

![Click below to go to platform specific docs](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-MicsKQFxNn1Vaob_uhb%2F-MicsPkujMxoTXMTzkg4%2FScreen%20Shot%202021-09-02%20at%205.38.59%20PM.png?alt=media\&token=21185a1c-3005-4724-b41c-4b65221872b6)

**Use the links below** for guides that will help you configure your application to send crash or error data to BugSplat across various languages and platforms.

{% hint style="info" %}
**Before you integrate:** [create a database](/getting-started/create-a-new-database-in-bugsplat) first, which is where your application posts its crashes.
{% endhint %}

If you are creating a new account, you'll have an option to access these documents through the Onboarding Tool, which assists in the configuration and setup of new accounts.

### Integrations

{% content-ref url="/pages/-Mea-SlchKzvwrdVln6G" %}
[Desktop Software](/integrations/desktop)
{% endcontent-ref %}

{% content-ref url="/pages/-Mea-X1-H07xFKLyAN\_c" %}
[Game Development](/integrations/game-development)
{% endcontent-ref %}

{% content-ref url="/pages/-Mea-d-9QYPHoBmcZa9d" %}
[Mobile Apps](/integrations/mobile)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg28TSi1S9pMZcEkQEl" %}
[Web](/integrations/web)
{% endcontent-ref %}

{% hint style="info" %}
**Not finding what you're looking for?** Please reach out to <support@bugsplat.com> to request the language or environment you'd like BugSplat to integrate with next!
{% endhint %}


# Desktop Software

BugSplat provides best-in-class support for desktop software: native Windows [C++](/integrations/desktop/cplusplus) and [.NET and .NET Framework](/integrations/desktop/bugsplat-for-dot-net) applications, [macOS](/integrations/desktop/macos) 11.5+ (including ARM Macs), and [Linux](/integrations/desktop/linux). It also covers cross-platform desktop frameworks and languages ([Electron](/integrations/desktop/electron), [Qt](/integrations/desktop/qt), [Java](/integrations/desktop/java), and [Python](/integrations/desktop/python)), plus the native [Crashpad](/integrations/desktop/crashpad) and [Breakpad](/integrations/desktop/breakpad) crash handlers. Take a look at the guides below to configure crash reporting in your app.

{% content-ref url="/pages/-LBNuL8eAtOKiWftzlY9" %}
[BugSplat for Windows (C++)](/integrations/desktop/cplusplus)
{% endcontent-ref %}

{% content-ref url="/pages/CMJweZYIfC1zhKJhC59m" %}
[BugSplat for .NET](/integrations/desktop/bugsplat-for-dot-net)
{% endcontent-ref %}

{% content-ref url="/pages/-MiRaZicbGk3N6gqitF2" %}
[macOS](/integrations/desktop/macos)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRWg8mVkYp1Z8J-AlE" %}
[Linux](/integrations/desktop/linux)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRTrBwNQFMT8JiWLql" %}
[Electron](/integrations/desktop/electron)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRZkA9XeOADgRRkzTC" %}
[Qt](/integrations/desktop/qt)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRW8tCuCIx0tsM0JNb" %}
[Java](/integrations/desktop/java)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRYWi5Zv1Un8TrD6Bl" %}
[Python](/integrations/desktop/python)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRJ2AOhWS2pZwCu3lW" %}
[Crashpad](/integrations/desktop/crashpad)
{% endcontent-ref %}

{% content-ref url="/pages/-MeQyyTehdBanl7X5nGC" %}
[Breakpad (Deprecated)](/integrations/desktop/breakpad)
{% endcontent-ref %}

{% hint style="info" %}
**Not finding what you're looking for?** Please reach out to <support@bugsplat.com> to request the language or environment you'd like BugSplat to integrate with next!
{% endhint %}


# BugSplat for Windows (C++)

{% hint style="info" %}
Need help upgrading from an older version of BugSplat? Check out our [upgrade guide](/integrations/desktop/cplusplus/bugsplat-for-windows-upgrade-guide) to get started.
{% 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.

### Getting Started 🚦

To begin, [download](https://app.bugsplat.com/browse/download_item.php?item=native) and unzip the BugSplat SDK for Microsoft Visual C++.

The SDK is organized per platform (`win32`, `x64`, `ARM64`) and configuration (`Release`, `Debug`):

| Folder                                 | Contents                                                                                                                                                                       |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `BugSplat\inc`                         | `BugSplat.h` (C++ API) and `BugSplatC.h` (C API)                                                                                                                               |
| `BugSplat\<platform>\<config>\bin`     | Runtime files that ship next to your executable: `BugSplat.dll`, `BugSplatMonitor.exe`, `BugSplatReporter.exe`, and `BugSplatWer.dll`, plus an optional `BugSplatTheme` folder |
| `BugSplat\<platform>\<config>\lib\md`  | Static `BugSplat.lib` built with `/MD` (dynamic CRT)                                                                                                                           |
| `BugSplat\<platform>\<config>\lib\mt`  | Static `BugSplat.lib` built with `/MT` (static CRT)                                                                                                                            |
| `BugSplat\<platform>\<config>\lib\dll` | Import library for `BugSplat.dll`                                                                                                                                              |

Link exactly one `BugSplat.lib` from the `lib` subfolder that matches your link model and runtime library setting, and ship the contents of `bin` with your application (`BugSplat.dll` is only needed if you link the import library).

The `BugSplatTheme` folder holds `theme.json` and `strings.en-US.json`, which `BugSplatReporter.exe` reads at runtime to decide how the crash dialog looks and what it says. It is optional — the reporter has a built-in copy of both — but ship it if you want to rebrand or reword the dialog. See [Crash Dialog Branding](/education/how-tos/customize-the-crash-dialog).

{% hint style="info" %}
Curious how these four files fit together, or debugging a report that arrived without a dialog? See [How the Windows Crash Reporter Works](/integrations/desktop/cplusplus/how-the-windows-crash-reporter-works).
{% endhint %}

To get a feel for the BugSplat service before enabling your application, feel free to experiment with the [MyConsoleCrasher sample application](/getting-started/posting-a-test-crash/myconsolecrasher-c-plus-plus), which is included as part of the software development kit and is also available on [GitHub](https://github.com/BugSplat-Git/Samples/tree/main/Samples/MyConsoleCrasher). For a native desktop application example, see the [MyCrasher sample](https://github.com/BugSplat-Git/Samples/tree/main/Samples/MyCrasher), an ATL/MFC Windows app.

### Integration 🏗️

{% hint style="warning" %}
For WinUI 3 applications, BugSplat must be registered as a WER [RuntimeExceptionModule](https://learn.microsoft.com/en-us/windows/win32/api/werapi/nf-werapi-werregisterruntimeexceptionmodule). This process is demonstrated in the MyWinUI3Crasher sample, which is available in the SDK and on [GitHub](https://github.com/BugSplat-Git/Samples/tree/main/Samples/MyWinUI3Crasher).
{% endhint %}

Add BugSplat to your application using the following steps:

1. Link with **`BugSplat.lib`** by adding an entry to `Linker > Input > Additional Dependencies`, and add the matching folder to `Linker > General > Additional Library Directories`: `lib\md` if your application builds with `/MD` (the Visual Studio default), or `lib\mt` if it builds with `/MT`.
2. Add **`BugSplatMonitor.exe`**, **`BugSplatReporter.exe`**, and **`BugSplatWer.dll`** (from the SDK's `bin` folder) to your application's installer, along with the `BugSplatTheme` folder if you're customizing the dialog.
3. Ensure your installer runs with Administrator privileges and creates a `RuntimeExceptionHelperModules` registry key with a name containing the full path to `BugSplatWer.dll`. For more information about configuring WER see this [doc](/integrations/desktop/cplusplus/bugsplat-for-windows-upgrade-guide#registry-changes).

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fbm5uN5lXZE20hVDwRQWe%2Fimage.png?alt=media&amp;token=61352b83-8f47-43d2-9495-7e0352173fa6" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
BugSplat's runtime files (`BugSplatMonitor.exe`, `BugSplatReporter.exe`, `BugSplatWer.dll`, and `BugSplat.dll` if you use the dynamic library) depend on the **Visual C++ 2015–2022 runtime**: `MSVCP140.dll`, `VCRUNTIME140.dll`, and `VCRUNTIME140_1.dll` on x64. These DLLs are **not part of Windows** and are missing on machines where no application has installed the redistributable. If they're absent, your application will run normally but crash reporting will fail. End users may see a "MSVCP140.dll was not found" error at crash time.

This applies even if your own application doesn't need the Visual C++ runtime (for example, if it's built with `/MT`). Make sure your installer either:

* chains the [Visual C++ Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist) installer that **matches the architecture of the BugSplat files you ship** (`vc_redist.x64.exe`, `vc_redist.x86.exe`, or `vc_redist.arm64.exe`), or
* copies `msvcp140.dll` and `vcruntime140.dll` (plus `vcruntime140_1.dll` on x64) from the redistributable into your application folder alongside the BugSplat runtime files.
  {% endhint %}

4. Include **`BugSplat.h`** in your application's source.
5. Create an instance of `BugSplat` following the example in [MyConsoleCrasher](/getting-started/posting-a-test-crash/myconsolecrasher-c-plus-plus). The BugSplat constructor requires three parameters: `database`, `application`, and `version`. A new BugSplat database can be created on the [Database](https://app.bugsplat.com/v2/database) page. Choose values for application name and version to match your product release. These same values are typically used when uploading symbol files for your application. Learn more about symbol uploads at [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload).

```cpp
#include "BugSplat.h"

BugSplat g_BugSplat(BUGSPLAT_DATABASE, APPLICATION_NAME, APPLICATION_VERSION);
```

6. Modify your build settings so that symbol files are created for release builds. Set `C/C++ > General > Debug Information Format` to `Program Database /Zi`. Be sure to also set `Linker > Debugging > Generate Debug Info` to `Yes (/DEBUG)`.
7. Configure a Post-Build step to upload your application's [symbol files](/guides/working-with-symbol-files). Your script should authenticate using OAuth Client Credentials. You can create credentials on the [Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page under the OAuth tab.

```batch
symbol-upload-windows.exe -b your-database -a your-app -v your-version -i your-client-id -s your-client-secret -d "$(OutputDir)\"
```

{% hint style="info" %}
To get complete symbolicated call stacks and variable names for each crash, you should upload all **`.exe`**, **`.dll`**, and **`.pdb`** files for your product every time you build a release version of your application for distribution or internal testing.
{% endhint %}

### Dynamic Library 🔗

The SDK also ships as a dynamic library, **`BugSplat.dll`**, with a flat C API declared in **`BugSplatC.h`**. The DLL exposes the same crash reporting engine as `BugSplat.lib` through `BugSplat_*` functions. Choose the dynamic library when:

* You don't want your runtime library setting (`/MT` vs `/MD`) coupled to BugSplat's. Only the C ABI crosses the DLL boundary, so your application's CRT choice doesn't need to match the SDK's.
* You're calling BugSplat from another language (C#, Rust, Python, etc.) via P/Invoke or FFI.

To integrate the dynamic library, follow the steps above with these differences:

1. Link with the import library **`lib\dll\BugSplat.lib`** instead of a static `BugSplat.lib`, and include **`BugSplatC.h`** instead of `BugSplat.h`.
2. Ship **`BugSplat.dll`** alongside your executable, in addition to `BugSplatMonitor.exe`, `BugSplatReporter.exe`, and `BugSplatWer.dll`.
3. Initialize BugSplat with the C API:

```cpp
#include "BugSplatC.h"

BugSplat_Init(BUGSPLAT_DATABASE, APPLICATION_NAME, APPLICATION_VERSION);
BugSplat_SetUser(L"fred");
BugSplat_SetAttribute(L"branch", L"main");
```

{% hint style="info" %}
The C API is also available to static library consumers: define `BUGSPLAT_STATIC` before including `BugSplatC.h`. See the [API documentation](https://docs.bugsplat.com/integrations/desktop/pages/CaGFZikPKXEUx98QaE0A#c-api-bugsplatc.h) for the full list of `BugSplat_*` functions.
{% endhint %}

### Verification ✅

Test your application by forcing a crash.

```cpp
*(volatile int *)0 = 0;
```

Verify that the BugSplat dialog appears, and that crashes are posted to your BugSplat account. Ensure that symbol names in the call stack are resolved correctly. If they aren’t, double-check that the correct version of symbol files and all executables for your application have been uploaded to BugSplat.

If everything was configured correctly, you should see a crash report that looks like this in your BugSplat database.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-6576458e05914356829b39307848961603119242%2Fimage.png?alt=media" alt="BugSplat Crash Page"><figcaption><p>BugSplat Crash Page</p></figcaption></figure>

#### Crash Dialog

The dialog is shown by `BugSplatReporter.exe`, which `BugSplatMonitor.exe` launches once the crash has been captured. It follows the end user's Windows light or dark mode:

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-6fe17e3405665d40734fb68db535b203168313dd%2Fwindows-crash-dialog-light.png?alt=media" alt="The BugSplat crash dialog"><figcaption><p>BugSplat Crash Dialog</p></figcaption></figure>

It reads its colors, type, layout and copy from the `BugSplatTheme` folder at run time, so customizing it means editing JSON rather than rebuilding anything. Its text can also link to your privacy policy or support site, for domains you allow with `SetCrashDialogLinkDomains`. See [Crash Dialog Branding](/education/how-tos/customize-the-crash-dialog), and [How the Windows Crash Reporter Works](/integrations/desktop/cplusplus/how-the-windows-crash-reporter-works) for the process split. To upload reports without showing the dialog, call `SetQuietMode(true)`.

{% hint style="warning" %}
If crash reports arrive but no dialog ever appears, `BugSplatReporter.exe` is almost certainly missing from your install folder. The monitor uploads the report without the dialog in that case and logs the reason to `BugSplat.log`.
{% endhint %}

## User Feedback

In addition to crash reporting, BugSplat supports collecting non-crashing user feedback such as bug reports and feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title.

Set user details and an application key, then call `PostFeedback` on your `BugSplat` instance:

```cpp
g_BugSplat.SetUser(L"Jane");
g_BugSplat.SetEmail(L"jane@example.com");
g_BugSplat.SetKey(L"en-US");

bool success = g_BugSplat.PostFeedback(L"Login button broken", L"Nothing happens when I tap it");
```

To include file attachments such as screenshots or log files:

```cpp
std::vector<const wchar_t*> attachments = {
    L"C:\\path\\to\\screenshot.png",
    L"C:\\path\\to\\log.txt"
};
bool success = g_BugSplat.PostFeedback(L"Login button broken", L"Nothing happens when I tap it", attachments);
```

You can also add attachments individually with `AddAttachment()` before calling `PostFeedback()`. All attachments passed to `PostFeedback` are cleared after each feedback upload whereas attachments added via `AddAttachment()` are added the current report and future reports during the current session.

## Dependencies

See technology dependencies on our [dependencies page](/integrations/desktop/cplusplus/dependencies).


# How the Windows Crash Reporter Works

How BugSplat for Windows captures a crash, shows the crash dialog, and uploads the report

BugSplat for Windows is a handful of files that ship next to your executable. Knowing which one does what makes it much easier to work out what went wrong when a report doesn't arrive, or when the crash dialog doesn't appear. This page describes BugSplat for Windows 9.0.0 and later.

{% hint style="warning" %}
**Upgrading from 8.x?** `BugSplatReporter.exe` is a **new file** in 9.0.0, and `BugSplatRc.dll` is **gone**. If you update the SDK but not your installer, crash reports still upload, but the crash dialog silently disappears and your users are never asked for a description. See [Upgrading to 9.0.0](https://docs.bugsplat.com/integrations/desktop/cplusplus/pages/Ae65yTK7rLsmpEMEZcpl#upgrading-to-9.0.0).
{% endhint %}

### The files you ship 📦

| File                        | What it does                                                                                                                                                                                                                                                                                                                   |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `BugSplat.dll`              | The crash reporting engine that loads into your application. Installs the exception filter, allocates guard memory, holds the user, notes and attributes you set, and signals the monitor when something goes wrong. Only needed if you link the import library rather than a static `BugSplat.lib`, or use BugSplat for .NET. |
| `BugSplatMonitor.exe`       | Runs in a separate process so it survives the crash. Reads the shared memory your application wrote, calls `MiniDumpWriteDump` against the crashing process, detects hangs, assembles the crash folder, and **uploads the report**.                                                                                            |
| `BugSplatReporter.exe`      | The **crash dialog** your end user sees, and nothing else. It never touches the network; it hands the user's answers back to the monitor.                                                                                                                                                                                      |
| `BugSplatWer.dll`           | The Windows Error Reporting runtime exception module. Catches the failures no in-process filter can see — fast-fail errors, stack buffer overruns, and some heap corruption. Registered in the registry by your installer.                                                                                                     |
| `BugSplatTheme\` (optional) | `theme.json` and `strings.en-US.json`, which `BugSplatReporter.exe` reads to decide how the crash dialog looks and what it says, plus any logo or translations you add.                                                                                                                                                        |

`BugSplatRc.dll`, the resource-only DLL that held the dialog templates and artwork before 9.0.0, no longer exists. Don't ship it.

{% hint style="info" %}
The `BugSplatTheme` folder in the SDK's `bin` folder is an exact copy of the defaults built into `BugSplatReporter.exe`, so the dialog looks the same with or without it. Ship it when you rebrand or reword the dialog. See [Crash Dialog Branding](/education/how-tos/customize-the-crash-dialog).
{% endhint %}

### The dialog is a separate process 🧩

Before 9.0.0, the crash dialog was part of `BugSplatMonitor.exe`. It now lives in its own executable. The monitor still does everything else — capture, upload and retries — and the two communicate through the crash folder and the reporter's exit code rather than through an IPC protocol.

`BugSplatMonitor.exe` writes everything it knows about the crash into a crash folder, then runs:

```
BugSplatReporter.exe --report "C:\Users\<user>\AppData\Local\Temp\BugSplat\<app>-<version>\<guid>"
```

That folder path is the reporter's input. It reads the application name and version and the user's name, email and description from `BugSplatCrashData.json` to fill in the dialog. The monitor also passes `--link-domains` with the domains your application allowed with `SetCrashDialogLinkDomains`, so that only your application's code, never a file on disk, decides which [links in the dialog](/education/how-tos/customize-the-crash-dialog#links-in-the-dialog) work.

The reporter answers with its exit code:

| Exit code                                          | Meaning                                                                                                   | What the monitor does                                                                    |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `0`                                                | **Send report.** The reporter wrote the user's name, email and description to `dialog-result.json` first. | Saves the answers into the crash data, then uploads the report.                          |
| `2`                                                | **Don't send.**                                                                                           | Deletes the crash folder. Nothing is uploaded.                                           |
| Anything else, or the reporter couldn't be started | The dialog failed.                                                                                        | Uploads the report as it stands, so a problem with the dialog never costs you the crash. |

The split has three practical consequences:

* **Theming needs no compiler.** The reporter reads its appearance from JSON at runtime, so rebranding the dialog is editing a file rather than rebuilding a resource DLL in Visual Studio.
* **Your application doesn't wait for the upload.** As soon as the user answers the dialog, the monitor releases your application and uploads in the background. There's no progress window.
* **A missing or broken reporter degrades rather than fails.** The monitor does the uploading either way, so the report still arrives without the dialog.

### A crash, end to end 🔄

```
  YOUR APPLICATION                          WINDOWS ERROR REPORTING
  BugSplat.dll / BugSplat.lib               BugSplatWer.dll
  exception filter + shared memory          fast-fail, stack overrun
            │                                          │
            │ 1. launch at init                        │
            │ 2. signal on crash / hang                │
            └─────────────────┬────────────────────────┘
                              ▼
                  ┌───────────────────────┐
                  │  BugSplatMonitor.exe  │   3. MiniDumpWriteDump
                  │                       │   4. write the crash folder:
                  │                       │      minidump, BugSplat.log,
                  │                       │      attachments,
                  │                       │      BugSplatCrashData.json
                  └───────────┬───────────┘
                              │
              5. spawn and wait for exit
                 --report <crash folder>
                              │
                              ▼
                  ┌───────────────────────┐
                  │ BugSplatReporter.exe  │   reads BugSplatTheme\theme.json
                  │                       │   and BugSplatTheme\strings.<tag>.json
                  │   the crash dialog    │   6. show the crash dialog
                  └───────────┬───────────┘
                              │
              7. exit code, and on Send
                 dialog-result.json { user, email, description }
                              │
                              ▼
                  ┌───────────────────────┐
                  │  BugSplatMonitor.exe  │   8. save the answers,
                  │                       │      release your application
                  │                       │   9. zip and upload to BugSplat
                  └───────────────────────┘  10. delete the crash folder
```

1. Your application constructs `BugSplat` (or calls `BugSplat_Init`). The SDK launches `BugSplatMonitor.exe` and hands it a shared memory block and a pair of events.
2. Your application crashes, or hangs past `SetHangDetectionTimeout`. The exception filter fills in the shared memory and signals the monitor. If the failure is one no in-process filter can see, Windows Error Reporting loads `BugSplatWer.dll`, which writes the minidump into the crash folder itself and then asks the monitor to send it.
3. Otherwise, the monitor — a live process, unaffected by the corruption in yours — calls `MiniDumpWriteDump` against the crashing process.
4. The monitor writes a crash folder under `%TEMP%\BugSplat\<appName>-<appVersion>\<guid>\`, containing the minidump, `BugSplat.log`, any attachments you added, and `BugSplatCrashData.json`.
5. The monitor spawns `BugSplatReporter.exe --report <folder>` and waits for it. Your application waits too.
6. The reporter loads `BugSplatTheme\theme.json` and the string file matching the end user's Windows UI language, then shows the crash dialog, prefilled with the name, email and description your application set.
7. On **Send report**, the reporter writes what the user entered to `dialog-result.json` and exits with `0`. On **Don't send**, or if the user closes the window, it exits with `2`. Pressing Escape does nothing, so a reflexive key press doesn't throw the report away.
8. On Send, the monitor saves the answers into `BugSplatCrashData.json` and releases your application, which can now exit. On Don't send, it deletes the crash folder and stops.
9. The monitor zips the folder and uploads it to BugSplat, then opens your [support response](/guides/production/setting-up-custom-support-responses) in the browser, if you have one for this crash.
10. On success the monitor deletes the crash folder. If the upload fails with an error worth retrying, it increments a retry count and leaves the folder in place, so a later launch of your application can try again, up to three times.

Because the answers are saved before the upload starts, an upload cut short — the machine shuts down, or a launcher ends your application's whole process tree — isn't lost: the next launch of your application uploads the folder with the user's description in it.

{% hint style="info" %}
`BugSplatCrashData.json` and `dialog-result.json` are deliberately **excluded** from the uploaded zip. They're the monitor's working state, not part of the report; the user's name, email and description are sent in the fields they belong in.
{% endhint %}

### Quiet mode and unattended machines 🤫

`SetQuietMode(true)` (`BugSplat_SetQuietMode(1)` in C, or `QuietMode = true` in .NET) tells the monitor not to start `BugSplatReporter.exe` at all. The monitor uploads the report with no window: no dialog and no support response. In quiet mode your application waits until the upload has finished.

For machines that have a screen but nobody in front of them — kiosks, build agents, test rigs — `features.autoCloseSeconds` in `theme.json` can be a better fit than quiet mode: the dialog appears, and sends itself if nobody touches it. It never discards the report.

### When `BugSplatReporter.exe` is missing 🚨

If `BugSplatReporter.exe` isn't next to `BugSplatMonitor.exe`, or can't be started, the monitor uploads the report without showing the dialog.

**The report still arrives.** What is lost is the dialog — so the user is never prompted for a description and has no opportunity to decline. From your side the only visible symptom is that crashes suddenly stop carrying user descriptions.

This is logged. `BugSplat.log` in the crash folder will contain:

```
BugSplatReporter.exe not found next to BugSplatMonitor.exe - uploading without the crash dialog. Add BugSplatReporter.exe to your installer.
```

If the reporter is there but can't be started, the log says `Failed to start BugSplatReporter.exe`, with the Windows error code, instead. Either line is the thing to search for if the dialog stops appearing after an SDK update.

{% hint style="danger" %}
Updating `BugSplat.dll` and `BugSplatMonitor.exe` without adding `BugSplatReporter.exe` is the failure mode to watch for. It doesn't fail, it doesn't warn the end user, and reports keep arriving; the dialog just quietly stops appearing. See [Upgrading to 9.0.0](https://docs.bugsplat.com/integrations/desktop/cplusplus/pages/Ae65yTK7rLsmpEMEZcpl#upgrading-to-9.0.0).
{% endhint %}

### Customizing the dialog 🎨

Colors, fonts, measurements, the logo and which fields appear all come from `BugSplatTheme\theme.json`. Every word the dialog shows comes from `BugSplatTheme\strings.en-US.json`, or from a translation you add. Both are read at run time, and `BugSplatReporter.exe --preview` shows the result without crashing anything or uploading a report.

See [Crash Dialog Branding](/education/how-tos/customize-the-crash-dialog).

### Xbox and GDK 🎮

There is no `BugSplatReporter.exe` or `BugSplatTheme` folder on Xbox, because there is no crash dialog. `BugSplatMonitor.exe` posts the report itself, and quiet mode is always on. Crash folders live under `XPersistentLocalStorageGetPath` rather than `%TEMP%`. See [Xbox](/integrations/game-development/xbox).


# Full Memory Dumps

In some circumstances, the default memory dump image created by BugSplat may not contain enough information to diagnose the underlying problem leading to the crash. In these cases, it can be helpful to create a full memory dump. Note, this can be an expensive operation. The full memory dump can be really large, slow to upload, and slow to process.

BugSplat customers interested in processing full memory dumps should contact <sales@bugsplat.com>. There is a charge for this feature. After your account has been enabled for full memory dump processing, follow the instructions below.

#### Creating Full Memory Dumps for Windows Applications

To enable full memory dumps in your C++ application, call the setMiniDumpType method after initializing the BugSplat library:

```cpp
// BugSplat initialization  
BugSplat *g_BugSplat = new BugSplat(L"DbName", L"AppName", L"AppVersion");
g_BugSplat->SetMiniDumpType(MINIDUMP_TYPE::MiniDumpWithFullMemory);
```

**Creating Full Memory Dumps for .NET Apps**

To enable full memory dumps in an application using [BugSplat for .NET](/integrations/desktop/bugsplat-for-dot-net), set `MiniDumpType` to `MiniDumpType.WithFullMemory` after initializing BugSplat:

```csharp
// BugSplat initialization
var bugsplat = new BugSplat(Database, App, Version);
bugsplat.MiniDumpType = MiniDumpType.WithFullMemory;

```

**Collecting Full Memory Dumps**

After modifying your application, use the following steps to collect full memory dumps:

1. Deploy your application. By default, crash reports will still be created with the normal minidump size.
2. Inside the BugSplat web application, the "Full Dumps" checkbox on the [versions page](https://app.bugsplat.com/v2/versions) must be enabled to get a full memory crash dump. Enable the checkbox for each version of your application that should send full memory dumps. If the checkbox isn't set, application crashes will create normal minidump files. The Full Dumps column is hidden by default; you must display it using the column visibility dropdown menu.
3. You should enable full memory dumps only for the duration required to capture your critical crash information. The overhead of the much larger full memory dump files will affect your customers' crash upload experience and the time needed to process the crash reports.
4. You can download crash reports containing full memory dumps using the crash details page's Attachments tab. Full memory dumps will typically not show the contents of the crash zip file. Your only option will be the "Download All" button.
5. Full dump crash artifacts are automatically removed from BugSplat after 7 days to keep storage costs reasonable.<br>


# BugSplat for Windows Dependencies

Our redistributable components are built from the Microsoft Visual C++ technology stack. In addition to the Microsoft libraries, the following third-party components are compiled into BugSplat binaries that you link with or ship with your application.

| Name:                                    | Version:                   | License:                  | URL:                                                                 | Used in:                                                         |
| ---------------------------------------- | -------------------------- | ------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------- |
| ATG Tool Kit (ATGTK)                     | 2022 snapshot              | MIT                       | <https://github.com/microsoft/Xbox-GDK-Samples/tree/main/Kits/ATGTK> | BugSplat.dll, BugSplat.lib, BugSplatMonitor.exe, BugSplatWer.dll |
| JSON for Modern C++ (bundled with ATGTK) | 3.6.1                      | MIT                       | <https://github.com/nlohmann/json>                                   | BugSplat.dll, BugSplat.lib, BugSplatMonitor.exe, BugSplatWer.dll |
| Miniz-Cpp                                | Commit 052335e             | MIT                       | <https://github.com/tfussell/miniz-cpp>                              | BugSplatMonitor.exe                                              |
| miniz (bundled with Miniz-Cpp)           | 1.15                       | Public domain (Unlicense) | <https://github.com/richgel999/miniz>                                | BugSplatMonitor.exe                                              |
| MultipartEncoder                         | Commit ab4182a             | MIT                       | <https://github.com/AndsonYe/MultipartEncoder>                       | BugSplatMonitor.exe                                              |
| RapidJSON                                | 1.1.0 (August 2022 master) | MIT                       | <https://github.com/Tencent/rapidjson/>                              | BugSplatMonitor.exe, BugSplatWer.dll                             |
| Windows Template Library (WTL)           | 10.0.8356                  | MS-PL                     | <https://sourceforge.net/projects/wtl/>                              | BugSplatMonitor.exe                                              |

Sample applications and build tools, such as `symbol-upload-windows.exe`, aren't redistributed with your application and aren't listed here.


# BugSplat for Windows Upgrade Guide

Upgrading BugSplat for Windows to 9.0.0, and from versions prior to 7.0.0

This guide covers the two releases of the BugSplat Windows/Xbox SDK that change what you ship or how you integrate it: [9.0.0](#upgrading-to-9.0.0), which moved the crash dialog into its own process, and [7.0.0](#upgrading-from-versions-prior-to-7.0.0), a significant upgrade of the whole SDK. If you're coming from a version before 7.0.0, read both.

## Upgrading to 9.0.0

In BugSplat for Windows 9.0.0, the crash dialog moved out of `BugSplatMonitor.exe` into a new program, `BugSplatReporter.exe`. The monitor still captures and uploads the report, and now uploads in the background after the user answers the dialog, so your application can exit sooner; there's no progress window. The dialog has a new design, and is customized with a theme folder of JSON files instead of by rebuilding `BugSplatRc.dll`, which no longer exists. See [How the Windows Crash Reporter Works](/integrations/desktop/cplusplus/how-the-windows-crash-reporter-works) for how the pieces fit together.

{% hint style="info" %}
**Already on 9.0.0?** In 9.0.1 the theme folder is `BugSplatTheme\`; rename your `theme\` folder, because `theme\` is no longer read. If you use the NuGet package's `BugSplatTheme` project folder, nothing changes for you.
{% endhint %}

{% hint style="danger" %}
**Add `BugSplatReporter.exe` to your installer.** Forgetting it doesn't produce an error: `BugSplatMonitor.exe` uploads the report without the dialog when the reporter is missing, so crashes keep arriving, but **the crash dialog silently stops appearing**. Nobody is asked what they were doing, and nobody can decline to send. The only sign is a line in the crash folder's `BugSplat.log`:

```
BugSplatReporter.exe not found next to BugSplatMonitor.exe - uploading without the crash dialog. Add BugSplatReporter.exe to your installer.
```

After upgrading, force a crash on a machine that installed your application from your installer, not from your build output, and confirm the dialog appears.
{% endhint %}

### Update Your Installer

Ship these files from the SDK's `BugSplat\<platform>\<config>\bin` folder, in the same folder as your executable:

| File                   | Change in 9.0.0                                                                                                                                              |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `BugSplatReporter.exe` | ➕ **New.** Shows the crash dialog.                                                                                                                           |
| `BugSplatMonitor.exe`  | Updated. Captures the crash, starts `BugSplatReporter.exe`, then uploads the report.                                                                         |
| `BugSplatWer.dll`      | Updated.                                                                                                                                                     |
| `BugSplat.dll`         | Updated. Only if you link the dynamic library.                                                                                                               |
| Theme folder           | ➕ **New, optional.** `theme.json` and `strings.en-US.json`, in `BugSplatTheme\` (9.0.1 and later; 9.0.0 used `theme\`). Ship it if you customize the dialog. |
| `BugSplatRc.dll`       | ➖ **Removed.** Delete it from your installer, your copy scripts and post-build steps, and your packaged application. Nothing loads it.                       |

The [`BugSplat`](https://www.nuget.org/packages/BugSplat) NuGet package copies `BugSplatReporter.exe` to your output with the rest of the native runtime, so a .NET application needs no project changes. If you copy BugSplat's files yourself, for example next to a native host's executable, copy `BugSplatReporter.exe` too. See [BugSplat for .NET](/integrations/desktop/bugsplat-for-dot-net).

Xbox titles are unaffected: there's no crash dialog on Xbox, so there's no `BugSplatReporter.exe` to ship.

### Update Every BugSplat Binary Together

The memory that your application and `BugSplatMonitor.exe` share changed in 9.0.0. Update `BugSplat.lib` or `BugSplat.dll`, `BugSplatMonitor.exe`, and `BugSplatWer.dll` together, all from the same release. A mixed set is detected and refused, so crashes aren't reported until every file matches.

### Move Dialog Customizations to the Theme

If you customized the dialog by editing `BugSplatRc.rc` and rebuilding `BugSplatRc.dll`, re-create those changes in the `BugSplatTheme` folder: colors, fonts, layout, logo and which fields appear in `theme.json`, and wording in `strings.en-US.json`. Nothing needs to be compiled, and `BugSplatReporter.exe --preview` shows the result without crashing anything. The defaults have changed too: the dialog has new wording, a new logo, and a light and a dark design that follows the user's Windows setting. See [Crash Dialog Branding](/education/how-tos/customize-the-crash-dialog). If your changes went further than a theme can, such as a different layout, the crash dialog's source is available to Enterprise customers.

### Allow Links in the Dialog, If You Want Them

The dialog's body text and contact note can now link to your privacy policy or support site. Links are off by default: they work only for domains your application allows in code with `SetCrashDialogLinkDomains` (`BugSplat_SetCrashDialogLinkDomains` in C, `CrashDialogLinkDomains` in .NET), so a theme file can't add a link on its own. See [Links in the Dialog](/education/how-tos/customize-the-crash-dialog#links-in-the-dialog).

Apart from that optional call, no code changes are required.

## Upgrading From Versions Prior to 7.0.0

The BugSplat Windows/Xbox SDK underwent a significant upgrade in version 7.0.0. Customers upgrading from earlier versions can use this section to assist their migration.

### Architecture Changes

BsSndRpt.exe has been replaced by BugSplatMonitor.exe. When BugSplat is initialized, `BugSplatMonitor.exe` is launched and is responsible for generating minidump files from the primary application process. Since 9.0.0, the monitor then starts `BugSplatReporter.exe`, which displays a dialog prompting the user for additional information related to a crash, and sends the report to BugSplat.

BugSplat now integrates with the local WER service to capture crashes that cannot be caught by application code. Crashes that can only be handled via a WER callback include fast-fail errors and certain types of memory overwrites. A new module, `BugSplatWer.dll`, must be installed with your application and configured in the registry to enable WER integration. Note that when WER handles an exception, there is no opportunity for application code to participate in the crash report. As a result, code in the Global Exception Filter is not executed.

### Code Changes

#### **BugSplat Constructor**

The BugSplat constructor initialization flags have been removed. Options can be configured after the BugSplat instance is initialized. Here are the new methods for configuring these options.

<table><thead><tr><th width="272.421875">Flag</th><th>New Method or Behavior</th></tr></thead><tbody><tr><td>MDSF_USEGUARDMEMORY</td><td><code>g_bugSplat.AllocGuardMemory(guardMemorySizeInBytes);</code> A 3-MB guard buffer is allocated by default.</td></tr><tr><td>MDSF_NONINTERACTIVE</td><td><code>g_BugSplat.SetQuietMode(true);</code></td></tr><tr><td>MDSF_FORCEEXIT</td><td>BugSplat's global exception filter always exits. Provide your own global exception filter to override.</td></tr><tr><td>MDSF_PREVENTHIJACKING</td><td>BugSplat now always attempts to keep our exception filter in place.</td></tr><tr><td>MDSF_DETECTHANGS</td><td><code>g_bugsplat.SetHangDetectionTimeout(detectionSeconds);</code> with detectionSeconds set to 0 to disable.</td></tr><tr><td>MDSF_SUSPENDALLTHREADS</td><td>No longer applicable since minidumps are now created by the external BugSplatMonitor process.</td></tr><tr><td>MDSF_LOGCONSOLE, MDSF_LOGFILE, MDSF_LOG_VERBOSE</td><td>BugSplat now always provides log files, and there is no longer a verbose option.</td></tr></tbody></table>

#### **Function Name Changes**

Several of the BugSplat method names have been changed:

| Old Method Name           | New Method Name    |
| ------------------------- | ------------------ |
| setDefaultUserName        | SetUser            |
| setDefaultUserEmail       | SetEmail           |
| setDefaultUserDescription | SetUserDescription |
| setNotes                  | SetNotes           |
| setAttribute              | SetAttribute       |
| createAsanReport          | CreateAsanReport   |
| createReport              | CreateXmlReport    |
| sendAdditionalFile        | AddAttachment      |

#### **Obsolete Functions**

`g_bugSplat.setCallback` The callback function has been removed. If you wish to perform tasks at crash time, provide your own global exception filter function. An example of this can be found in the MyConsoleCrasher example program.

### Build Changes

Add the `/GS` compiler flag to both Debug and Release configurations to enable checking stack overrun conditions.

Link with `BugSplat.lib` .

Copy `BugSplatMonitor.exe`, `BugSplatReporter.exe`, and `BugSplatWer.dll` to your executable folder.

### Installer Changes

#### **Redistributable Files**

Your installer must install `BugSplatMonitor.exe`, `BugSplatReporter.exe`, and `BugSplatWer.dll`, plus `BugSplat.dll` if you link the dynamic library. There is no longer a `BsSndRpt.exe` to install, and since 9.0.0 there's no `BugSplatRc.dll` either. These files should all be located in the same directory as your primary executable. See [Update Your Installer](#update-your-installer) for the optional `BugSplatTheme` folder.

#### **Registry Changes**

To enable BugSplat to register for WER callbacks, register the `BugSplatWer.dll` module as shown below. This registry entry should be a `DWORD` whose name is the path to the `BugSplatWer.dll` file installed in the same location as your executable. The value should be `0`.

Most applications should create the WER registry key at the following location:

```
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModules
```

However, 32-bit applications must create the WER registry key at a different location:

```
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModules
```

Here is that value shown highlighted in the registry editor for one of our sample applications:

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FpdTKkAzysQpwTg4RsfUy%2Fimage.png?alt=media&amp;token=5b28ea4e-9cf2-49ef-a194-fda85ec50345" alt=""><figcaption></figcaption></figure>

By default, WER will stop creating crash dumps after it has seen a few of the same type. To disable this, create the following registry key:

```
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\{Application Name}
```

Add the following values under the new key you created:

<table><thead><tr><th width="197.11328125">Registry Key Setting</th><th width="358.19921875">Description</th><th>Value</th></tr></thead><tbody><tr><td>DumpType</td><td>Sets the type of dump to create.</td><td>0</td></tr><tr><td>DumpCount</td><td>Sets the maximum number of dumps.</td><td>0</td></tr></tbody></table>

Here's an example of this shown in the registry editor:

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FTGI8CWHNBaXvfPZHNdQE%2Fimage.png?alt=media&amp;token=b9a7d9b4-eadb-4c2d-8096-dcbd968671b1" alt=""><figcaption></figcaption></figure>

For additional information, see <https://learn.microsoft.com/en-us/windows/win32/wer/wer-settings>


# BugSplat for Windows API Documentation

***

### Class: BugSplat

#### Constructor

```cpp
BugSplat(const wchar_t* database, 
         const wchar_t* appName, 
         const wchar_t* appVersion, 
         LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter = nullptr);
```

**Description:** Initializes a new BugSplat instance for crash reporting.

**Parameters:**

* `database` - The BugSplat database identifier
* `appName` - Name of your application
* `appVersion` - Version string of your application
* `lpTopLevelExceptionFilter` - Optional custom top-level exception filter (default: nullptr)

#### Destructor

```cpp
~BugSplat();
```

**Description:** Cleans up BugSplat resources and restores original exception handlers.

***

### Configuration Methods

#### SetQuietMode

```cpp
void SetQuietMode(bool flag);
```

**Description:** Controls whether the crash report dialog is presented to the user (desktop applications only). QuietMode is off by default. In quiet mode, crash reports are still uploaded, with no dialog or support response.

**Parameters:**

* `flag` - `true` to suppress the dialog, `false` to show it

#### SetCrashDialogLinkDomains

```cpp
void SetCrashDialogLinkDomains(const wchar_t* domains);
```

**Description:** Sets the domains that links in the crash dialog's text may open (desktop applications only). Links come from the `body` and `contactNote` strings in the dialog's [theme](/education/how-tos/customize-the-crash-dialog#links-in-the-dialog), but they only work for these domains and their subdomains, and only as `https://` links; anything else is shown as plain text. By default no domain is allowed, so a theme file on its own can never put a working link in the dialog. Call it at startup, before a crash occurs.

**Parameters:**

* `domains` - Domains separated by semicolons, for example `L"example.com;example.org"`, at most 1023 characters. `example.com` also allows `support.example.com`. Pass `nullptr` or an empty string to allow none again.

#### SetKey

```cpp
void SetKey(const wchar_t* key);
```

**Description:** Sets the crash 'key' field for crash identification and grouping.

**Parameters:**

* `key` - Unique identifier string for this crash context

#### SetUser

```cpp
void SetUser(const wchar_t* user);
```

**Description:** Sets the default 'user' field. The crash dialog may allow users to override this value.

**Parameters:**

* `user` - Username or user identifier

#### SetEmail

```cpp
void SetEmail(const wchar_t* email);
```

**Description:** Sets the default 'email' field. The crash dialog may allow users to override this value.

**Parameters:**

* `email` - User's email address

#### SetUserDescription

```cpp
void SetUserDescription(const wchar_t* description);
```

**Description:** Sets the default 'userDescription' field. The crash dialog may allow users to override this value.

**Parameters:**

* `description` - User-provided description of what happened before the crash

#### SetNotes

```cpp
void SetNotes(const wchar_t* notes);
```

**Description:** Sets the initial value of the 'notes' field. BugSplat web application users can edit this field.

**Parameters:**

* `notes` - Additional notes or debugging information

#### SetAttribute

```cpp
void SetAttribute(const wchar_t* name, const wchar_t* value);
```

**Description:** Sets custom attributes that will be included with crash reports.

**Parameters:**

* `name` - Attribute name
* `value` - Attribute value

#### SetMiniDumpType

```cpp
void SetMiniDumpType(MINIDUMP_TYPE dumpType);
```

**Description:** Configures the type of minidump to generate during crashes.

**Parameters:**

* `dumpType` - Windows MINIDUMP\_TYPE enumeration value

#### SetHangDetectionTimeout

```cpp
void SetHangDetectionTimeout(int ms);
```

**Description:** Sets the timeout used to determine if a process is hung.

**Parameters:**

* `ms` - Timeout in milliseconds (default: 5000). Use 0 to disable hang detection.

#### SetCrashCompletionBehavior

```cpp
enum class BugSplatCrashCompletion { Exit = 0, Terminate = 1, ContinueSearch = 2 };

void SetCrashCompletionBehavior(BugSplatCrashCompletion behavior);
```

**Description:** Controls what the crash handler does after the crash report has been created and uploaded. The dump is captured and sent before any of these paths, so reporting is unaffected by the choice:

* `Exit` (default) - calls `exit()`, which runs full C-runtime shutdown.
* `Terminate` - calls `TerminateProcess`, a hard termination that avoids CRT-shutdown hangs in complex hosts (for example, a Unity standalone player whose process can hang on `exit()` after the report is sent).
* `ContinueSearch` - returns `EXCEPTION_CONTINUE_SEARCH` from the unhandled-exception filter, handing control to the operating system's default unhandled-exception handling (Windows Error Reporting, or an attached debugger) instead of ending the process itself.

**Parameters:**

* `behavior` - one of the `BugSplatCrashCompletion` values above (default `Exit`)

#### SetCrashType

```cpp
void SetCrashType(int crashTypeId);
```

**Description:** Overrides the BugSplat crash type id stamped on uploaded crashes. By default native crashes are uploaded as `Native` (id `1`). Set this when a higher-level integration needs the server to process the crash differently. For example, a Unity IL2CPP integration sets `15` (`UnityNative`: "a native crash with an additional file containing the managed call stack"), which is the crash type the BugSplat backend uses to apply `LineNumberMappings.json` and symbolicate managed (C#) frames.

**Parameters:**

* `crashTypeId` - the BugSplat crash type id (default `1` = Native; `15` = UnityNative)

***

### Crash Detection & Reporting

#### GenerateDump

```cpp
void GenerateDump(LPEXCEPTION_POINTERS const exceptionPointers, 
                  MINIDUMP_TYPE dumpType = (MINIDUMP_TYPE)(MiniDumpNormal|MiniDumpFilterTriage)) const;
```

**Description:** Manually generates a BugSplat crash report with the specified exception information.

**Parameters:**

* `exceptionPointers` - Pointer to exception information structure
* `dumpType` - Type of minidump to create (default: MiniDumpNormal|MiniDumpFilterTriage)

#### CreateXmlReport

```cpp
void CreateXmlReport(const wchar_t* xmlReport);
```

**Description:** Sends an XML report to BugSplat, bypassing minidump creation. Program execution continues normally after this call.

**Parameters:**

* `xmlReport` - XML-formatted report string

**Note:** See MyConsoleCrasher.cpp for XML schema examples.

#### CreateAsanReport

```cpp
void CreateAsanReport(const char* asanReport);
```

**Description:** Creates a crash report specifically for AddressSanitizer (ASAN) errors.

**Parameters:**

* `asanReport` - ASAN error report string

***

### File Attachments

#### AddAttachment

```cpp
bool AddAttachment(const wchar_t* filepath);
```

**Description:** Adds a file to be included with crash reports and feedback uploads.

**Parameters:**

* `filepath` - Full path to the file to attach

**Returns:** `true` if the file was successfully added, `false` otherwise

#### RemoveAttachment

```cpp
bool RemoveAttachment(const wchar_t* filepath);
```

**Description:** Removes a single file attachment from the attachment list.

**Parameters:**

* `filepath` - Full path to the file to remove

**Returns:** `true` if the file was found and removed, `false` otherwise

#### ClearAttachments

```cpp
void ClearAttachments();
```

**Description:** Removes all previously added file attachments.

***

### User Feedback

#### PostFeedback

```cpp
bool PostFeedback(const wchar_t* title,
                  const wchar_t* description = L"",
                  const std::vector<const wchar_t*>& attachments = {});
```

**Description:** Posts non-crashing user feedback such as bug reports or feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title.

**Parameters:**

* `title` - Feedback title, used as the stack key for grouping
* `description` - Optional description of the feedback (default: empty string)
* `attachments` - Optional list of file paths to include with the feedback (default: empty)

**Returns:** `true` if the feedback was posted successfully, `false` otherwise

**Note:** Attachments passed via the `attachments` parameter are automatically removed after upload. Attachments added via `AddAttachment()` are not affected.

#### PostFeedbackWithResult

```cpp
struct FeedbackResult {
    bool success = false;
    int crashId = 0;
    std::wstring infoUrl;
};

FeedbackResult PostFeedbackWithResult(const wchar_t* title,
                                      const wchar_t* description = L"",
                                      const std::vector<const wchar_t*>& attachments = {});
```

**Description:** Posts user feedback like `PostFeedback`, and also returns the id BugSplat gave the report and its URL, so your feedback UI can show the report id or link to it. `PostFeedback` calls this function and returns only `success`.

The call waits until the upload finishes, so call it from a background thread rather than your UI thread. Hang detection is paused while it runs.

**Parameters:**

* `title` - Feedback title, used as the stack key for grouping
* `description` - Optional description of the feedback (default: empty string)
* `attachments` - Optional list of file paths to include with this feedback only (default: empty)

**Returns:** A `FeedbackResult`:

* `success` - `true` if the feedback was posted
* `crashId` - The BugSplat report id of the feedback
* `infoUrl` - The URL BugSplat returned for the report

On failure, `success` is `false`, `crashId` is `0`, and `infoUrl` is empty.

**Note:** Added in version 8.0.0.

***

### Crash Management

#### PostCrash

```cpp
bool PostCrash();
```

**Description:** Posts a single crash report and removes the folder after successful upload.

**Returns:** `false` if no BugSplat monitor is available

#### PostAllCrashes

```cpp
bool PostAllCrashes();
```

**Description:** Posts all pending crash reports. This method blocks until completion.

**Returns:** `true` once the monitor has finished posting, whether or not there were crashes to post. `false` if no BugSplat monitor is available.

**Note:** Should only be called on a new thread to avoid blocking the main application.

#### PostAllCrashesAsync

```cpp
bool PostAllCrashesAsync();
```

**Description:** Posts all pending crash reports on a new background thread.

**Returns:** Always returns `true`

#### AttachToProcess

```cpp
bool AttachToProcess(DWORD pid);
```

**Description:** For use in a custom Windows Error Reporting (WER) runtime exception module. WER runs the module inside `WerFault.exe`, where a `BugSplat` instance has no monitor of its own. `AttachToProcess` connects the instance to the monitor of the crashed application, so `PostCrash` uploads through that monitor. Most applications don't need this: registering `BugSplatWer.dll` reports fail-fast crashes without any code (see [Registry Changes](/integrations/desktop/cplusplus/bugsplat-for-windows-upgrade-guide#registry-changes)).

Get the crashed application's process id from the `hProcess` that WER passes to your module. After a successful attach, write your minidump and any extra files into `GetCrashFolder()`, then call `PostCrash`. Crash fields you set on the instance, such as `SetUserDescription`, are included in the report, along with the files the crashed application registered with `AddAttachment`. The crash dialog follows the crashed application's `SetQuietMode` setting.

```cpp
DWORD crashedPid = GetProcessId(pExceptionInformation->hProcess);
if (g_BugSplat.AttachToProcess(crashedPid))
{
    // Write your minidump, plus any extra files to attach, into g_BugSplat.GetCrashFolder().
    g_BugSplat.PostCrash();
}
```

**Parameters:**

* `pid` - Process id of the crashed application

**Returns:** `true` if the instance is attached. `false` if `pid` is `0` or the current process, or if that process has no running BugSplat monitor this SDK can talk to. If it returns `false`, decline the crash in your module so WER can pass it to its other handlers.

**Notes:**

* The crashed application must create its own `BugSplat` instance with the same SDK release as your module.
* Attaching stops the monitor that your instance started. If the attach fails, `PostCrash` and the other upload calls return `false` instead of waiting for a monitor.
* Don't also list `BugSplatWer.dll` under `RuntimeExceptionHelperModules`. WER gives each crash to whichever registered module claims it.
* Added in version 8.2.0.

***

### Utility Methods

#### IsWerEnabled

```cpp
bool IsWerEnabled();
```

**Description:** Checks if Windows Error Reporting integration is currently enabled.

**Returns:** `true` if WER integration is enabled, `false` otherwise

#### AllocGuardMemory

```cpp
void AllocGuardMemory(size_t nbytes);
```

**Description:** Allocates guard memory that is freed in the default GlobalExceptionFilter. By default, a three-megabyte guard memory block is created.

**Parameters:**

* `nbytes` - Number of bytes to allocate

#### FreeGuardMemory

```cpp
void FreeGuardMemory();
```

**Description:** Frees previously allocated guard memory.

#### GetCrashFolder

```cpp
const wchar_t* GetCrashFolder();
```

**Description:** Returns the folder path where current crash artifacts will be stored. BugSplat moves to a new folder after each upload, so copy the string rather than keeping the pointer.

**Returns:** Path string in format `BugSplat\{appName}-{appVersion}\{unique-guid-string}` under the user's temp folder on desktop, or under persistent local storage on Xbox

#### SetSuspendingState

```cpp
void SetSuspendingState(BOOL status);
```

**Description:** Tells BugSplat that the application is suspending, for example across system sleep, or has resumed. While it's suspending, the monitor skips hang detection and crash reports are not generated.

**Parameters:**

* `status` - `TRUE` while the application is suspending, `FALSE` on resume

#### GetLogFilePath

```cpp
const wchar_t* GetLogFilePath();
```

**Description:** Returns the path to the BugSplat log file.

**Returns:** Path string to log file

#### CleanupExceptionSystem

```cpp
void CleanupExceptionSystem();
```

**Description:** Explicitly remove BugSplat's current working folder, log file, and crash state file. This function is needed on Xbox because the system terminates the monitor program and doesn't give it a chance to exit.

***

### Helper Functions

#### CRT Exception Handling

BugSplat provides helper functions to configure CRT (C Runtime) exception handling for comprehensive crash detection.

**SetGlobalCRTExceptionBehavior**

```cpp
inline void SetGlobalCRTExceptionBehavior();
```

**Description:** Configures global CRT exception handlers. Should be called once during application initialization.

**Configured Handlers:**

* `set_terminate()` - Handles C++ termination
* `_set_purecall_handler()` - Handles pure virtual function calls
* `_set_invalid_parameter_handler()` - Handles invalid parameter errors
* `_set_new_handler()` - Handles memory allocation failures

**SetPerThreadCRTExceptionBehavior**

```cpp
inline void SetPerThreadCRTExceptionBehavior();
```

**Description:** Configures per-thread CRT exception handling. It should be called in each thread of your application.

**Configured Handlers:**

* Signal handling for SIGABRT
* Abort behavior configuration

***

### C API (BugSplatC.h)

In addition to the `BugSplat` C++ class, the SDK exposes a flat C API declared in **`BugSplatC.h`**. The C API manages a single process-wide `BugSplat` instance and is the interface exported by the dynamic library, **`BugSplat.dll`**. Because only the C ABI crosses the DLL boundary, consumers of `BugSplat.dll` do not need to match the SDK's runtime library setting (`/MT` vs `/MD`), and any language with C FFI support (C#, Rust, Python, etc.) can call these functions directly.

**Linkage:**

* **Dynamic:** link the import library `lib\dll\BugSplat.lib` and ship `BugSplat.dll` with your application. This is the default when including `BugSplatC.h` with no extra defines.
* **Static:** the C API is also compiled into both static flavors of `BugSplat.lib` (`lib\md` for `/MD` builds, `lib\mt` for `/MT` builds). Define `BUGSPLAT_STATIC` before including `BugSplatC.h`.

All strings are null-terminated UTF-16 (`wchar_t*`). Boolean parameters and return values use `int` (`0`/`1`) for ABI stability.

#### BugSplat\_Init

```c
int BugSplat_Init(const wchar_t* database, const wchar_t* appName, const wchar_t* appVersion);
```

**Description:** Initializes crash reporting and installs the unhandled exception filter. Call once, early in your application's lifetime.

**Returns:** `1` on success, `0` if already initialized or if any argument is null.

#### BugSplat\_IsInitialized

```c
int BugSplat_IsInitialized(void);
```

**Description:** Returns `1` if `BugSplat_Init` has been called successfully, `0` otherwise.

#### BugSplat\_IsWerEnabled

```c
int BugSplat_IsWerEnabled(void);
```

**Description:** Returns `1` if BugSplat's Windows Error Reporting runtime exception module is registered for this process, `0` otherwise. Fail-fast terminations — stack buffer overrun (`0xC0000409`), heap corruption (`0xC0000374`), and `__fastfail` — bypass the unhandled exception filter, so they are reported only when this returns `1`.

Registration requires `BugSplatWer.dll` beside the host executable and a value naming its full path under `RuntimeExceptionHelperModules` (see [Registry Changes](/integrations/desktop/cplusplus/bugsplat-for-windows-upgrade-guide#registry-changes)). It fails silently when either is missing, so check this at startup and warn during development.

**Returns:** `1` if WER integration is registered, `0` otherwise.

#### Forwarding Functions

The remaining functions forward to the equivalent `BugSplat` class methods documented above:

| C function                            | Class method                 |
| ------------------------------------- | ---------------------------- |
| `BugSplat_SetKey`                     | `SetKey`                     |
| `BugSplat_SetUser`                    | `SetUser`                    |
| `BugSplat_SetEmail`                   | `SetEmail`                   |
| `BugSplat_SetUserDescription`         | `SetUserDescription`         |
| `BugSplat_SetNotes`                   | `SetNotes`                   |
| `BugSplat_SetAttribute`               | `SetAttribute`               |
| `BugSplat_AddAttachment`              | `AddAttachment`              |
| `BugSplat_RemoveAttachment`           | `RemoveAttachment`           |
| `BugSplat_SetQuietMode`               | `SetQuietMode`               |
| `BugSplat_SetCrashDialogLinkDomains`  | `SetCrashDialogLinkDomains`  |
| `BugSplat_SetHangDetectionTimeout`    | `SetHangDetectionTimeout`    |
| `BugSplat_SetCrashCompletionBehavior` | `SetCrashCompletionBehavior` |
| `BugSplat_SetCrashType`               | `SetCrashType`               |
| `BugSplat_PostAllCrashesAsync`        | `PostAllCrashesAsync`        |
| `BugSplat_CreateXmlReport`            | `CreateXmlReport`            |
| `BugSplat_CreateAsanReport`           | `CreateAsanReport`           |
| `BugSplat_SetMiniDumpType`            | `SetMiniDumpType`            |

`BugSplat_SetMiniDumpType` takes the Windows `MINIDUMP_TYPE` flags as an `int`. `BugSplat_CreateAsanReport` takes a `const char*` (ASan reports are ASCII/UTF-8 text).

#### BugSplat\_PostFeedback

```c
int BugSplat_PostFeedback(const wchar_t* title,
                          const wchar_t* description,
                          const wchar_t* const* attachments,
                          int attachmentCount);
```

**Description:** Posts non-crashing user feedback such as a bug report or feature request. The title is used as the stack key for grouping feedback in the dashboard.

**Parameters:**

* `title` - Feedback title (also the grouping key)
* `description` - Optional description; may be `NULL` (treated as empty)
* `attachments` - Optional array of file paths, or `NULL` for none. These are included only in this feedback upload and do not affect attachments added via `BugSplat_AddAttachment`
* `attachmentCount` - Number of entries in `attachments` (0 if none)

**Returns:** `1` on success, `0` on failure.

**Note:** The C++ `BugSplat::PostFeedback` takes a `std::vector`, which cannot cross the DLL boundary. The C entry point takes an `(array, count)` pair instead so the C ABI stays free of STL types and remains compatible with `/MT` and non-C++ consumers.

#### BugSplat\_PostFeedbackWithResult

```c
int BugSplat_PostFeedbackWithResult(const wchar_t* title,
                                    const wchar_t* description,
                                    const wchar_t* const* attachments,
                                    int attachmentCount,
                                    int* outCrashId,
                                    wchar_t* outInfoUrl,
                                    int outInfoUrlChars);
```

**Description:** Posts user feedback like `BugSplat_PostFeedback`, and also returns the id BugSplat gave the report and its URL, so your feedback UI can show the report id or link to it. The C counterpart of `PostFeedbackWithResult`. The call waits until the upload finishes, so call it from a background thread rather than your UI thread.

**Parameters:**

* `title`, `description`, `attachments`, `attachmentCount` - As for `BugSplat_PostFeedback`
* `outCrashId` - Receives the BugSplat report id. May be `NULL` if you don't need it.
* `outInfoUrl` - Buffer that receives the URL BugSplat returned for the report, or `NULL` to skip it. The URL is truncated if it doesn't fit and is always null-terminated.
* `outInfoUrlChars` - Capacity of `outInfoUrl` in wide characters, including the null terminator, or `0` to skip it

**Returns:** `1` on success, `0` on failure, before `BugSplat_Init`, or if `title` is `NULL`. On failure, `*outCrashId` is set to `0` when `outCrashId` is non-`NULL`, and `outInfoUrl[0]` is set to the null terminator when `outInfoUrl` is non-`NULL` and `outInfoUrlChars` is greater than `0`.

**Note:** The C++ `BugSplat::PostFeedbackWithResult` returns a `FeedbackResult` that holds a `std::wstring`, which cannot cross the DLL boundary, so this entry point writes the URL into a buffer you supply. Added in version 8.0.0.

#### BugSplat\_GenerateDump

```c
void BugSplat_GenerateDump(void* exceptionPointers, int dumpType);
```

**Description:** Generates a crash report from caller-supplied exception information without terminating the process. Most applications do not need this. The exception filter installed by `BugSplat_Init` already captures unhandled crashes automatically. Use it only when you run your own exception handler and want to report a specific exception.

**Parameters:**

* `exceptionPointers` - An `EXCEPTION_POINTERS*` as provided by the OS inside an SEH `__except` filter (`GetExceptionInformation()`) or an unhandled-exception-filter callback. It is passed as `void*` so the header carries no `<windows.h>` dependency; it is not a value you construct.
* `dumpType` - A combination of Windows `MINIDUMP_TYPE` flags, or a negative value to use the SDK default.

#### BugSplat\_SetSuspendingState

```c
void BugSplat_SetSuspendingState(int suspending);
```

**Description:** Tells BugSplat that the application is suspending or has resumed. The C counterpart of `SetSuspendingState`: while it's suspending, the monitor skips hang detection and crash reports are not generated. Call it with `1` on `WM_POWERBROADCAST` / `PBT_APMSUSPEND` and with `0` on `PBT_APMRESUMEAUTOMATIC` or `PBT_APMRESUMESUSPEND`. It's cheap and safe to call from the UI thread. The monitor also ignores hangs that span system sleep on its own, so calling this is optional for sleep and hibernate.

**Parameters:**

* `suspending` - Non-zero while the application is suspending, `0` on resume

**Note:** Does nothing before `BugSplat_Init`. Added in version 8.3.0.

#### BugSplat\_AttachToProcess

```c
int BugSplat_AttachToProcess(unsigned long pid);
```

**Description:** The C counterpart of [`AttachToProcess`](#attachtoprocess), for a custom WER runtime exception module written in C. Call `BugSplat_Init` in the module, attach with the crashed application's process id, write the minidump into `BugSplat_GetCrashFolder()`, then call `BugSplat_PostCrash`.

**Parameters:**

* `pid` - Process id of the crashed application, from `GetProcessId` on the `hProcess` that WER passes to your module

**Returns:** `1` if attached. `0` before `BugSplat_Init`, if `pid` is `0` or the current process, or if that process has no running BugSplat monitor this SDK can talk to.

**Note:** Added in version 8.2.0.

#### BugSplat\_GetCrashFolder

```c
const wchar_t* BugSplat_GetCrashFolder(void);
```

**Description:** Returns the folder for the next crash report, the same path as `GetCrashFolder`. Copy the string: the folder changes after each upload.

**Returns:** The folder path, or `NULL` before `BugSplat_Init`.

**Note:** Added in version 8.2.0.

#### BugSplat\_PostCrash

```c
int BugSplat_PostCrash(void);
```

**Description:** Uploads the report in the crash folder and removes the folder on success. The C counterpart of `PostCrash`.

**Returns:** `1` once the monitor has handled the upload. `0` before `BugSplat_Init` or if no BugSplat monitor is available.

**Note:** Added in version 8.2.0.

#### C API Example

```c
#include "BugSplatC.h"

int main() {
    BugSplat_Init(L"MyDatabase", L"MyApp", L"1.0.0");
    BugSplat_SetUser(L"john.doe");
    BugSplat_SetEmail(L"john.doe@example.com");
    BugSplat_SetQuietMode(1);
    BugSplat_PostAllCrashesAsync();

    // Your application code here...

    return 0;
}
```

***

### Usage Examples

#### Basic Initialization

```cpp
#include "BugSplat.h"

// Initialize BugSplat
BugSplat BugSplat(L"MyDatabase", L"MyApp", L"1.0.0");
    
int main() {
   
    // Configure global CRT exception handling
    SetGlobalCRTExceptionBehavior();
    
    // Configure per-thread CRT exception handling
    SetPerThreadCRTExceptionBehavior();
    
    // Configure BugSplat options
    BugSplat.SetUser(L"john.doe");
    BugSplat.SetEmail(L"john.doe@example.com");
    BugSplat.SetKey(L"main-session");
    
    // Your application code here...
    
    return 0;
}
```

***

### Notes and Best Practices

1. **Initialization:** Always call `SetGlobalCRTExceptionBehavior()` once during application startup.
2. **Thread Safety:** Call `SetPerThreadCRTExceptionBehavior()` in each thread that should report crashes.
3. **File Attachments:** Be mindful of file sizes when adding attachments to avoid large uploads.
4. **Custom Attributes:** Use `SetAttribute()` to add context-specific information that will help with crash analysis.


# BugSplat for .NET

Report crashes, hangs, and handled exceptions from .NET Framework and .NET 10 applications on Windows with the BugSplat NuGet package.

### Overview 👀

BugSplat for .NET adds crash reporting to .NET Framework 4.7.2+ and .NET 10+ applications on Windows. It's installed from one NuGet package, [`BugSplat`](https://www.nuget.org/packages/BugSplat), whose library, `BugSplatDotNet.dll`, is built for both runtimes from the same source, with the same API. It's built on the BugSplat native SDK: every report is a minidump that BugSplat symbolicates from the symbols you upload, so call stacks show function names, file names, and line numbers for both managed (C#) and native (C++) frames, without shipping `.pdb` files with your application.

The package contains both builds, and NuGet picks the one for your target framework. Everything else in this guide (the native runtime you ship, initialization, handled exceptions, Windows Error Reporting, and symbols) is the same for both. Where a runtime behaves differently, a note says so.

BugSplat captures crashes in two ways, and a complete integration needs both:

* **The application exception handler.** Creating a `BugSplat` instance installs it in your process. It catches unhandled managed exceptions on any thread, including the WPF dispatcher, and crashes in native code your application calls, such as access violations.
* **Windows Error Reporting (WER).** Some crashes end the process without running any of the application's exception handlers, and Windows hands them to WER instead. That includes heap corruption, `__fastfail`, `/GS` failures, fail-fasts from the .NET 10 runtime, and every unhandled exception in a WinUI 3 app. BugSplat captures these with its WER helper, `BugSplatWer.dll`, which Windows loads only after your installer registers it.

Either way, `BugSplatMonitor.exe` writes the minidump from outside your process and uploads it. BugSplat reports:

| Event                                                                                                                                        | How it's captured                                                                                                                           |
| -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Unhandled managed exceptions, on any thread (including the WPF dispatcher)                                                                   | Application exception handler → minidump                                                                                                    |
| Crashes in native code called from managed code (P/Invoke), including access violations                                                      | Application exception handler → minidump, with one mixed C#/C++ call stack                                                                  |
| Handled exceptions you choose to report                                                                                                      | `BugSplat.Post(exception)` → minidump; your app keeps running                                                                               |
| Application hangs (apps with a window)                                                                                                       | Hang detection → minidump of the hung process                                                                                               |
| Fail-fast crashes: heap corruption, `__fastfail`, `/GS` failures, and on .NET 10 runtime fail-fasts and unhandled exceptions in WinUI 3 apps | Windows Error Reporting → `BugSplatWer.dll` → minidump (requires a registry entry; see [Windows Error Reporting](#windows-error-reporting)) |
| User feedback                                                                                                                                | `BugSplat.PostFeedback(...)`                                                                                                                |

Crashes and handled exceptions alike are reported as minidumps with BugSplat's .NET crash type, so the managed frames are named from your symbols. To rebrand or reword the crash dialog, see [Customize the Crash Dialog](#customize-the-crash-dialog).

### Supported Versions

| Runtime                         | Support                              |
| ------------------------------- | ------------------------------------ |
| .NET Framework 4.7.2 and later  | Supported, with the `net472` build.  |
| .NET 10 and later               | Supported, with the `net10.0` build. |
| .NET 5 through 9, and .NET Core | Not supported.                       |

BugSplat for .NET runs on **Windows** only; Linux and macOS aren't supported. It loads the native `BugSplat.dll`, which must match the architecture your application runs as. The NuGet package includes the native runtime for **x64, x86, and ARM64** and copies the matching one; the SDK download includes x64 only.

{% hint style="info" %}
**.NET 10:** your application must target .NET 10 or later to reference the `net10.0` build. BugSplat's server can name the managed frames in crashes from .NET 9 and later, but not from .NET 5 through 8 or .NET Core, whose crashes it can't fully symbolicate.
{% endhint %}

### Getting Started 🚦

Install the [`BugSplat`](https://www.nuget.org/packages/BugSplat) NuGet package:

```
dotnet add package BugSplat
```

or search for **BugSplat** in Visual Studio's NuGet Package Manager. The same package works for .NET Framework 4.7.2+ and .NET 10+ projects.

To get a feel for BugSplat before integrating it, clone [my-dotnet-crasher](https://github.com/BugSplat-Git/my-dotnet-crasher) and try one of the [samples](#sample-apps), which install BugSplat from NuGet: [MyDotNetFrameworkWpfCrasher](/getting-started/posting-a-test-crash/mydotnetframeworkwpfcrasher) for .NET Framework, or [MyDotNetWinUI3Crasher](/getting-started/posting-a-test-crash/mydotnetwinui3crasher) and [MyDotNetCrasher](/getting-started/posting-a-test-crash/mydotnetcrasher) for .NET 10. The samples are also in the [SDK download](https://app.bugsplat.com/browse/download_item.php?item=dotnet).

### Integration 🏗️

1. **Add the** [**`BugSplat`**](https://www.nuget.org/packages/BugSplat) **NuGet package**, as shown in Getting Started above. It references `BugSplatDotNet.dll` for your target framework and brings BugSplat's native runtime with it.
2. **Ship the native runtime next to your executable.** `BugSplat.dll` starts `BugSplatMonitor.exe` from your application's directory to capture crashes, and the monitor starts `BugSplatReporter.exe` to show the crash dialog and upload the report, so `BugSplat.dll`, `BugSplatMonitor.exe`, `BugSplatReporter.exe`, and `BugSplatWer.dll` must be installed alongside your `.exe`. The package copies them to your build and `dotnet publish` output as content files; make sure your installer includes them.

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p><strong>Architecture:</strong> the package copies the runtime for the architecture your application runs as. It uses your runtime identifier or <code>PlatformTarget</code> if you set one. Otherwise, a .NET 10 application gets the architecture of the .NET SDK that builds it. A .NET Framework AnyCPU application gets x86 with <em>Prefer 32-bit</em> and x64 without it. To choose explicitly, set <code>&#x3C;BugSplatNativeArchitecture></code> to <code>x64</code>, <code>x86</code>, or <code>arm64</code>.</p><p><strong>Libraries:</strong> the runtime is copied into executables and test projects. A library loaded by another application, such as a plug-in, can set <code>&#x3C;BugSplatCopyNativeFiles>true&#x3C;/BugSplatCopyNativeFiles></code>, and the files must then be deployed next to the host application's <code>.exe</code>.</p><p><strong>MSIX:</strong> <code>BugSplatMonitor.exe</code> is a plain file in the package; don't list it as an <code>&#x3C;Executable></code> in the manifest.</p></div>

   <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p>BugSplat's native runtime (<code>BugSplat.dll</code>, <code>BugSplatMonitor.exe</code>, <code>BugSplatReporter.exe</code>, and <code>BugSplatWer.dll</code>) depends on the <strong>Visual C++ 2015–2022 runtime</strong> for your application's architecture: <code>MSVCP140.dll</code> and <code>VCRUNTIME140.dll</code>, plus <code>VCRUNTIME140_1.dll</code> on x64. These DLLs are <strong>not part of Windows</strong> and are missing on machines where no application has installed the redistributable. Neither the .NET Framework nor the .NET runtime includes them, so without them your application runs normally but crash reporting fails. Make sure your installer either:</p><ul><li>chains the <a href="https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist">Visual C++ Redistributable</a> installer for your architecture (<code>vc_redist.x64.exe</code>, <code>vc_redist.x86.exe</code>, or <code>vc_redist.arm64.exe</code>), or</li><li>copies those DLLs from the redistributable into your application folder alongside the BugSplat runtime files.</li></ul></div>
3. **Register `BugSplatWer.dll` with Windows Error Reporting** from your installer. Crashes that go through WER aren't reported without it, and **for a WinUI 3 application that's every crash**. See [Windows Error Reporting](#windows-error-reporting) below for the registry entry.
4. **Initialize BugSplat once, as early as possible** (at the top of `Main` or `Program.cs`, or in your `App` constructor), and keep the instance for the life of the process:

   ```csharp
   using BugSplatDotNet;

   var bugsplat = new BugSplat("your-database", "YourApp", "1.0.0")
   {
       User = "fred",
       Email = "fred@example.com",
   };
   bugsplat.SetAttribute("channel", "beta");
   ```

   The database is created on the [Manage Database](https://app.bugsplat.com/v2/company/databases) page in Settings. Creating the instance installs the application exception handler and hang detection, so you don't need a handler of your own for unhandled exceptions, including WPF dispatcher exceptions and exceptions on background threads. Crashes that bypass the application's exception handlers are captured through the WER registration from step 3.
5. **Report handled exceptions** by calling `Post` from inside the `catch` block:

   ```csharp
   try
   {
       LoadDocument(path);
   }
   catch (Exception ex)
   {
       bugsplat.Post(ex);
   }
   ```

   `Post` writes a minidump of the exception being handled and uploads it; your application keeps running. Call it inside the `catch`, while the frames of the code that threw are still on the stack, so the report shows where the exception came from. Called anywhere else, there is no exception in flight and `Post` returns `false` without reporting anything. It blocks while the report is written and uploaded.

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p><strong>32-bit .NET Framework:</strong> the runtime unwinds the stack before a <code>catch</code> block runs, so <code>Post</code> reports where the exception was caught rather than where it was thrown. To keep the throw site, call <code>Post</code> from an exception filter, which runs before the stack unwinds:</p><pre class="language-csharp"><code class="lang-csharp">try
   {
       LoadDocument(path);
   }
   catch (Exception ex) when (Report(ex))
   {
   }

   bool Report(Exception ex)
   {
   bugsplat.Post(ex);
   return true;
   } </code></pre><p>Before version 8.6.2 of the package, <code>Post</code> returned <code>false</code> there and reported nothing.</p></div>
6. **Upload symbols** for every build you ship, so call stacks show function names, file names, and line numbers. See [Symbols](#symbols) below.
7. **Test your integration** by forcing a crash with the application running outside the Visual Studio debugger (Ctrl+F5, or `dotnet run`); the debugger intercepts the exceptions BugSplat would report. Verify that symbols were uploaded on the [Versions](https://app.bugsplat.com/v2/versions) page and that the crash appears on the [Crashes](https://app.bugsplat.com/v2/crashes) page with a symbolicated call stack. `BugSplat.IsWerEnabled` tells you whether the WER registration from step 3 is in place.

### Using the SDK Download Instead of NuGet

If you can't use NuGet, you can add BugSplat from the [SDK download](https://app.bugsplat.com/browse/download_item.php?item=dotnet) instead. Its sample projects show how to wire everything up by hand. In place of steps 1 and 2 above:

1. Reference `BugSplatDotNet.dll` from `BugSplat\dotnet\Release\net472` (.NET Framework) or `net10.0` (.NET 10).
2. Build your application for x64, since the download's native runtime is x64 only.
3. Copy `BugSplat.dll`, `BugSplatMonitor.exe`, `BugSplatReporter.exe`, and `BugSplatWer.dll` from `BugSplat\x64\Release\bin` next to your executable, and include them in your installer. Copy the `BugSplatTheme` folder too if you [customize the crash dialog](#customize-the-crash-dialog).

### Customize the Crash Dialog

The crash dialog's colors, fonts, layout, logo, and wording come from a theme folder that `BugSplatReporter.exe` reads at run time. To ship your own, add a folder named `BugSplatTheme` next to your project file, holding `theme.json`, `strings.en-US.json`, and any logo or translations, and write only the values you're changing:

```
YourApp.csproj
BugSplatTheme\
  theme.json
  strings.en-US.json
  logo.png
```

The package copies the folder's contents to `BugSplatTheme\` in your build output and `dotnet publish` folder, next to `BugSplatReporter.exe`, and keeps it a loose folder in a single-file publish. Without a `BugSplatTheme` folder, the dialog uses its built-in defaults.

* To keep the theme elsewhere, set `<BugSplatThemeDirectory>` to its path, relative to the project file. If that folder doesn't exist, the build fails with `BSTHEME000`.
* Every build on Windows checks the theme with `BugSplatReporter.exe --check-theme` and reports each value the dialog would ignore as a warning, `BSTHEME001` to `BSTHEME005`. Add a code to `<NoWarn>` to silence it, or set `<BugSplatCheckTheme>false</BugSplatCheckTheme>` to skip the check.
* A library that sets `<BugSplatCopyNativeFiles>true</BugSplatCopyNativeFiles>` gets the theme in its own output's `BugSplatTheme\` folder; deploy it next to the host's executable with the native files. If you copy BugSplat's files to a host yourself, copy your theme folder there as `BugSplatTheme\` too.

Links in the dialog's text work only for domains you allow in code:

```csharp
bugsplat.CrashDialogLinkDomains = new[] { "example.com" };
```

See [Crash Dialog Branding](/education/how-tos/customize-the-crash-dialog) for every setting, how to preview a theme, and the rules for links.

### Symbols

BugSplat symbolicates your crashes from the symbol files you upload, which is why your application doesn't need to ship its `.pdb` files. After each build, upload every `.exe`, `.dll`, and `.pdb` your application ships with [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload), using the same database, application name, and version you pass to `new BugSplat(...)`. That includes `BugSplatDotNet.pdb`, BugSplat's native PDBs, and the native PDBs of any C++ libraries you call, so mixed C#/C++ call stacks are symbolicated on both sides.

{% hint style="info" %}
**.NET Framework:** emit full Windows PDBs, the format BugSplat's symbol upload expects:

```xml
<DebugType>full</DebugType>
```

**.NET 10:** the portable PDBs the .NET SDK produces by default work as they are.
{% endhint %}

symbol-upload authenticates with a Client ID and Client Secret, which you create on the [Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page. The samples run it after every build with a `Scripts\SymbolUpload.ps1` post-build step, which reads the credentials from `Scripts\env.ps1` or the `BUGSPLAT_CLIENT_ID` and `BUGSPLAT_CLIENT_SECRET` environment variables. Building with `/p:BugSplatSymbolUpload=false` skips it, and in the .NET 10 samples a failed upload fails the build. Copy the script into your own project, or run symbol-upload from your build pipeline.

### Windows Error Reporting

Some crashes end the process without running any of the application's exception handlers: Windows fail-fasts the process straight through Windows Error Reporting (WER). This happens for heap corruption (for example, a native library freeing the same memory twice), `__fastfail`, and `/GS` stack-cookie failures, as well as the runtime fail-fasts and WinUI 3 crashes described below. WER is the only way BugSplat can capture these crashes. It does so through its WER helper, `BugSplatWer.dll`, which Windows loads only when its full path is listed in the registry. Your installer must create the entry, with administrator rights:

```
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\RuntimeExceptionHelperModules" /v "C:\Path\To\YourApp\BugSplatWer.dll" /t REG_DWORD /d 0 /f
```

`BugSplat.IsWerEnabled` tells you at run time whether the entry is in place. See the [upgrade guide](/integrations/desktop/cplusplus/bugsplat-for-windows-upgrade-guide#registry-changes) for more about the registry entry.

{% hint style="info" %}
**.NET Framework:** unhandled managed exceptions and access violations reach BugSplat's application exception handler. Fail-fasts from native code, such as heap corruption, still go through WER.

**.NET 10:** the runtime also ends some access violations and stack overflows with a fail-fast, so only the WER helper captures them.
{% endhint %}

{% hint style="warning" %}
**WinUI 3 applications must register `BugSplatWer.dll`.** WinUI turns every unhandled exception into a fail-fast, which ends the process without running the application's exception handlers, so the WER helper is the only way BugSplat can capture a WinUI 3 app's crashes. Without the registry entry, none of its crashes are reported.

Check `IsWerEnabled` at startup and warn when the entry is missing, as the [MyDotNetWinUI3Crasher](/getting-started/posting-a-test-crash/mydotnetwinui3crasher) sample does:

```csharp
if (!bugsplat.IsWerEnabled)
{
    // Crashes won't be reported until BugSplatWer.dll is registered.
    System.Diagnostics.Trace.TraceWarning("BugSplat WER is not configured; crashes will not be reported.");
}
```

{% endhint %}

### Mixed C#/C++ Crashes

When managed code calls native code through P/Invoke and the native code crashes, BugSplat reports one call stack that interleaves the C# and C++ frames, symbolicated from both the managed and the native PDBs you upload. This covers native code that faults when called from C#, native code that calls back into C# code that throws, and crashes on native threads with no managed frames at all. The [MyDotNetCrasher](/getting-started/posting-a-test-crash/mydotnetcrasher) sample's `native-*` and `cpp-throw` modes demonstrate each of these, and the Mixed-Mode buttons of the WPF and WinUI 3 samples show the simplest case.

### Limitations

* **Windows only.** The NuGet package supports x64, x86, and ARM64; the SDK download supports x64 only.
* **Start your application with its `.exe`.** `dotnet YourApp.dll` runs your application inside `dotnet.exe`, and BugSplat looks for `BugSplatMonitor.exe` next to `dotnet.exe` instead of your application.
* **Crashes that go through WER aren't reported without the registry entry.** That includes heap corruption, `__fastfail`, `/GS` failures, .NET 10 runtime fail-fasts, and every WinUI 3 crash (see [Windows Error Reporting](#windows-error-reporting)).
* **Unobserved task exceptions aren't reported.** They don't crash the process, so there's no crash to capture. Observe your tasks and report failures with `Post` from a `catch`.
* **.NET Framework: stack overflows in managed code aren't reported.** The .NET Framework ends the process on a stack overflow without running any application exception handler, and reports it through its own `CLR20r3` WER event, which doesn't call `BugSplatWer.dll` even when it's registered.
* **.NET 10: uncaught C++ exceptions** thrown from native code called through P/Invoke are reported from the point where the .NET runtime re-raises them, rather than from the C++ `throw`.

### Native Applications That Host .NET

If your application is a native C++ program that loads the .NET Framework and calls into managed code, integrate the native SDK, [BugSplat for Windows (C++)](/integrations/desktop/cplusplus), in the host program instead of the `BugSplat` package, and call `SetCrashType(8)` so BugSplat resolves the managed frames in its minidumps. Crashes in the managed code are captured by the native SDK's handlers, and the call stack shows the managed frames on top of your native ones. The [MyDotNetFrameworkHostCrasher](/getting-started/posting-a-test-crash/mydotnetframeworkhostcrasher) sample demonstrates the setup.

### API Reference 📖

| Member                                                                                                | Description                                                                                                                                                                                                                                                                                                                                                                             |
| ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BugSplat(string database, string application, string version)`                                       | Initializes crash reporting. Create one instance, early, and keep it for the life of the process.                                                                                                                                                                                                                                                                                       |
| `bool Post(Exception exception)`                                                                      | Reports a handled exception as a minidump and uploads it. Call it inside the `catch` block. Returns whether the report was uploaded.                                                                                                                                                                                                                                                    |
| `FeedbackResult PostFeedback(string title, string? description = null, string[]? attachments = null)` | Posts user feedback. The result's `Success`, `CrashId`, and `InfoUrl` describe the report. It blocks while the report is uploaded, so call it off the UI thread.                                                                                                                                                                                                                        |
| `string User`, `Email`, `Key`, `Description`, `Notes`                                                 | Default values stamped on every report.                                                                                                                                                                                                                                                                                                                                                 |
| `void SetAttribute(string name, string value)`                                                        | Adds a custom attribute to every report.                                                                                                                                                                                                                                                                                                                                                |
| `bool AddAttachment(string filePath)`                                                                 | Attaches a file to every report.                                                                                                                                                                                                                                                                                                                                                        |
| `bool QuietMode`                                                                                      | Set to `true` to suppress the crash dialog; reports are still uploaded.                                                                                                                                                                                                                                                                                                                 |
| `string[] CrashDialogLinkDomains`                                                                     | The domains, and their subdomains, that links in the crash dialog's text may open, for example `new[] { "example.com" }`. Only `https` links work. By default no domain is allowed, and links are shown as plain text. See [Links in the Dialog](/education/how-tos/customize-the-crash-dialog#links-in-the-dialog).                                                                    |
| `MiniDumpType MiniDumpType`                                                                           | The minidump type for crash reports and `Post`. The default, `MiniDumpType.Normal`, is enough for BugSplat to name the managed frames. Larger types, such as `WithPrivateReadWriteMemory` or `WithFullMemory`, are written only when [full memory dumps](/integrations/desktop/cplusplus/full-memory-dumps) are enabled for your database; otherwise BugSplat writes a normal minidump. |
| `bool IsWerEnabled`                                                                                   | Whether `BugSplatWer.dll` is registered with Windows Error Reporting.                                                                                                                                                                                                                                                                                                                   |
| `bool IsInitialized`                                                                                  | Whether crash reporting is installed for this process.                                                                                                                                                                                                                                                                                                                                  |

### Upgrading From the Legacy .NET Framework SDK

The previous .NET Framework SDK (`BugSplat.CrashReporter`) has been replaced by BugSplat for .NET. To upgrade:

| Legacy SDK                                                                                                                                 | BugSplat for .NET                                                                                                                                                      |
| ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BugSplat.CrashReporter.Init(database, app, version)`                                                                                      | `new BugSplat(database, app, version)`                                                                                                                                 |
| Subscribing `AppDomainUnhandledExceptionHandler`, `DispatcherUnhandledExceptionHandler`, and `TaskSchedulerUnobservedTaskExceptionHandler` | Nothing: unhandled exceptions are captured by the constructor                                                                                                          |
| `CrashReporter.createReport(exception)` for handled exceptions                                                                             | `bugsplat.Post(exception)`, inside the `catch`                                                                                                                         |
| Referencing `BugSplatDotNet.dll` from the SDK download                                                                                     | The [`BugSplat`](https://www.nuget.org/packages/BugSplat) NuGet package                                                                                                |
| Shipping `BsSndRpt.exe`, `BugSplatDotNet.dll`, and `BugSplatRc.dll`                                                                        | Shipping `BugSplatDotNet.dll` plus `BugSplat.dll`, `BugSplatMonitor.exe`, `BugSplatReporter.exe`, and `BugSplatWer.dll`, which the NuGet package copies to your output |
| Editing `BugSplatRc.dll` to change the crash dialog                                                                                        | A [`BugSplatTheme` folder](#customize-the-crash-dialog) in your project                                                                                                |
| Any CPU                                                                                                                                    | Any architecture with the NuGet package, which copies the matching native runtime; x64 with the SDK download                                                           |
| SendPdbs                                                                                                                                   | [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload)                                                                                   |

### Sample Apps

| Sample                                                                                             | Runtime                             | What it shows                                                             |
| -------------------------------------------------------------------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------- |
| [MyDotNetFrameworkWpfCrasher](/getting-started/posting-a-test-crash/mydotnetframeworkwpfcrasher)   | .NET Framework 4.7.2                | A WPF app with a button for each kind of report                           |
| [MyDotNetFrameworkHostCrasher](/getting-started/posting-a-test-crash/mydotnetframeworkhostcrasher) | .NET Framework 4.7.2, hosted by C++ | A native C++ program that crashes in the C# code it calls                 |
| [MyDotNetWinUI3Crasher](/getting-started/posting-a-test-crash/mydotnetwinui3crasher)               | .NET 10                             | A WinUI 3 app with a button for each kind of report                       |
| [MyDotNetCrasher](/getting-started/posting-a-test-crash/mydotnetcrasher)                           | .NET 10                             | A console app with a mode for every crash, including mixed C#/C++ crashes |


# macOS

### 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.

### Requirements 📋

* BugSplat for iOS supports iOS 13 and later.
* BugSplat for macOS supports macOS 11.5 and later.

### Integration 🏗️

BugSplat supports multiple methods for installing the xcfamework in a project.

#### Swift Package Manager (SPM)

Add the following URL to your project's `Additional Package Dependencies`:

```
https://github.com/BugSplat-Git/bugsplat-apple
```

#### Manual Setup

To manually install BugSplat.xcframework in your project:

1. Download the latest release (BugSplat.xcframework.zip) from the [Releases](https://github.com/BugSPlat-Git/bugsplat-apple/releases) page. The zip will contain BugSplat.xcframework.
2. Unzip the archive.
3. In Xcode, select your app target, then go to the General tab, scroll down to Framework, Libraries, and Embedded Content, then click the "+" and navigate to where you unzipped the archive in step 2. Select BugSplat.xcframework, then tap the "Add" button. Once added, select Embed & Sign.

### Usage 🧑‍💻

#### Configuration

BugSplat requires a few Xcode configuration steps to integrate the xcframework with your BugSplat account.

Add the following case-sensitive key to your app's `Info.plist` replacing `DATABASE_NAME` with your customer-specific BugSplat database name.

```xml
<key>BugSplatDatabase</key>
<string>DATABASE_NAME</string>
```

{% hint style="info" %}
For macOS apps, you must enable `Outgoing network connections (client)` in the Signing & Capabilities of the Target.
{% endhint %}

#### Symbol Upload

To symbolicate crash reports, you must upload your app's `dSYM` files to the BugSplat server. There are scripts to help with this.

Download BugSplat's cross-platform tool, [symbol-upload-macos](https://docs.bugsplat.com/introduction/development/working-with-symbol-files/upload-symbols-with-symbol-upload) for Apple Silicon by entering the following command in your terminal.

```bash
curl -sL -O "https://app.bugsplat.com/download/symbol-upload-macos"
```

Alternatively, you can download the Intel version via the following command.

```bash
curl -sL -O "https://app.bugsplat.com/download/symbol-upload-macos-intel"
```

Make `symbol-upload-macos` executable

```bash
chmod +x symbol-upload-macos
```

Several options exist to integrate `symbol-upload-macos` into the app build process.

* Create an Xcode build-phase script to upload dSYM files after every build. See example script [Symbol\_Upload\_Examples/Build-Phase-symbol-upload.sh](https://github.com/BugSplat-Git/bugsplat-apple/blob/main/Symbol_Upload_Examples/Build-Phase-symbol-upload.sh)
* Create an Xcode Archive post-action script in the target's Build Scheme in order to upload dSYM files after the app is archived and ready for submission to TestFlight or the App Store. The build-phase script above can be adapted for this purpose.
* Manually upload an `xcarchive` or `dSYM` file generated by Xcode via BugSplat's [Versions](https://app.bugsplat.com/v2/versions) page.

{% hint style="info" %}
For the build-phase script to create dSYM files, change Build Settings `DEBUG_INFORMATION_FORMAT` from `DWARF` to `DWARF with dSYM File`. See inline notes within each script for modifications to Xcode Build Settings required for each script to work.
{% endhint %}

Please refer to our [documentation](https://docs.bugsplat.com/introduction/development/working-with-symbol-files/upload-symbols-with-symbol-upload) to learn more about how to use `symbol-upload-macos`.

#### Initialization

Several iOS and macOS test app examples are included within the [Example\_Apps](https://github.com/BugSplat-Git/bugsplat-apple/blob/main/Example_Apps) folder to show how simple and quickly BugSplat can be integrated into an app, and ready to submit crash reports.

You can instantiate BugSplat by following the language-specific examples below.

**Swift (UIKit)**

```swift
import BugSplat

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Initialize BugSplat
        BugSplat.shared().delegate = self
        BugSplat.shared().autoSubmitCrashReport = false
        BugSplat.shared().start()

        return true
    }
}

extension AppDelegate: BugSplatDelegate {
    // MARK: BugSplatDelegate
    func bugSplatWillSendCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillSendCrashReportsAlways(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatDidFinishSendingCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillCancelSendingCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillShowSubmitCrashReportAlert(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplat(_ bugSplat: BugSplat, didFailWithError error: Error) {
        print("\(#file) - \(#function)")
    }
}
```

**Swift (SwiftUI)**

```swift
import BugSplat

@main
struct BugSplatTestSwiftUIApp: App {
    private let bugSplat = BugSplatInitializer()

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

@objc class BugSplatInitializer: NSObject, BugSplatDelegate {
    override init() {
        super.init()
        BugSplat.shared().delegate = self
        BugSplat.shared().autoSubmitCrashReport = false
        BugSplat.shared().start()
    }

    // MARK: BugSplatDelegate
    func bugSplatWillSendCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillSendCrashReportsAlways(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatDidFinishSendingCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillCancelSendingCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillShowSubmitCrashReportAlert(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplat(_ bugSplat: BugSplat, didFailWithError error: Error) {
        print("\(#file) - \(#function)")
    }
}
```

**Obj-C**

```objectivec
#import <BugSplat/BugSplat.h>

@interface AppDelegate () <BugSplatDelegate>
@end

@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Initialize BugSplat
    [[BugSplat shared] setDelegate:self];
    [[BugSplat shared] setAutoSubmitCrashReport:NO];
    [[BugSplat shared] start];
}

#pragma mark - BugSplatDelegate

- (void)bugSplatWillSendCrashReport:(BugSplat *)bugSplat {
    NSLog(@"bugSplatWillSendCrashReport called");
}

- (void)bugSplatWillSendCrashReportsAlways:(BugSplat *)bugSplat {
    NSLog(@"bugSplatWillSendCrashReportsAlways called");
}

- (void)bugSplatDidFinishSendingCrashReport:(BugSplat *)bugSplat {
    NSLog(@"bugSplatDidFinishSendingCrashReport called");
}

- (void)bugSplatWillCancelSendingCrashReport:(BugSplat *)bugSplat {
    NSLog(@"bugSplatWillCancelSendingCrashReport called");
}

- (void)bugSplatWillShowSubmitCrashReportAlert:(BugSplat *)bugSplat {
    NSLog(@"bugSplatWillShowSubmitCrashReportAlert called");
}

- (void)bugSplat:(BugSplat *)bugSplat didFailWithError:(NSError *)error {
    NSLog(@"bugSplat:didFailWithError: %@", [error localizedDescription]);
}
```

#### Attributes

BugSplat supports custom attributes that can be added to a crash report. These attributes are searchable in the BugSplat dashboard.

```swift
BugSplat.shared().setValue("Value of Attribute", forAttribute: "AttributeName")
```

```objectivec
[[BugSplat shared] setValue:@"Value of Attribute" forAttribute:@"AttributeName"];
```

Please see the framework-specific [sample applications](#sample-applications) for more examples demonstrating how to use attributes.

#### Application Name and Version

By default, BugSplat uses values from your app's `Info.plist` (`CFBundleDisplayName`/`CFBundleName` for application name and `CFBundleShortVersionString` for version). You can override these values programmatically:

```swift
BugSplat.shared().applicationName = "MyCustomAppName"
BugSplat.shared().applicationVersion = "2.0.0-beta"
BugSplat.shared().start()
```

```objectivec
[[BugSplat shared] setApplicationName:@"MyCustomAppName"];
[[BugSplat shared] setApplicationVersion:@"2.0.0-beta"];
[[BugSplat shared] start];
```

#### Application Key

Set an `appKey` to identify your application build, environment, or user locale. In the BugSplat dashboard, you can configure custom localized support responses for crash groups based on the `appKey` value using the "Support Response" button on the Crash Group page. See [Support Responses](https://docs.bugsplat.com/introduction/production/setting-up-custom-support-responses) for more information.

```swift
BugSplat.shared().appKey = "en-US"
```

```objectivec
[[BugSplat shared] setAppKey:@"en-US"];
```

#### Notes

Add arbitrary additional data to include with crash reports. Notes can also be modified in the BugSplat dashboard after a crash is submitted.

```swift
BugSplat.shared().notes = "Debug build, feature-x enabled"
```

```objectivec
[[BugSplat shared] setNotes:@"Debug build, feature-x enabled"];
```

#### Crash Reporter Customization

There are several ways to customize your BugSplat crash reporter.

**Custom Banner Image**

* BugSplat for macOS provides the ability to configure a custom image to be displayed in the crash reporter UI for branding purposes. The image view dimensions are 440x110 and will scale down proportionately. There are 2 ways developers can provide an image:
  1. Set the image property directly on BugSplat
  2. Provide an image named `bugsplat-logo` in the main app bundle or asset catalog

**User Details**

* Set `askUserDetails` to `NO` to prevent the name and email fields from displaying in the crash reporter UI. Defaults to `YES`.

**Auto Submit**

* By default, BugSplat will auto-submit crash reports for iOS and prompt the end user to submit a crash report for macOS. This default can be changed using the `autoSubmitCrashReport` property. Set `autoSubmitCrashReport` to `YES` in order to send crash reports to the server automatically without presenting the crash reporter dialogue. On iOS, when set to `NO`, the user is presented with an alert with options: "Send", "Don't Send", and "Always Send".

**Persist User Details**

* Set `persistUserDetails` to `YES` to save and restore the user's name and email when presenting the crash reporter dialogue. Defaults to `NO`.

**Expiration Time**

* Set `expirationTimeInterval` to a desired value (in seconds) whereby if the difference in time between when the crash occurred and the next launch is greater than the set expiration time, auto-send the report without presenting the crash reporter dialogue. Defaults to `-1`, which represents no expiration.

**Attachments**

Bugsplat supports uploading attachments with crash reports. There's a delegate method provided by `BugSplatDelegate` that can be implemented to provide attachments to be uploaded.

**Bitcode**

Bitcode was introduced by Apple to allow apps sent to the App Store to be recompiled by Apple itself and apply the latest optimization. Bitcode has now been officially deprecated by Apple and should be removed or disabled. If Bitcode is enabled, the symbols generated for your app in the store will be different than the ones from your own build system. We recommend that you disable bitcode in order for BugSplat to reliably symbolicate crash reports. Disabling bitcode significantly simplifies symbols management and currently doesn't have any known downsides for iOS apps.

### 💬 User Feedback

In addition to crash reporting, BugSplat supports collecting non-crashing user feedback such as bug reports and feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title.

```objectivec
[[BugSplat shared] postFeedback:@"Login button broken"
                    description:@"Nothing happens when I tap it"
                       userName:@"Jane"
                      userEmail:@"jane@example.com"
                         appKey:@"pro-tier"
                    attachments:nil
                     completion:^(NSError *error) {
    if (error) {
        NSLog(@"Feedback failed: %@", error);
    } else {
        NSLog(@"Feedback submitted successfully");
    }
}];
```

To include file attachments such as screenshots:

```objectivec
BugSplatAttachment *screenshot = [[BugSplatAttachment alloc] initWithFilename:@"screenshot.png"
                                                              attachmentData:imageData
                                                                 contentType:@"image/png"];
[[BugSplat shared] postFeedback:@"Login button broken"
                    description:@"Nothing happens when I tap it"
                       userName:@"Jane"
                      userEmail:@"jane@example.com"
                         appKey:nil
                    attachments:@[screenshot]
                     completion:^(NSError *error) {
    if (error) {
        NSLog(@"Feedback failed: %@", error);
    } else {
        NSLog(@"Feedback submitted successfully");
    }
}];
```

### ⏱️ Hang Detection

BugSplat can detect fatal main-thread hangs and upload them on the next launch using the same pipeline as crash reports. When enabled, BugSplat watches the main thread; if it stays unresponsive for longer than the configured threshold and the app is then terminated without the main thread recovering (a launch/resume watchdog kill or user force-quit), a hang report is uploaded on the next launch. Non-fatal hangs (those where the main thread eventually resumes) are discarded automatically.

Enable hang detection by setting `enableHangDetection` to `YES` **before** calling `start`. `start` must be invoked on the main thread when this property is enabled.

```swift
BugSplat.shared().enableHangDetection = true
BugSplat.shared().hangDetectionThreshold = 2.0 // optional, defaults to 2.0 seconds
BugSplat.shared().start()
```

```objectivec
[[BugSplat shared] setEnableHangDetection:YES];
[[BugSplat shared] setHangDetectionThreshold:2.0]; // optional, defaults to 2.0 seconds
[[BugSplat shared] start];
```

Hang reports carry the exception name `App Hang (Fatal)` and include attributes prefixed with `bugsplat-hang-` (duration, detection time, app state, launch id) that can be used to correlate them with crashes from the same launch.

{% hint style="info" %}
Detection is suppressed while a debugger is attached. macOS apps have no UIApplication background state, so detection runs whenever the app is launched. Command-line tools can opt in, but be aware that any code path that blocks the main thread without pumping the runloop (for example `std::getline` on stdin) will look like a hang until the runloop runs again.
{% endhint %}

The `hangDetectionThreshold` property accepts values in seconds. Typical production values are between 1.0 and 5.0 seconds. Pick a value that comfortably exceeds any work your app may legitimately do on the main thread (image decoding, JSON parsing, etc.) to avoid false positives. Values below `0.1` are clamped to `0.1`.

### Sample Applications 🧑‍🏫

`Example_Apps` includes several iOS and macOS BugSplat Test apps. Integrating BugSplat only requires the xcframework and a few lines of code.

1. Clone the [bugsplat-apple repo](https://github.com/BugSplat-Git/bugsplat-apple).
2. Open `BugSplat.xcworkspace` in Xcode. This workspace contains the SDK and all example apps. Select an example app scheme to run. For iOS, set the destination to be your iOS device. After running from Xcode, stop the process and relaunch from the iOS device directly.
3. Once the app launches, click the "crash" button when prompted.
4. Relaunch the app on the iOS device. At this point a crash report should be submitted to bugsplat.com
5. Visit BugSplat's [Crashes](https://app.bugsplat.com/v2/crashes) page. When prompted for credentials, enter user `fred@bugsplat.com` and password `Flintstone`. The crash you posted from BugSplatTester should be at the top of the list of crashes.
6. Click the "Crash ID" link to view more details about your crash.


# Linux

## 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.

Before continuing with the tutorial, please review our [myUbuntuCrasher](https://github.com/BugSplat-Git/myUbuntuCrasher) sample application.

## Tutorial

The first step in integrating with Crashpad is ensuring your system has all the required dependencies. These dependencies include `git`, `git-lfs`, `llvm`, `build-essential` and `clang++`. The following snippet will download and install all the dependencies on an Ubuntu system:

```
sudo apt-get install git
sudo apt-get install git-lfs
sudo apt-get install llvm
sudo apt-get install build-essential
sudo apt-get install clang
```

Next, you will need to build and integrate Crashpad with your application. For a step-by-step guide on how to build and integrate Crashpad please see this [doc](/integrations/desktop/crashpad).

Once you've built and integrated Crashpad, you must ensure that your application is built with symbolic information and a build identifier. Symbolic information is required to map the stack trace in the minidump to function names and line numbers in your application's source. A build identifier is required so that `minidump_stackwalk` can match modules loaded at runtime with the corresponding `.sym` file.

{% hint style="info" %}
When specifying the Crashpad libraries `libbase.a` must be the last library argument specified otherwise your code will not compile.
{% endhint %}

If you are building with `clang++`, specify the `-g` flag to ensure the output executable contains symbolic information for debugging. Additionally, when building with `clang++` you must pass the `-Wl,--build-id` argument to ensure the linker creates a build identifier in the output executable. The following [script](https://github.com/BugSplat-Git/myUbuntuCrasher/blob/master/scripts/compile.sh) from [myUbuntuCrasher](https://github.com/BugSplat-Git/myUbuntuCrasher) demonstrates how to link the Crashpad libraries and output an executable with symbolic information using `clang++`:

```
#!/bin/bash
source exports.sh

clang++ -pthread $PROJECT_DIR/main.cpp \
  $CRASHPAD_DIR/lib/libclient.a \
  $CRASHPAD_DIR/lib/libcommon.a \
  $CRASHPAD_DIR/lib/libutil.a \
  $CRASHPAD_DIR/lib/libbase.a \
  -I$CRASHPAD_DIR/include \
  -I$CRASHPAD_DIR/include/third_party/mini_chromium/mini_chromium \
  -I$CRASHPAD_DIR/include/out/Default/gen \
  -o$OUT_DIR/$MODULE_NAME \
  -g \
  -Wl,--build-id
```

Finally, you will need to generate and upload `.sym` files to BugSplat. BugSplat's symbol-upload tool can be used conveniently to generate and upload `.sym` files with a single terminal command. Download a copy of symbol-upload from [GitHub](https://github.com/BugSplat-Git/symbol-upload) or install it via [npm](https://npmjs.com/package/@bugsplat/symbol-upload).

Once you have symbol-upload downloaded or installed, modify the following command to suit your needs.

```bash
$CRASHPAD_DIR/tools/symbol-upload-linux -b $BUGSPLAT_DATABASE \
    -a $BUGSPLAT_APP_NAME \
    -v $BUGSPLAT_APP_VERSION \
    -u $BUGSPLAT_EMAIL \
    -p $BUGSPLAT_PASSWORD \
    -d $PROJECT_DIR/out \
    -f $MODULE_NAME \
    --dumpSyms
```

It's crucial that you re-upload symbols each time you build your application. Otherwise, BugSplat cannot generate function names and line numbers for the crash report. Symbols should be uploaded using a new version for every build to ensure your crashes are processed quickly.

If you've set everything up correctly, your crash report should look like this:

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Feybt4IVrRZsa2B1KYLPV%2Fimage.png?alt=media&amp;token=a361ad38-2ef6-4171-94da-3a8d493ab347" alt=""><figcaption><p>MyUbuntuCrasher Crash on BugSplat</p></figcaption></figure>


# Electron

## Overview 👀

{% hint style="info" %}
Want to see a sample Electron application integrated with BugSplat? Check out [my-electron-crasher](https://github.com/BugSplat-Git/my-electron-crasher)!
{% endhint %}

BugSplat supports the collection of both [electron.crashReporter](https://www.electronjs.org/docs/api/crash-reporter) (native) and [node.js](/integrations/web/node.js) crash reports. Native crashes are generated via [Crashpad](https://github.com/chromium/crashpad) and BugSplat requires symbol files in order to calculate the call stack.

BugSplat will automatically resolve Electron framework symbol files when calculating call stacks. However, if your application includes native add-ons or is packaged with [electron-builder](https://github.com/electron-userland/electron-builder) you will need to upload application-specific symbol files to see full native call stacks. All symbol files must be uploaded to BugSplat via [@bugsplat/symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload), [symupload](https://github.com/google/breakpad/blob/master/docs/getting_started_with_breakpad.md#build-process-specificssymbol-generation), or manually via the [Versions page](https://app.bugsplat.com/v2/versions). More information about uploading symbol files to BugSplat can be found [here](/integrations/desktop/crashpad/how-to-build-google-crashpad#uploading-symbols).

BugSplat-node can also be used to collect [uncaughtException](https://nodejs.org/api/process.html#process_event_uncaughtexception) and [unhandledRejection](https://nodejs.org/api/process.html#process_event_unhandledrejection) events in your application's JavaScript code.

## Native (C++) Crash Reporting ⚙️

Configure [electron.crashReporter](https://github.com/electron/electron/blob/master/docs/api/crash-reporter.md) to upload crash reports to BugSplat using the following steps. BugSplat will automatically download Electron and Electron Framework symbol files. If your application uses [Native Node Modules](https://www.electronjs.org/docs/latest/tutorial/using-native-node-modules), you will need to generate and upload symbol files to resolve call stacks correctly.

### Update Package.json

Add a `database` property with the value of your BugSplat database to `package.json`. Be sure to replace `your-bugsplat-database` with the actual value of your BugSplat database.

```json
{
    ...
    "database": "your-bugsplat-database"
}
```

### Configure Crash Reporter

Next, call `crashReporter.start` as shown in the example below. You may optionally pass globalExtra values for `key`, `email`, `comments`, `notes`, and `ipAddress`.

Note that the `globalExtra` fields will be sent with crashes captured on all processes:

```javascript
const { crashReporter } = require("electron");
const { database, name, version } = require("../../package.json");
crashReporter.start({
  submitURL: `https://${database}.bugsplat.com/post/electron/v2/crash.php`,
  ignoreSystemCrashHandler: true,
  uploadToServer: true,
  rateLimit: false,
  globalExtra: {
    "product": name,
    "version": version,
    "key": "en-US",
    "email": "fred@bugsplat.com",
    "comments": "BugSplat rocks!",
  }
})
```

For more information on configuring `electron.crashReporter` including adding properties to individual processes, please see the [Electron crashReporter documentation](https://www.electronjs.org/docs/latest/api/crash-reporter).

### Generate a Crash

Generate a crash in one of the Electron processes to test your BugSplat integration:

```typescript
process.crash()
```

### View BugSplat Crash Report

Navigate to the [Crashes](https://app.bugsplat.com/v2/crashes) page in BugSplat. You should see a new crash report for your application. Click the link in the **ID** column to see details about your crash on the [Crash](https://app.bugsplat.com/v2/crash?id=1) page:

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FplCKtND87LwU5TGP81fz%2Fimage.png?alt=media&amp;token=7d0fb391-cccc-4ed5-8b96-ec2018cd630f" alt=""><figcaption><p>Electron Native Crashes</p></figcaption></figure>

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fii8SadvlgJpdMlmE0dGW%2Fimage.png?alt=media&amp;token=48ac8fd9-4284-4711-a36a-4c0091dd27e4" alt=""><figcaption><p>Electron Native Crash</p></figcaption></figure>

### Optional: Upload Native Addon Symbols

If your application uses a [node native addon](https://nodejs.org/api/addons.html), you must generate and upload symbols for each binary and for every build.

Use [@bugsplat/symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload#improving-upload-speeds-1) and the `-m` argument to generate and upload `.sym` files from your application binaries automatically. You can run symbol-upload without any arguments to view all available options.

```bash
npx @bugsplat/symbol-upload -u you@email.com -p password -d ./dist -f "**/*.node" -m
```

Alternatively, you can add a build step to generate and upload `.sym` files for your node native addon using standard Breakpad tools. To generate symbol files, you can run [dump\_syms](/integrations/desktop/crashpad/how-to-build-google-crashpad#generating-symbols) with a path to a `.node` file after the Node Native Module build or rebuild step if you're using a tool like [electron-rebuild](https://github.com/electron/electron-rebuild). Once you've generated a `.sym` file for your `.node` native module, the `.sym` file can be uploaded via [symupload](/integrations/desktop/crashpad/how-to-build-google-crashpad#uploading-symbols), or manually on the [Versions](https://app.bugsplat.com/v2/versions?database=Fred) page.

Verify that your node native addon `.sym` files show up on the [Versions](https://app.bugsplat.com/v2/versions) page. Be sure to upload symbols for each released version of your application. Integrate [@bugsplat/symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload) or [symupload](/integrations/desktop/crashpad/how-to-build-google-crashpad#uploading-symbols) into your build and release processes for best results.

## JavaScript/TypeScript Error Reporting 💥

To configure reporting of JavaScript or TypeScript errors in your main and renderer processes, please see our [node.js](/integrations/web/node.js) documentation for installing and configuring [bugsplat-node](https://github.com/BugSplat-Git/bugsplat-node).

{% content-ref url="/pages/-MeRXRpKp3KQxkGy3IUU" %}
[Node.js](/integrations/web/node.js)
{% endcontent-ref %}

### Installing bugsplat-node

Install bugsplat-node via the following command:

```bash
npm i bugsplat-node
```

### Configuration

Next `import` or `require` BugSplat in both your main and renderer threads.

```typescript
import { BugSplatNode as BugSplat } from "bugsplat-node"
const bugsplat = new BugSplat(database, name, version)
```

In addition to the configuration demonstrated above, there are a few public methods that can be used to customize your BugSplat integration:

```typescript
bugsplat.setDefaultAppKey(appKey); // Additional metadata that can be queried via BugSplat's web application
bugsplat.setDefaultUser(user); // The name or id of your user
bugsplat.setDefaultEmail(email); // The email of your user 
bugsplat.setDefaultDescription(description); // A description placeholder that can be overridden at crash time
bugsplat.setDefaultAdditionalFilePaths([paths]); // Paths to files to be sent to BugSplat at post time (limit 10MB) 
bugsplat.postAndExit(error, options); // Wrapper for post that calls process.exit(1) after posting error to BugSplat
bugsplat.post(error, options); // Async function that posts an arbitrary Error object to BugSplat
// If the values options.appKey, options.user, options.email, options.description, options.additionalFilePaths are set the corresponding default values will be overwritten
// Returns a promise that resolves with properties: error (if there was an error posting to BugSplat), response (the response from the BugSplat crash post API), and original (the error passed by bugsplat.post)
```

### Main Thread

Create an error handler for `uncaughtExceptions` and `unhandledPromise` rejections. We recommend you quit your application in the event of an `uncaughtException` or `unhandledPromiseRejection`. You may also want to add code to display a message to your user here:

```typescript
const javaScriptErrorHandler = async (error) => {
  await bugsplat.post(error);
  app.quit();
}
```

Add the error handler created above to `uncaughtException` and `unhandledPromiseRejection` events:

```typescript
process.on('unhandledRejection', javaScriptErrorHandler)
process.on('uncaughtException', javaScriptErrorHandler)
```

### Renderer Thread

Many Electron applications run multiple node.js processes. For instance, the [electron-quick-start](https://github.com/electron/electron-quick-start) application runs both a [main](https://github.com/electron/electron-quick-start/blob/master/main.js) and a [renderer](https://github.com/electron/electron-quick-start/blob/master/renderer.js) process. You must require `bugsplat` in each process you want to capture errors. To capture errors in the renderer process, add the following to renderer.js:

Reloading or quitting the application is sometimes desirable when an error occurs in the renderer process. The following is an example of how to invoke the main process from the renderer and quit your application in the case of an unhandled exception in the renderer:

[renderer.ts](https://github.com/BugSplat-Git/my-electron-crasher/blob/master/src/renderer.ts)

```typescript
window.onerror = async (messageOrEvent, source, lineno, colno, error) => {
await bugsplat.post(error)
  ipcRenderer.send('rendererCrash')
}
```

[main.ts](https://github.com/BugSplat-Git/my-electron-crasher/blob/master/src/main.ts)

```typescript
import { ipcMain } from "electron";
ipcMain.on('rendererCrash', function () {
  // Display an error and reload or quit the app here
})
```

Test BugSplat by throwing a new error in either the main or renderer process:

```typescript
throw new Error("BugSplat!");
```

You may see the following error in the console:

<pre><code><strong>Refused to connect to 'https://fred.bugsplat.com/post/js/' because it violates the following Content Security Policy directive: "default-src 'self'". 
</strong></code></pre>

If you see this error, modify your index.html file to allow report upload from the renderer process:

```html
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; connect-src 'self' https://your-database.bugsplat.com 'unsafe-eval'"/>
```

### Uploading Source Maps

If you're using TypeScript or another language that compiles to JavaScript, BugSplat can map uglified and minified JavaScript function names, file names, and line numbers back to their original values via [source maps](/guides/working-with-symbol-files/source-maps).

To upload source maps, add a symbol-upload script that uploads all your build's `.js.map` files:

```json
{
  ...
  "scripts": {
    "upload-source-maps": "npx @bugsplat/symbol-upload -u you@email.com -p password -d ./dist -f \"**/*.js.map\""
  }
}
```

### Viewing Error Reports

Run your application and generate an error report. Navigate to the [Crashes](https://app.bugsplat.com/v2/crashes) page in BugSplat to view reports for the application you just configured. Click the link in the **ID** column to see details about your crash on the [Crash](https://app.bugsplat.com/v2/crash?id=1) page:

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FE8bGWRUz0b35tA6oeXXA%2Fimage.png?alt=media&amp;token=ec1f56d3-0314-41a8-b267-ea86967c438a" alt=""><figcaption><p>TypeScrpt Error on Crashes Page</p></figcaption></figure>

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2F6cNz2ZwJ6dAPSyue6v9I%2Fimage.png?alt=media&amp;token=3b66265f-db12-46d0-9de5-0bed0b22689c" alt=""><figcaption><p>TypeScript Error in Main Process</p></figcaption></figure>

That’s it! Your Electron application is now configured to upload crash reports to BugSplat.

## Contributing 🤝

BugSplat loves open-source software! If you have suggestions on how we can improve this integration, please reach out to <support@bugsplat.com>, create an [issue](https://github.com/BugSplat-Git/bugsplat-node/issues) in our [GitHub repo](https://github.com/BugSplat-Git/bugsplat-node) or send us a [pull request](https://github.com/BugSplat-Git/bugsplat-node/pulls).


# Qt

## Sample

BugSplat has developed a sample application demonstrating a cross-platform Qt crash reporting solution with Crashpad. The MyQtCrasher sample application provides a good starting point for developers wishing to capture Windows, macOS, and Linux crashes. Additionally, the sample provides symbol upload [scripts](https://github.com/BugSplat-Git/my-qt-crasher/tree/master/Crashpad/Tools) that you can incorporate into your build tools to generate crash reports with fully symbolicated call stacks

The MyQtCrasher sample application is available on [GitHub](https://github.com/BugSplat-Git/my-qt-crasher).

## Building Crashpad

BugSplat leverages [Crashpad](https://chromium.googlesource.com/crashpad/crashpad/+/master/README.md) to provide crash reporting for macOS, Windows, and Linux Qt applications. Please see this [article](/integrations/desktop/crashpad/how-to-build-google-crashpad) for an in-depth guide that discusses how to build Crashpad.

For Windows, you'll need to build shared libraries for both Release (`/MD`) and Debug (`/MDd`) configurations. You'll also want to consider building with [Whole Program Optimization](https://docs.microsoft.com/en-us/cpp/build/reference/gl-whole-program-optimization?view=msvc-170) turned off (`/GL-`). To build shared libraries, generate your Crashpad build using the following terminal command:

```
gn gen out\MD --args="extra_cflags=\"/MD /GL-\"" && gn gen out\MDd --args="extra_cflags=\"/MDd /GL-\""
```

The snippet above works with Windows CMD, and depending on the terminal you're using, you might get various errors related to escape characters. If you choose to omit the `/GL-` flag you must ensure that you build Crashpad with the same version of MSVC you use for building your Qt application otherwise your project [will not build](https://stackoverflow.com/questions/62396117/integrating-crashpad-with-a-windows-qt-application). Setting the version of MSVC that builds Crashpad can be done by instead generating your configuration using the command `gn gen out/Default --winsdk="10.0.19041.0" --ide="vs2017"`.

For more info on how to build Crashpad shared libraries on Windows, see this [post](https://stackoverflow.com/questions/55302553/how-to-build-dynamic-shared-libraries-of-crashpad).

## Integrating Crashpad

Once Crashpad has been built, you'll need to add the relevant include directories to your project. Copy all of the Crashpad `.h` files to the directory `$$PWD/Crashpad/Include/crashpad` where `$$PWD` is your project's working directory. Add the include directories to your project by pasting the following snippet at the top of your project file:

```
# Include directories for Crashpad libraries
INCLUDEPATH += $$PWD/Crashpad/Include/crashpad
INCLUDEPATH += $$PWD/Crashpad/Include/crashpad/third_party/mini_chromium/mini_chromium
INCLUDEPATH += $$PWD/Crashpad/Include/crashpad/out/Default/gen
```

Add values corresponding to your BugSplat database, application name, and version. Note these values, as they will be used to configure Crashpad later in the configuration process.

```
# BugSplat configuration options
BUGSPLAT_DATABASE = fred            # Replace with your BugSplat database
BUGSPLAT_APPLICATION = myQtCrasher  # Replace with the name of your app
BUGSPLAT_VERSION = 1.1              # Replace with your apps version
BUGSPLAT_USER = fred@bugsplat.com   # Your BugSplat email (for uploading symbols)
BUGSPLAT_PASSWORD = Flintstone      # Your BugSplat password (for uploading symbols)
```

Next, link your app with the Crashpad libraries. Linking with the Crashpad libraries is platform-dependent.

### **macOS**

Copy `libcommon.a`, `libbase.a`, `libutil.a`, `libclient.a` , and `libmig_output.a` into `$$PWD/Crashpad/Libraries/MacOS`. You'll need to link to versions of these libraries that were built to target either `arm64` or `x86_64` depending on which architecture your build targets. You'll also need to link with the system libraries `libbsm`, `AppKit.Framework`, and `Security.Framework`. Add the following snippet to your project file to link with the aforementioned libraries:

```
# Crashpad rules for MacOS
macx {
    # Choose either x86_64 or arm64
    #ARCH = x86_64
    ARCH = arm64

    # Crashpad libraries
    LIBS += -L$$PWD/Crashpad/Libraries/MacOS/$$ARCH -lcommon
    LIBS += -L$$PWD/Crashpad/Libraries/MacOS/$$ARCH -lclient
    LIBS += -L$$PWD/Crashpad/Libraries/MacOS/$$ARCH -lbase
    LIBS += -L$$PWD/Crashpad/Libraries/MacOS/$$ARCH -lutil
    LIBS += -L$$PWD/Crashpad/Libraries/MacOS/$$ARCH -lmig_output

    # System libraries
    LIBS += -L/usr/lib/ -lbsm
    LIBS += -framework AppKit
    LIBS += -framework Security
}
```

You'll need to include a copy of the `crashpad_handler` executable with your application. Again, be sure to copy the version of `crashpad_handler` that targets either `arm64` or `x86_64` depending on what architecture you're targeting.

Copy `crashpad_handler` to the `$$PWD/Crashpad/Bin/MacOS` directory. Add the following snippet to the `macx` section of your project file that copies the macOS `crashpad_handler` to your project's build directory.

<pre><code><strong># Crashpad rules for MacOS
</strong>macx {
    ...
    # Copy crashpad_handler to build directory
    QMAKE_POST_LINK += "mkdir -p $$OUT_PWD/crashpad"
    QMAKE_POST_LINK += "&#x26;&#x26; cp $$PWD/Crashpad/Bin/MacOS/crashpad_handler $$OUT_PWD/crashpad"
}
</code></pre>

### **Windows**

Copy `base.lib`, `common.lib`, `client.lib` and `util.lib` into `$$PWD/Crashpad/Libraries/Windows`. You'll need to link with the system library `Advapi32`. Add the following snippet to your project file to link with the aforementioned libraries:

```
# Crashpad rules for Windows
win32 {
    # Crashpad libraries
    LIBS += -L$$PWD/Crashpad/Libraries/Windows/ -lbase
    LIBS += -L$$PWD/Crashpad/Libraries/Windows/ -lcommon
    LIBS += -L$$PWD/Crashpad/Libraries/Windows/ -lclient
    LIBS += -L$$PWD/Crashpad/Libraries/Windows/ -lutil

    # System libraries
    LIBS += -lAdvapi32
}
```

Additionally, you'll need to ship a copy of the `crashpad_handler.exe` executable with your application.

Copy `crashpad_handler.exe` to the `$$PWD/Crashpad/Bin/Windows` directory. Add the following snippet to the `win32` section of your project file that copies the Windows `crashpad_handler.exe` to your project's build directory.

```
# Crashpad rules for Windows
win32 {
    ...
    # Build variables
    CONFIG(debug, debug|release) {
        EXEDIR = $$OUT_PWD\debug
    }
    CONFIG(release, debug|release) {
        EXEDIR = $$OUT_PWD\release
    }

    # Copy crashpad_handler.exe to output directory
    QMAKE_POST_LINK += "copy /y $$shell_path($$PWD)\Crashpad\Bin\Windows\crashpad_handler.exe $$shell_path($$OUT_PWD)\crashpad"
}
```

### **Linux**

Copy `libbase.a`, `libutil.a`, `libcommon.a` and `libclient.a` into `$$PWD/Crashpad/Libraries/Linux`. The order in which you specify the Crashpad libraries to link is important! `libcommon.a`, and `libclient.a` must be specified first, then `libutil.a` and finally `libbase.a`. Add the following snippet to your project file to link with the aforementioned libraries:

```
# Crashpad rules for Linux
linux {
    # Crashpad libraries
    LIBS += -L$$PWD/Crashpad/Libraries/Linux/ -lcommon
    LIBS += -L$$PWD/Crashpad/Libraries/Linux/ -lclient
    LIBS += -L$$PWD/Crashpad/Libraries/Linux/ -lutil
    LIBS += -L$$PWD/Crashpad/Libraries/Linux/ -lbase
}
```

Additionally, you'll need to ship a copy of the `crashpad_handler` executable with your application. Copy `crashpad_handler` to the `$$PWD/Crashpad/Bin/Linux` directory. Add the following snippet to the `linux` section of your project file that copies the Linux `crashpad_handler` to your project's build directory.

```
# Crashpad rules for Linux
linux {
    ...
    # Copy crashpad_handler to build directory
    QMAKE_POST_LINK += "cp $$PWD/Crashpad/Bin/Linux/crashpad_handler $$OUT_PWD/crashpad"
}
```

## Configuring Crashpad

To enable Crashpad in your application, you must configure the Crashpad handler with your BugSplat database, application name, and application version. The following is a macOS, Windows, and Linux-compatible snippet that will configure the Crashpad handler:

```cpp
#include <QApplication>
#include <vector>
#include "paths.h"
#include "client/crash_report_database.h"
#include "client/crashpad_client.h"
#include "client/settings.h"

using namespace base;
using namespace crashpad;

bool initializeCrashpad(QString dbName, QString appName, QString appVersion);
QString getExecutableDir(void);

bool initializeCrashpad(QString dbName, QString appName, QString appVersion)
{
    // Get directory where the exe lives so we can pass a full path to handler, reportsDir and metricsDir
    QString exeDir = getExecutableDir();

    // Helper class for cross-platform file systems
    Paths crashpadPaths(exeDir);

    // Ensure that crashpad_handler is shipped with your application
    FilePath handler(Paths::getPlatformString(crashpadPaths.getHandlerPath()));

    // Directory where reports will be saved. Important! Must be writable or crashpad_handler will crash.
    FilePath reportsDir(Paths::getPlatformString(crashpadPaths.getReportsPath()));

    // Directory where metrics will be saved. Important! Must be writable or crashpad_handler will crash.
    FilePath metricsDir(Paths::getPlatformString(crashpadPaths.getMetricsPath()));

    // Configure url with your BugSplat database
    QString url = "https://" + dbName + ".bugsplat.com/post/bp/crash/crashpad.php";

    // Metadata that will be posted to BugSplat
    QMap<std::string, std::string> annotations;
    annotations["format"] = "minidump";                 // Required: Crashpad setting to save crash as a minidump
    annotations["database"] = dbName.toStdString();     // Required: BugSplat database
    annotations["product"] = appName.toStdString();     // Required: BugSplat appName
    annotations["version"] = appVersion.toStdString();  // Required: BugSplat appVersion
    annotations["key"] = "Sample key";                  // Optional: BugSplat key field
    annotations["user"] = "fred@bugsplat.com";          // Optional: BugSplat user email
    annotations["list_annotations"] = "Sample comment";	// Optional: BugSplat crash description

    // Disable crashpad rate limiting so that all crashes have dmp files
    std::vector<std::string> arguments;
    arguments.push_back("--no-rate-limit");

    // Initialize crashpad database
    std::unique_ptr<CrashReportDatabase> database = CrashReportDatabase::Initialize(reportsDir);
    if (database == NULL) return false;

    // Enable automated crash uploads
    Settings *settings = database->GetSettings();
    if (settings == NULL) return false;
    settings->SetUploadsEnabled(true);

    // Attachments to be uploaded alongside the crash - default bundle size limit is 100MB
    std::vector<FilePath> attachments;
    FilePath attachment(Paths::getPlatformString(crashpadPaths.getAttachmentPath()));
    attachments.push_back(attachment);

    // Start crash handler
    CrashpadClient *client = new CrashpadClient();
    bool status = client->StartHandler(handler, reportsDir, metricsDir, url.toStdString(), annotations.toStdMap(), arguments, true, true, attachments);
    return status;
}
```

Be sure to update the values for `dbName`, `appName` and `appVersion` to values specific to your application. The `Paths` class allows you to get platform-specific paths for Crashpad; its source can be found [here](https://github.com/BugSplat-Git/myQtCrasher/blob/master/paths.cpp). To configure the paths to `crashpad_handler`, `metricsDir`, `reportsDir` and `attachment` you'll first want to find the location of your executable using the sample code below:

```cpp
#if defined(Q_OS_WIN)
    #define NOMINMAX
    #include <windows.h>
#endif

#if defined(Q_OS_MAC)
    #include <mach-o/dyld.h>
#endif

#if defined(Q_OS_LINUX)
    #include <unistd.h>
    #define MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif

QString getExecutableDir() {
#if defined(Q_OS_MAC)
    unsigned int bufferSize = 512;
    std::vector<char> buffer(bufferSize + 1);

    if(_NSGetExecutablePath(&buffer[0], &bufferSize))
    {
        buffer.resize(bufferSize);
        _NSGetExecutablePath(&buffer[0], &bufferSize);
    }

    char* lastForwardSlash = strrchr(&buffer[0], '/');
    if (lastForwardSlash == NULL) return NULL;
    *lastForwardSlash = 0;

    return &buffer[0];
#elif defined(Q_OS_WINDOWS)
    HMODULE hModule = GetModuleHandleW(NULL);
    WCHAR path[MAX_PATH];
    DWORD retVal = GetModuleFileNameW(hModule, path, MAX_PATH);
    if (retVal == 0) return NULL;

    wchar_t *lastBackslash = wcsrchr(path, '\\');
    if (lastBackslash == NULL) return NULL;
    *lastBackslash = 0;

    return QString::fromWCharArray(path);
#elif defined(Q_OS_LINUX)
    char pBuf[FILENAME_MAX];
    int len = sizeof(pBuf);
    int bytes = MIN(readlink("/proc/self/exe", pBuf, len), len - 1);
    if (bytes >= 0) {
        pBuf[bytes] = '\0';
    }

    char* lastForwardSlash = strrchr(&pBuf[0], '/');
    if (lastForwardSlash == NULL) return NULL;
    *lastForwardSlash = '\0';

    return QString::fromStdString(pBuf);
#else
    #error getExecutableDir not implemented on this platform
#endif
}
```

Add a call to `initializeCrashpad` at your application's entry point.

```cpp
int main(int argc, char *argv[]) {
    QString dbName = "Fred";
    QString appName = "myQtCrasher";
    QString appVersion = "1.0";
    initializeCrashpad(dbName, appName, appVersion);
}
```

### Symbols

{% hint style="info" %}
You can download the platform-specific symbol-upload executables on the [GitHub releases page](https://github.com/BugSplat-Git/symbol-upload/releases).
{% endhint %}

To get function names and line numbers in your crash reports, you will need to generate and upload `.sym` files to BugSplat. Crashpad `.sym` files can be generated from a macOS `.dSYM` file, a Windows `.pdb` file or a Linux `.debug` file.

To generate `.dSYM`, `.pdb` and `.debug` files add the following to the project file:

```
# Create symbols for dump_syms and symupload
CONFIG += force_debug_info
CONFIG += separate_debug_info
```

BugSplat's symbol-upload executable can generate `.sym` files as part of the symbol upload process. To generate `.sym` files from your `.dSYM`, `.pdb`, and `.debug` files, invoke symbol-upload with the `-m` flag as demonstrated in the platform-specific examples below.

### **macOS**

{% hint style="warning" %}
If you downloaded symbol-upload-macos via a web browser, you will need to [right-click and open](https://www.idownloadblog.com/2017/04/20/fix-application-from-internet-gatekeeper/#1-Right-click-to-open) the file before you can run the `symbol-upload command`.
{% endhint %}

To generate and upload `.sym` files as part of your build, create a `symbols.sh` script that calls `symbol-upload-macos`:

```bash
symbol_upload="${1}/Crashpad/Tools/MacOS/symbol-upload-macos"
database="${3}"
app="${4}"
version="${5}"
dir="${2}"
file="${4}.app.dSYM"
user="${6}"
password="${7}"

eval "${symbol_upload} -b ${database} -a \"${app}\" -v \"${version}\" -d \"${dir}\" -f \"${file}\" -u \"${user}\" -p \"${password}\" -m"
```

Call `symbols.sh` from your `QMAKE_POST_LINK` step:

```
# Crashpad rules for MacOS
macx {
    ...
    # Copy crashpad_handler, attachment.txt to build directory, and upload symbols
    QMAKE_POST_LINK += "mkdir -p $$OUT_PWD/crashpad"
    QMAKE_POST_LINK += "&& cp $$PWD/Crashpad/Bin/MacOS/crashpad_handler $$OUT_PWD/crashpad"
    QMAKE_POST_LINK += "&& bash $$PWD/Crashpad/Tools/MacOS/symbols.sh $$PWD $$OUT_PWD $$BUGSPLAT_DATABASE $$BUGSPLAT_APPLICATION $$BUGSPLAT_VERSION $$BUGSPLAT_USER $$BUGSPLAT_PASSWORD"
}
```

After each build, you must re-upload symbol files. For best results, you should increment the version number each time you release your application. The `dbName`, `appName,` and `appVersion` values from the [Configuring Crashpad](#configuring-crashpad) section must match the values set for `$$BUGSPLAT_DATABASE`, `$$BUGSPLAT_APPLICATION` , and `$$BUGSPLAT_VERSION`.

### **Windows**

To generate and upload `.sym` files as part of your build, create a `symbols.bat` script that calls `symbol-upload-windows.exe`:

```batch
%1\Crashpad\Tools\Windows\symbol-upload-windows.exe -b %3 -a "%4" -v "%5" -d "%2" -f "%4.exe" -u "%6" -p "%7" -m
```

Call `symbols.bat` from your `QMAKE_POST_LINK` step:

```bash
# Crashpad rules for Windows
win32 {
    ...
    # Copy crashpad_handler, attachment.txt to build directory, and upload symbols
    QMAKE_POST_LINK += "mkdir $$shell_path($$OUT_PWD)\crashpad"
    QMAKE_POST_LINK += "& copy /y $$shell_path($$PWD)\Crashpad\Bin\Windows\crashpad_handler.exe $$shell_path($$OUT_PWD)\crashpad\crashpad_handler.exe"
    QMAKE_POST_LINK += "&& $$shell_path($$PWD)\Crashpad\Tools\Windows\symbols.bat $$shell_path($$PWD) $$shell_path($$EXEDIR) $$BUGSPLAT_DATABASE $$BUGSPLAT_APPLICATION $$BUGSPLAT_VERSION $$BUGSPLAT_USER $$BUGSPLAT_PASSWORD"
    QMAKE_POST_LINK += "&& copy /y $$shell_path($$PWD)\Crashpad\attachment.txt $$shell_path($$OUT_PWD)\attachment.txt"
}
```

After each build, you must re-upload symbol files. For best results, you should increment the version number each time you release your application. The `dbName`, `appName,` and `appVersion` values from the [Configuring Crashpad](#configuring-crashpad) section must match the values set for `$$BUGSPLAT_DATABASE`, `$$BUGSPLAT_APPLICATION` , and `$$BUGSPLAT_VERSION`.

### **Linux**

To generate and upload `.sym` files as part of your build, create a `symbols.sh` script that calls `symbol-upload-linux`:

```bash
#!/bin/bash
symbol_upload="${1}/Crashpad/Tools/Linux/symbol-upload-linux"
database="${3}"
app="${4}"
version="${5}"
dir="${2}"
file="${4}.debug"
user="${6}"
password="${7}"

eval "${symbol_upload} -b ${database} -a \"${app}\" -v \"${version}\" -d \"${dir}\" -f \"${file}\" -u \"${user}\" -p \"${password}\" -m"
```

Call `symbols.sh` from your `QMAKE_POST_LINK` step:

<pre><code># Crashpad rules for Linux
linux {
<strong>    ...
</strong>    # Copy crashpad_handler, attachment.txt to build directory, and upload symbols
    QMAKE_POST_LINK += "mkdir -p $$OUT_PWD/crashpad &#x26;&#x26; cp $$PWD/Crashpad/Bin/Linux/crashpad_handler $$OUT_PWD/crashpad/crashpad_handler"
    QMAKE_POST_LINK += "&#x26;&#x26; $$PWD/Crashpad/Tools/Linux/symbols.sh $$PWD $$OUT_PWD $$BUGSPLAT_DATABASE $$BUGSPLAT_APPLICATION $$BUGSPLAT_VERSION $$BUGSPLAT_USER $$BUGSPLAT_PASSWORD"
    QMAKE_POST_LINK += "&#x26;&#x26; cp $$PWD/Crashpad/attachment.txt $$OUT_PWD/attachment.txt"
}
</code></pre>

After each build, you must re-upload symbol files. For best results, you should increment the version number each time you release your application. The `dbName`, `appName,` and `appVersion` values from the [Configuring Crashpad](#configuring-crashpad) section must match the values set for `$$BUGSPLAT_DATABASE`, `$$BUGSPLAT_APPLICATION` , and `$$BUGSPLAT_VERSION`.

## Generating a Crash Report

Force a crash in your application after Crashpad has been initialized:

```cpp
*(volatile int *)0 = 0;
```

After you've submitted a crash report, navigate to the [Dashboard](https://app.bugsplat.com/v2/dashboard) page. Click the link in the `ID` column to see the details of your crash report. The following image is from our sample `myQtCrasher` application:

!\[BugSplat Qt Crash]\(../../.gitbook/assets/image (1) (3) (1).png>)


# Java

### 🏗 Installation

Install `com.bugsplat` from [Maven Central](https://search.maven.org/artifact/com.bugsplat/bugsplat-java).

**Maven**

```xml
<dependency>
    <groupId>com.bugsplat</groupId>
    <artifactId>bugsplat-java</artifactId>
    <version>0.0.0</version>
</dependency>
```

**Gradle**

```kotlin
implementation("com.bugsplat:bugsplat-java:0.0.0")
```

### ⚙️ Configuration

After you've installed the SDK from Maven, add an import statement for `com.bugsplat.BugSplat`:

```java
import com.bugsplat.BugSplat;
```

Call `BugSplat.init` providing it your `database`, `application`, and `version`. It's best to do this at the entry point of your application. Several defaults can be provided to BugSplat. You can provide default values for things such as `description`, `email`, `key`, `notes`, `user` and additional file attachments.

```java
BugSplat.init("Fred", "MyJavaCrasherConsole", "1.0");
BugSplat.setDescription("Please enter a description");
BugSplat.setEmail("fred@bugsplat.com");
BugSplat.setNotes("bobby testing notes");
BugSplat.setKey("en-US");
BugSplat.setUser("Fred");
BugSplat.addAdditionalFile(new File("file.txt").getAbsolutePath());
```

For servers, console applications, or applications where you don't want to show the report dialog, call `BugSplat.setQuietMode` to prevent the BugSplat dialog from appearing.

```java
BugSplat.setQuietMode(true);
```

Wrap your application in a try/catch block and call `BugSplat.handleException` in the catch block. This will post the exception to BugSplat.

```java
try {
    throw new Exception("BugSplat rocks!");
} catch (Exception ex) {
    Bugsplat.handleException(ex);
}
```

If your application uses [threads](https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html), add a call to `BugSplat.handleException` in `uncaughtException` to post a report to BugSplat before the thread is terminated.

```java
class MyThreadGroup extends ThreadGroup {
  public MyThreadGroup (String s) {
      super(s);
  }

  public void uncaughtException(Thread thread, Throwable throwable) {
      BugSplat.handleException(new Exception(throwable));                     
  }
}
```

### 🗺️ Samples

This repo includes sample projects that demonstrate how to integrate `bugsplat-java`. Please review the [my-java-crasher](https://github.com/BugSplat-Git/bugsplat-java/tree/main/my-java-crasher) and [my-java-crasher-console](https://github.com/BugSplat-Git/bugsplat-java/tree/main/my-java-crasher-console) folders for more a sample implementation. To run the sample projects, clone this repo and open it in either [IntelliJ IDEA](https://www.jetbrains.com/idea/) or [VS Code](https://code.visualstudio.com/).

### ✅ Verification

Once you've generated an exception, navigate to the BugSplat [Dashboard](https://app.bugsplat.com/v2/dashboard) and ensure you have to correct database selected in the dropdown menu. You should see a new report under the **Recent Crashes** section:

![BugSplat Dashboard Page](https://user-images.githubusercontent.com/2646053/234051911-2bed816e-ffff-424e-8dcd-d81f678cfbfa.png)

Click the link in the **ID** column to see details about the report:

![BugSplat Crash Page](https://user-images.githubusercontent.com/2646053/234052953-465c53f2-e4c2-4190-8d5b-d6d6ec556e97.png)

That’s it! Your application is now configured to post reports to BugSplat.


# Python

### Sample

An example Python project configured with BugSplat exception reporting can be found [here](https://github.com/BugSplat-Git/my-python-crasher).

### Installation

BugSplat recommends you use [bugsplat-py](https://github.com/BugSplat-Git/bugsplat-py) with a Python [virtual environment](https://docs.python.org/3/library/venv.html). To create a virtual environment for your project please run the following command at your project's root directory:

```shell
python -m venv venv
```

Activate your virtual environment by running the following command:

```shell
# unix/macos
source venv/bin/activate

# windows
.\env\Scripts\activate
```

Install the [bugsplat](https://pypi.org/project/bugsplat) package using pip:

```bash
pip install bugsplat
```

### Usage

Import the BugSplat class

```python
from bugsplat import BugSplat
```

Create a new BugSplat instance passing it the name of your BugSplat database, application, and version

```python
bugsplat = BugSplat(database, application, version)
```

Optionally, you set default values for key, description, email, user, and additionaFilePaths

```python
bugsplat.set_default_app_key('key!')
bugsplat.set_default_description('description!')
bugsplat.set_default_email('fred@bugsplat.com')
bugsplat.set_default_user('Fred')
bugsplat.set_default_additional_file_paths([
    './path/to/additional-file.txt',
    './path/to/additional-file-2.txt'
])
```

Wrap your application code in a try/except block. In the except block call post. You can override any of the default properties that were set in step 3

```python
try:
    crash()
except Exception as e:
    bugsplat.post(
        e,
        additional_file_paths=[],
        app_key='other key!',
        description='other description!',
        email='barney@bugsplat.com',
        user='Barney'
    )
```

Once you've posted a crash, navigate to the Crashes page and click the link in the ID column to see the crash's details

!\[]\(../../.gitbook/assets/image (5).png>)

### User Feedback

In addition to crash reporting, BugSplat supports collecting non-crashing user feedback such as bug reports and feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title.

```python
bugsplat.post_feedback(
    'Login button broken',
    description='Nothing happens when I tap it',
    email='jane@example.com',
    user='Jane',
    app_key='en-US'
)
```

To include file attachments such as screenshots or log files:

```python
bugsplat.post_feedback(
    'Login button broken',
    description='Nothing happens when I tap it',
    email='jane@example.com',
    user='Jane',
    additional_file_paths=[
        './path/to/screenshot.png',
        './path/to/log.txt'
    ]
)
```

Thanks for using BugSplat ❤️


# Crashpad

## Overview ℹ️

{% hint style="warning" %}
**Want help building Crashpad?** View our [step-by-step guide](/integrations/desktop/crashpad/how-to-build-google-crashpad) to help you get started more quickly.
{% endhint %}

Crashpad is the latest open-source crash reporting tool built by Google and is the successor to the popular Breakpad crash reporter. Crashpad allows you to submit minidumps to a configured URL after a crash occurs in your product. Crashpad and Breakpad are 'wire compatible.' The crash reports created by both systems are processed similarly on our backend.

The official Crashpad documentation is available [here](https://chromium.googlesource.com/crashpad/crashpad/+/master/README.md).

Want to see a sample application integrated with Crashpad and BugSplat? Check out [bugsplat-crashpad](https://github.com/BugSplat-Git/bugsplat-crashpad)!

## Build Configuration 🏗️

The first step to integrating Crashpad is to configure your build process. BugSplat provides pre-built versions of Crashpad that are updated monthly. You can find the prebuilt libraries on the [Releases](https://github.com/BugSplat-Git/bugsplat-crashpad/releases) page in the [bugsplat-crashpad](https://github.com/BugSplat-Git/bugsplat-crashpad/releases) repo. The [bugsplat-crashpad](https://github.com/BugSplat-Git/bugsplat-crashpad) repo also includes scripts that demonstrate how to build Crashpad on [Windows](https://github.com/BugSplat-Git/bugsplat-crashpad/blob/main/scripts/build_crashpad_windows_msvc.ps1), [macOS](https://github.com/BugSplat-Git/bugsplat-crashpad/blob/main/scripts/build_crashpad_macos.sh), and [Linux](https://github.com/BugSplat-Git/bugsplat-crashpad/blob/main/scripts/build_crashpad_linux.sh) with Chromium's [Depot Tools](https://www.chromium.org/developers/how-tos/depottools/).

We also offer a detailed walkthrough that describes how to [build Crashpad from scratch](/integrations/desktop/crashpad/how-to-build-google-crashpad).

### Binaries and Libraries

To add Crashpad to your application, you'll need to link with the `client` , `common`, `util`, and `base` libraries. Additionally, on macOS, you'll need to link with the `mig_output` library. On all platforms, you'll need to copy `crashpad_handler` to your build output directory and include it in your installer so that it is available at runtime.

The following example is a snippet from [CMakeLists.txt](https://github.com/BugSplat-Git/bugsplat-crashpad/blob/main/CMakeLists.txt) for Windows - please see our [sample](https://github.com/BugSplat-Git/bugsplat-crashpad/blob/main/CMakeLists.txt) for macOS and Linux.

<pre class="language-cmake"><code class="lang-cmake"># Library vars
set(CRASHPAD_LIBRARIES
    ${CRASHPAD_OUT_DIR}/obj/client/client.lib
<strong>    ${CRASHPAD_OUT_DIR}/obj/client/common.lib
</strong>    ${CRASHPAD_OUT_DIR}/obj/util/util.lib
    ${CRASHPAD_OUT_DIR}/obj/third_party/mini_chromium/mini_chromium/base/base.lib
)

# Handler var
set(CRASHPAD_HANDLER ${CRASHPAD_OUT_DIR}/crashpad_handler.exe)

# Link crashpad libs
target_link_libraries(MyCMakeCrasher ${CRASHPAD_LIBRARIES})

# Copy handler exe
add_custom_command(TARGET MyCMakeCrasher POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy
    ${CRASHPAD_HANDLER}
    ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_CONFIG_DIR}/crashpad_handler${CMAKE_EXECUTABLE_SUFFIX}
)
</code></pre>

### Include Directories

You'll also need to add a few Crashpad directories to your app's includes list.

```cmake
# Include dirs
include_directories(
    ${CRASHPAD_ROOT}
    ${CRASHPAD_ROOT}/third_party/mini_chromium/mini_chromium
)
```

## Code Integration 🧑‍💻

The [bugsplat-crashpad](https://github.com/BugSplat-Git/bugsplat-crashpad) repo provides a [my-cmake-crasher](https://github.com/BugSplat-Git/bugsplat-crashpad/blob/main/main.cpp) sample application that demonstrates how to configure Crashpad. The following code snippets are from the [my-cmake-crasher example](https://github.com/BugSplat-Git/bugsplat-crashpad/blob/main/main.cpp).

### Includes and Namespaces

Add the following:

```cpp
#include "client/crashpad_client.h"
#include "client/crash_report_database.h"
#include "client/settings.h"

using namespace crashpad;
using namespace std;
```

### Initialization

Copy the `initializeCrashpad` and `getExecutableDir` methods from the BugSplat sample. The Crashpad `url` and parameters `format`, `database`, `product` and `version` are required to upload crash reports to BugSplat. You can optionally specify values for the parameters `user`, `list_annotations`, and `key` which will be tracked with each crash report.

The following snippet is for Windows. Please see [my-cmake-crasher](https://github.com/BugSplat-Git/bugsplat-crashpad/blob/main/main.cpp) for macOS, and Linux compatible code changes.

```cpp
// Function to initialize Crashpad with BugSplat integration
bool initializeCrashpad(std::string dbName, std::string appName, std::string appVersion) {
    using namespace crashpad;
    
    // Get the directory where the exe lives
    std::string exeDir = getExecutableDir();

    // Ensure that crashpad_handler is shipped with your application
    base::FilePath handler(base::FilePath::StringType(exeDir.begin(), exeDir.end()) + L"/crashpad_handler.exe");

    // Directory where reports and metrics will be saved
    base::FilePath reportsDir(base::FilePath::StringType(exeDir.begin(), exeDir.end()));
    base::FilePath metricsDir(base::FilePath::StringType(exeDir.begin(), exeDir.end()));

    // Configure URL with your BugSplat database
    std::string url = "https://" + dbName + ".bugsplat.com/post/bp/crash/crashpad.php";

    // Metadata that will be posted to BugSplat
    std::map<std::string, std::string> annotations;
    annotations["format"] = "minidump";              // Required: Crashpad setting to save crash as a minidump
    annotations["database"] = dbName;                // Required: BugSplat database
    annotations["product"] = appName;                // Required: BugSplat appName
    annotations["version"] = appVersion;             // Required: BugSplat appVersion
    annotations["key"] = "Sample key";               // Optional: BugSplat key field
    annotations["user"] = "fred@bugsplat.com";       // Optional: BugSplat user email
    annotations["list_annotations"] = "Sample crash from dynamic library"; // Optional: BugSplat crash description

    // Disable crashpad rate limiting
    std::vector<std::string> arguments;
    arguments.push_back("--no-rate-limit");

    // File paths of attachments to be uploaded with the minidump file at crash time
    std::vector<base::FilePath> attachments;
    base::FilePath attachment(base::FilePath::StringType(exeDir.begin(), exeDir.end()) + L"/attachment.txt");
    attachments.push_back(attachment);

    // Initialize Crashpad database
    std::unique_ptr<CrashReportDatabase> database = CrashReportDatabase::Initialize(reportsDir);
    if (database == nullptr) {
        return false;
    }

    // Enable automated crash uploads
    Settings* settings = database->GetSettings();
    if (settings == nullptr) {
        return false;
    }
    settings->SetUploadsEnabled(true);

    // Start crash handler
    CrashpadClient client;
    bool success = client.StartHandler(
        handler,
        reportsDir,
        metricsDir,
        url,
        annotations,
        arguments,
        true,  // Restartable
        true,  // Asynchronous
        attachments  // Add attachment
    );

    return success;
}

// Function to get the executable directory
std::string getExecutableDir() {
    char path[MAX_PATH];
    GetModuleFileNameA(NULL, path, MAX_PATH);
    std::string pathStr(path);
    size_t lastBackslash = pathStr.find_last_of('\\');
    if (lastBackslash != std::string::npos) {
        return pathStr.substr(0, lastBackslash);
    }
    return "";
}
```

Call `initializeCrashpad` using parameters specific to your application for `dbName`, `appName`, and `appVersion`.

```cpp
#define BUGSPLAT_DATABASE "your-database-here"
#define BUGSPLAT_APP_NAME "your-application-here"
#define BUGSPLAT_APP_VERSION "1.2.3-etc"

initializeCrashpad(BUGSPLAT_DATABASE, BUGSPLAT_APP_NAME, BUGSPLAT_APP_VERSION);
```

#### Attributes

BugSplat will parse the `annotations` fields as attributes that can be configured as searchable columns within the BugSplat web app. For more information, please refer to the [Crash Attributes documentation](/education/how-tos/using-the-crash-attribute-feature).

## Symbol Uploads 🗺️

You will need to generate and upload `.sym` files to BugSplat to generate function names and line numbers in the stack traces of your crash reports. BugSplat's [symbol-upload](https://github.com/BugSplat-Git/symbol-upload) tool can be used conveniently to generate and upload `.sym` files with a single terminal command. Download a copy of symbol-upload from [GitHub](https://github.com/BugSplat-Git/symbol-upload) or install it via [npm](https://npmjs.com/package/@bugsplat/symbol-upload).

Once you have symbol-upload downloaded or installed, modify the following command to suit your needs.

```bash
symbol-upload-windows -b "your-database-here" ^
    -a "your-application-here" ^
    -v "1.2.3-etc" ^
    -u "you@company.com" ^
    -p "*******" ^
    -d "C:\\path\\to\\build\\output" ^
    -f "*.{pdb,exe,dll}" ^
    --dumpSyms
```

## Testing 🧪

Trigger a crash in your application. The crash report should be available immediately on the BugSplat website. Click on the link in the `ID` column. If everything worked correctly, you should see something that resembles the following.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FNTTl6yV8CipmCNiL8vRO%2Fimage.png?alt=media&amp;token=2be05d29-2177-4039-abe2-4007fd5abb4e" alt=""><figcaption><p>BugSplat Crash Details Page</p></figcaption></figure>

## Additional Considerations 🤔

### Databases

The BugSplat database for your crash reports is created on the [Manage Database](https://app.bugsplat.com/v2/company/databases) page in Settings. Typically, you will create a new database for each major release of your product.

### Optimizations

Compiler optimizations can cause a mismatch between the line numbers in crash reports and the actual line numbers in your code. BugSplat recommends turning off compiler optimizations to ensure that the line numbers in your crash reports match the line numbers in your code. To turn off optimizations in Visual Studio, right-click your project and navigate to **Properties > C/C++ > Optimization > Optimization,** and set the value to **Disabled (/Od)**.


# How to Build Google Crashpad

## Overview

Crashpad is a cross-platform system for end-to-end crash reporting. Crashpad supports reporting of native crashes on a variety of operating systems including Windows, macOS, Linux, Android, and iOS. Crashpad also provides tools such as `dump_syms`, `symupload` and `minidump_stackwalk` that provide developers with function names, file names, and line numbers in their crash reports. Integrating with Crashpad helps software engineers find and fix program crashes in order to develop more stable applications.

{% embed url="<https://bugsplat.wistia.com/medias/bh4l456ydm>" %}

## Installing depot\_tools

The Chromium [depot\_tools](https://chromium.googlesource.com/chromium/tools/depot_tools.git) are a set of tools that are required to build Crashpad. Run the following terminal commands below to clone `depot_tools` and add the tools to your system `PATH` variable. Be sure to change `/path/to/depot_tools` to the path where you cloned depot\_tools.

### **macOS**

```bash
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 
sudo echo "export PATH=/path/to/depot_tools:$PATH" >> ~/.zshrc
```

### **Linux**

```
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 
sudo echo "export PATH=/path/to/depot_tools:$PATH" >> ~/.bashrc
```

### **Windows**

```bash
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
setx path "%path%;C:\path\to\depot_tools"
```

## Getting the Crashpad Source

The Crashpad source code can be found [here](https://chromium.googlesource.com/crashpad/crashpad). Crashpad’s dependencies are managed by `gclient` instead of git submodules, so it is best to use `fetch` to get the source code.

### **Initial Checkout**

```bash
mkdir ~/crashpad
cd ~/crashpad
fetch crashpad
```

### **Subsequent Checkouts**

```bash
cd ~/crashpad/crashpad
git pull -r
gclient sync
```

## Building Crashpad

Crashpad uses `gn` to generate `ninja` build files. You'll need to ensure you've installed a C++ compiler such as [MSVC](https://visualstudio.microsoft.com/), [gcc](https://gcc.gnu.org/), or [clang](https://clang.llvm.org/). For Linux, you'll also need to install `build-essential` and `libcurl4-openssl-dev` .

### **Generating Build Configuration**

```bash
cd ~/crashpad/crashpad
gn gen out/Default
```

You can supply multiple arguments to customize your build, depending on the desired target OS and processor architecture. If you omit these values, [gn](https://gn.googlesource.com/gn/+/main/docs/quick_start.md) will use values that match the current system.

For Windows, you will likely want to build Crashpad as a dynamic library. You can do this by passing `extra_cflags="/MD"` for release configurations and `extra_cflags="/MDd"` for debug configurations. Be sure to double-check that you're escaping special characters correctly, as the following command syntax can vary depending on whether you're using CMD or PowerShell.

```bash
gn gen out/Default --args="extra_cflags=\"/MD\""
```

### **Building with Ninja**

Once you've generated your build config, use [ninja](https://ninja-build.org/) to build your Crashpad configuration.

```bash
ninja -C out/Default
```

## Integrating Crashpad

The Crashpad build generates several libraries that must be specified in the arguments passed to your application's linker.

### **macOS & Linux**

At a minimum, macOS and Linux applications need to be linked with `out/Default/obj/client/libcommon.a`, `out/Default/obj/client/libclient.a`, `out/Default/obj/util/libutil.a`, and `out/Default/obj/third_party/mini_chromium/mini_chromium/base/libbase.a`.

A macOS application will need to link with `out/Default/obj/util/libmig_output.a` as well.

When building Linux applications, `libbase.a` must be the last Crashpad file specified in the build arguments, or the application will not build.

Additionally, `~/crashpad/crashpad` and `~/crashpad/crashpad/third_party/mini_chromium/mini_chromium` need to be added as include directories.

Finally, `out/Default/crashpad_handler` needs to be deployed with the application and accessible at runtime.

### **Windows**

At a minimum, Windows applications need to be linked with `out\Default\obj\client\common.lib`, `out\Default\obj\client\client.lib`, `out\Default\obj\util\util.lib`, and `out\Default\obj\third_party\mini_chromium\mini_chromium\base\base.lib.`

Finally, `out\Default\crashpad_handler.exe` needs to be deployed with the application and accessible at runtime.

## Configuring Crashpad

Add the following includes to your application's entry point.

```cpp
#include "client/crashpad_client.h"
#include "client/crash_report_database.h"
#include "client/settings.h"
```

Add a typedef for `StringType`, add using statements for the `base`, `crashpad` and `std` namespace and declare the following methods at the top of the entry point of the application.

```bash
#if defined(__APPLE__)
typedef std::string StringType;
#elif  defined(__linux__)
typedef std::string StringType;
#elif defined(_MSC_VER)
typedef std::wstring StringType;
#endif

using namespace base;
using namespace crashpad;
using namespace std;

bool initializeCrashpad(void);
StringType getExecutableDir(void);
```

Implement the `initializeCrashpad` method replacing the file paths with valid values.

```cpp
bool initializeCrashpad() {
  // Get directory where the exe lives so we can pass a full path to handler, reportsDir, metricsDir and attachments
  StringType exeDir = getExecutableDir();

  // Ensure that handler is shipped with your application
  FilePath handler(exeDir + "/path/to/crashpad_handler");

  // Directory where reports will be saved. Important! Must be writable or crashpad_handler will crash.
  FilePath reportsDir(exeDir + "/path/to/crashpad");

  // Directory where metrics will be saved. Important! Must be writable or crashpad_handler will crash.
  FilePath metricsDir(exeDir + "/path/to/crashpad");

  // Configure url with BugSplat’s public fred database. Replace 'fred' with the name of your BugSplat database.
  StringType url = "https://fred.bugsplat.com/post/bp/crash/crashpad.php";

  // Metadata that will be posted to the server with the crash report map
  map<StringType, StringType> annotations;
  annotations["format"] = "minidump";           // Required: Crashpad setting to save crash as a minidump
  annotations["database"] = "fred";             // Required: BugSplat appName
  annotations["product"] = "myCrashpadCrasher"; // Required: BugSplat appName
  annotations["version"] = "1.0.0";             // Required: BugSplat appVersion
  annotations["key"] = "Sample key";            // Optional: BugSplat key field
  annotations["user"] = "fred@bugsplat.com";    // Optional: BugSplat user email
  annotations["list_annotations"] = "Sample comment"; // Optional: BugSplat crash description

  // Disable crashpad rate limiting so that all crashes have dmp files
  vector<StringType> arguments; 
  arguments.push_back("--no-rate-limit");

  // Initialize Crashpad database
  unique_ptr<CrashReportDatabase> database = CrashReportDatabase::Initialize(reportsDir);
  if (database == NULL) return false;

  // File paths of attachments to be uploaded with the minidump file at crash time - default upload limit is 100MB
  vector<FilePath> attachments;
  FilePath attachment(exeDir + "/path/to/attachment.txt");
  attachments.push_back(attachment);

  // Enable automated crash uploads
  Settings *settings = database->GetSettings();
  if (settings == NULL) return false;
  settings->SetUploadsEnabled(true);

  // Start crash handler
  CrashpadClient *client = new CrashpadClient();
  bool status = client->StartHandler(handler, reportsDir, metricsDir, url, annotations, arguments, true, true, attachments);
  return status;
}
```

Next, implement the platform-specific `getExecutableDir` method.

### **macOS**

```cpp
#include <mach-o/dyld.h>
#include <vector>

StringType getExecutableDir() {
  unsigned int bufferSize = 512;
  vector<char> buffer(bufferSize + 1);

  if (_NSGetExecutablePath(&buffer[0], &bufferSize)) {
    buffer.resize(bufferSize);
    _NSGetExecutablePath(&buffer[0], &bufferSize);
  }

  char *lastForwardSlash = strrchr(&buffer[0], '/');
  if (lastForwardSlash == NULL) return NULL;
  *lastForwardSlash = 0;

  return &buffer[0];
}
```

### **Linux**

```cpp
#include <stdio.h>
#include <unistd.h>
#define MIN(x, y) (((x) < (y)) ? (x) : (y))

StringType getExecutableDir() {
  char pBuf[FILENAME_MAX];
  int len = sizeof(pBuf);
  int bytes = MIN(readlink("/proc/self/exe", pBuf, len), len - 1);
  if (bytes >= 0) {
    pBuf[bytes] = '\0';
  }

  char* lastForwardSlash = strrchr(&pBuf[0], '/');
  if (lastForwardSlash == NULL) return NULL;
  *lastForwardSlash = '\0';

  return pBuf;
}
```

### Windows

```cpp
StringType getExecutableDir() {
  HMODULE hModule = GetModuleHandleW(NULL);
  WCHAR path[MAX_PATH];
  DWORD retVal = GetModuleFileNameW(hModule, path, MAX_PATH);
  if (retVal == 0) return NULL;

  wchar_t *lastBackslash = wcsrchr(path, '\\');
  if (lastBackslash == NULL) return NULL;
  *lastBackslash = 0;

  return path;
}
```

Finally, call the `initializeCrashpad` method at the entry point of the application.

```cpp
int main(int argc, char *argv[]) {
  initializeCrashpad();
}
```

## Generating Symbols

Generating sym files requires the `dump_syms` tool from the repository of Crashpad’s predecessor, [Breakpad](https://chromium.googlesource.com/breakpad/breakpad/). Dump\_syms creates [sym files](https://github.com/google/breakpad/blob/master/docs/symbol_files.md) from executable binaries, which allow minidumps to be symbolicated with function names, file names, and line numbers in the call stack.

```bash
mkdir ~/breakpad
cd breakpad
fetch breakpad
```

### **macOS**

Build the application with symbolic information (preferably in a separate dSYM file) in order to get fully symbolicated crash reports.

Next, build the Xcode project located at `src/src/tools/mac/dump_syms/dump_syms.xcodeproj`. Switch the configuration to dump\_syms and build the project. The report navigator tab (icon looks like a chat bubble in Xcode 11) will show the file system location with the compiled executable. Run the dump\_syms executable.

```bash
dump_syms -g "/path/to/myApp.app.dSYM" "/path/to/myApp.app/Contents/MacOS/myApp" > myApp.sym
```

### **Linux**

Build the application with symbolic information and a build identifier. Using `clang` this means building with the `-g` and `-Wl,--build-id` arguments.

Next, run `./configure && make` in the Breakpad directory. This will generate `dump_syms`, `symupload` and `minidump_stackwalk`.

```bash
dump_syms /path/to/myApp.out > myApp.out.sym
```

### **Windows**

The `dump_syms` functionality is built into the `symupload` utility and can be skipped if the application will be symbolicated remotely. Run `dump_syms` only if the application will be symbolicated locally or the sym file will be uploaded to a remote server via some means other than `symupload`.

For `symupload.exe` to generate the correct output, applications must be built with symbolic information so that each `exe` and `dll` file generates a corresponding `pdb` file. Generated `pdb` files must contain full debug information. With Visual Studio, full debug information can be generated with the `/Zi` compiler argument and the `/DEBUG:FULL` linker argument. Failure to specify either the `/Zi` or `/DEBUG:FULL` arguments will result in dump\_syms outputting incorrect sym file data. Additionally, the output `pdb` file must be in the same folder as the corresponding `exe` or `dll` file otherwise `dump_syms.exe` will fail.

To run `symupload.exe` a copy of `msdia140.dll` must be placed in the same folder. If [Visual Studio](https://docs.microsoft.com/en-us/visualstudio/productinfo/2017-redistribution-vs#dia-sdk) is installed this file can be found at `[VisualStudioFolder]\DIA SDK\bin\amd64\msdia140.dll`. Copy `msdia140.dll` into the same folder as `symupload.exe` and run `symupload.exe`.

```bash
symupload.exe "path/to/myApp.exe" "https://fred.bugsplat.com/post/bp/symbol/breakpadsymbols.php?appName=myApp&appVer=1.0.0"
```

Dump\_syms can be built from source so that the debugger can be used for troubleshooting. To build `dump_syms` clone the [gyp repository](https://github.com/chromium/gyp) and run `python setup.py install`. Next, run `gyp ~\breakpad\src\tools\windows\dump_syms\dump_syms.gyp` and use Visual Studio to build the sln file generated by gyp. If the build fails with an error that unique\_pointer is not part of std add `#include <memory>` to the top of the file that contains the error and rebuild.

## Uploading Symbols

The `symupload` tool is also part of the [Breakpad](https://chromium.googlesource.com/breakpad/breakpad/) repository and can be used to upload sym files to your server. Symbols need to be uploaded to a server in order for it to correctly symbolicate a minidump file.

### **macOS**

Build the Xcode project located at `src/src/tools/mac/symupload/symupload.xcodeproj`. The report navigator tab (icon looks like a chat bubble in Xcode 11) will show you the file system location with the compiled executable. Copy the symupload file into your project and run the executable wrapping the arguments to symupload in quotes.

```bash
symupload "/path/to/myApp.sym" "https://fred.bugsplat.com/post/bp/symbol/breakpadsymbols.php?appName=myApp&appVer=1.0.0"
```

### **Windows**

To use `symupload` , applications must be built with symbolic information so that each `exe` and `dll` file generates a corresponding `pdb` file. Generated `pdb` files must contain full debug information. Full debug information can be generated with the `/Zi` compiler argument and the `/DEBUG:FULL` linker argument. Failure to specify either the `/Zi` or `/DEBUG:FULL` arguments will result in `symupload` failing. The output `pdb` file must be in the same folder as the corresponding `exe` or `dll` file.

To run `symupload.exe` a copy of `msdia140.dll` must be placed in the same folder. If [Visual Studio](https://docs.microsoft.com/en-us/visualstudio/productinfo/2017-redistribution-vs#dia-sdk) is installed, this file can be found at `[VisualStudioFolder]\DIA SDK\bin\amd64\msdia140.dll`. Copy msdia140.dll into the same folder as symupload.exe and run symupload.exe.

```bash
symupload.exe "/path/to/myApp.exe" "https://fred.bugsplat.com/post/bp/symbol/breakpadsymbols.php?appName=myApp&appVer=1.0.0"
```

Symupload can be built from source so that the debugger can be used for troubleshooting. To build `symupload` clone the [gyp repository](https://github.com/chromium/gyp) and run `python setup.py install`. Next, run `gyp ~\breakpad\src\tools\windows\symupload\symupload.gyp` and use Visual Studio to build the sln file generated by `gyp`. If the build fails with an error that unique\_pointer is not part of std add `#include <memory>` to the top of the file that contains the error and rebuild.

## Symbolicating Crash Reports

`Minidump_stackwalk` is another tool in the [Breakpad](https://chromium.googlesource.com/breakpad/breakpad/) repository that is responsible for the symbolication of minidump files. In order to correctly symbolicate minidumps, sym files need to be nested at least 2 folders deep. The topmost parent folder’s name must equal the sym files module name. The first child folder’s name must equal the module id. Additionally, the sym file name must also match the module name. The module id and module name can be found in the [module record](https://github.com/google/breakpad/blob/master/docs/symbol_files.md#module-records) of the sym file.

For example the module `myApp` with the module id `1A67F3DEAACA3B209D9992871B2620AA0` must be located at `/path/to/symbols/myApp/1A67F3DEAACA3B209D9992871B2620AA0/myApp.sym`.

### **macOS & Linux**

Minidump\_stackwalk is built when building [Breakpad](https://chromium.googlesource.com/breakpad/breakpad#getting-started-from-master).

```
cd ~/breakpad/src && ./configure && make
```

### **Windows**

Minidump\_stackwalk can be built on Windows with the help of [MinGW-w64](https://www.mingw-w64.org/) and [TDM-GCC](https://jmeubank.github.io/tdm-gcc/). First, download and install [TDM-GCC](https://jmeubank.github.io/tdm-gcc/download/). Next, open a MINGw64 shell, such as [Git Bash](https://gitforwindows.org/).

```bash
cd ~/breakpad/src && ./configure --disable-dependency-tracking && make
```

If make doesn't work, try removing all instances of `/usr/bin` from `Makefile`.

Run `minidump_stackwalk` passing it a path to a `.dmp` file and a symbols directory. The folders in the symbols directory need to be laid out following the pattern `module_name/module_id/module_name.sym`:

```
minidump_stackwalk -m "/path/to/minidump.dmp" "/path/to/symbols"
```

Additionally, minidumps generated by the Crashpad library can also be symbolicated via [Debugging Tools](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/) for Windows given the `.exe`, `.dll` and `.pdb` files are made available to WinDBG.

## Troubleshooting

Most issues symbolicating dump files can be traced back to mismatched module ids. Anything that modifies a given executable (code-signing, anti-cheat) must be performed before `dump_syms` and `symupload` are run. Every time an executable is modified `dump_syms` and `symupload` need to be re-run. The name and id of the module loaded at runtime can be found in the `minidump_stackwalk` output. The module name and id must match the module name and id of the generated sym file in order for `minidump_stackwalk` to correctly symbolicate the minidump file.

## References

1. <https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up>
2. <https://chromium.googlesource.com/crashpad/crashpad/+/HEAD/doc/developing.md>
3. <https://groups.google.com/a/chromium.org/forum/#!topic/crashpad-dev/XVggc7kvlNs>
4. <https://docs.bugsplat.com/introduction/getting-started/integrations/desktop/crashpad>
5. <https://github.com/google/breakpad/blob/master/docs/getting_started_with_breakpad.md#build-process-specificssymbol-generation>
6. <https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/getting_started_with_breakpad.md#build-process-specifics_symbol-generation>
7. <https://www.chromium.org/developers/decoding-crash-dumps>


# Breakpad (Deprecated)

{% hint style="danger" %}
**Breakpad is the predecessor of Crashpad**. If you are configuring a new integration, please consider using our [Crashpad integration](/integrations/desktop/crashpad) instead.
{% endhint %}

## Overview

Breakpad is the predecessor of Crashpad. If you are configuring a new integration, please consider using our [Crashpad integration](/integrations/desktop/crashpad) instead.

Google Breakpad is a crash reporting tool built by Google in C++. It allows you to submit minidumps to a configured URL as a crash happens. With Breakpad you can process crashes for [Windows](https://github.com/google/breakpad/blob/master/docs/windows_client_integration.md), [macOS](https://github.com/google/breakpad/blob/master/docs/mac_breakpad_starter_guide.md), and [Linux](https://github.com/google/breakpad/blob/master/docs/linux_starter_guide.md) applications.

In a few simple steps, your Breakpad-enabled application can be configured to send crash reports to BugSplat, allowing you to take advantage of BugSplat's reporting mechanisms.

For more information, see Google's Integration Overview [here](https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/getting_started_with_breakpad.md).

## Prerequisites

Before continuing with the integration, please complete the following tasks:

* Create a new [database](https://app.bugsplat.com/v2/company) for your application
* Clone the [source](https://chromium.googlesource.com/breakpad/breakpad/)
* Build the exception\_handler and crash\_report\_sender libraries and integrate them into your application
* Build the dump\_syms and symupload tools

## Configuration

Configure Breakpad to post crashes to `https://{database}.bugsplat.com/post/bp/crash/postBP.php`. Be sure to specify your value for the {database} portion of the URL, which corresponds to the BugSplat database used to store your crash reports.

```cpp
bool minidumpCallback(
  const wchar_t* dump_path,
  const wchar_t* minidump_id,
  void* context,
  EXCEPTION_POINTERS* exinfo,
  MDRawAssertionInfo* assertion,
  bool succeeded
)
{
  ...
  wstring bugSplatUrl = L"https://" + database + L".bugsplat.com/post/bp/crash/postBP.php";
  ReportResult reportResult = reportSender->SendCrashReport(bugSplatUrl, parameters, files, &exceptionCode);
}
```

Configure the Breakpad POST parameters `prod` for the BugSplat application name and `ver` for the BugSplat application version. You can optionally specify values for the POST parameters `email` and `comments`, which will be tracked with each crash report. Also, configure the `files` parameter as shown below.

```cpp
bool minidumpCallback(
  const wchar_t* dump_path,
  const wchar_t* minidump_id,
  void* context,
  EXCEPTION_POINTERS* exinfo,
  MDRawAssertionInfo* assertion,
  bool succeeded
)
{
  ...
  map<wstring, wstring> parameters;
  parameters[L"prod"] = L"MyApp";
  parameters[L"ver"] = L"1.0";
  parameters[L"email"] = L"fred@bugsplat.com";
  parameters[L"comments"] = L"BugSplat rocks!";
  files[L"upload_file_minidump"] = dump_path;
  ReportResult reportResult = reportSender->SendCrashReport(bugSplatUrl, parameters, files, &exceptionCode);
}
```

Create a new symbol store on our [Versions](https://app.bugsplat.com/v2/versions) page. You should do this for each released product version to ensure your crash reports contain function names and line numbers.

Trigger a crash in your application. The following code snippet can be used to generate an EXCEPTION\_ACCESS\_VIOLATION\_WRITE crash:

```cpp
int nullVal;
void crash()
{
  *(volatile int *)0 = nullVal;
}
```

### Uploading Breakpad Symbols

Upload your application's symbol files to BugSplat for symbolic call stack information. For more information on how to upload symbols manually, please see this [article](/guides/working-with-symbol-files/how-to-manually-upload-symbols). Alternatively, you can use symupload to automate the symbol upload process. Run the following symupload command replacing `{database}`, `{appName}` and `{appVersion}` with values specific to your BugSplat database and symbol store:

```bash
symupload <file.exe|file.dll> "https://{database}.bugsplat.com/post/bp/symbol/breakpadsymbols.php?appName={appName}&appVer={appVersion}"
```

Breakpad symbol uploads for platforms other than Windows (e.g., Linux, Mac) require an additional step. First, run the Breakpad utility dump\_syms to create .sym files from your local executable files. Then, use symupload to upload the .sym files to BugSplat.

Operating system symbol files can be uploaded in a similar manner. You may be able to find symbolic debug files for your operating system. If these are available when dump\_syms is run, your OS call stack functions will be fully symbolicated.

### Additional Considerations

Crashes can be posted manually using our test page at `https://{database}.bugsplat.com/post/bp/crash/Native/index.php`. Replace `{database}` with the name of your BugSplat database. Viewing the source HTML of that page may help with the configuration.

The BugSplat database for your crash reports is created on the [Manage Database](https://app.bugsplat.com/v2/company/databases) page in Settings. Typically, you will create a new database for each major product release.


# Game Development

Game engines are some of the largest and most complicated codebases that developers encounter in their careers. Your team needs BugSplat to reduce the cost and confusion of navigating large codebases in search of crashes. BugSplat is easy to integrate in your platform of choice and will drastically reduce the headaches caused by chasing user-reported crashes.

### Game Engines

{% content-ref url="/pages/-MeRRqdyM5mZrayEhLE7" %}
[CRYENGINE](/integrations/game-development/cryengine)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRb\_iN4crnhEGfpddL" %}
[Unreal Engine](/integrations/game-development/unreal-engine)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRabISGEaEIYX-2bh1" %}
[Unity](/integrations/game-development/unity)
{% endcontent-ref %}

{% content-ref url="/pages/Sbyy7zDZXEG5wG9jYxq3" %}
[Custom Engine Support](/integrations/game-development/custom-engine-support)
{% endcontent-ref %}

### Game Consoles

{% content-ref url="/pages/ZnWLNLy0AyDiQbxLdk9N" %}
[Nintendo Switch 2](/integrations/game-development/nintendo)
{% endcontent-ref %}

{% content-ref url="/pages/-MeReB0FS\_eQY9U1p5\_s" %}
[PlayStation](/integrations/game-development/playstation)
{% endcontent-ref %}

{% content-ref url="/pages/-Me\_zyP-AToH5unoiDJg" %}
[Xbox](/integrations/game-development/xbox)
{% endcontent-ref %}

{% hint style="info" %}
**Not finding what you're looking for?** Please reach out to <support@bugsplat.com> to request the language or environment you'd like BugSplat to integrate with next!
{% endhint %}


# CRYENGINE

## Building CRYENGINE

To get function names and line numbers for internal CRYENGINE code you'll need to build CRYENGINE from source and generate `.pdb` files. Make sure to build the engine with the `Profile` configuration so that `.pdb` files are generated. The following video gives an overview of how to clone and build the CRYENGINE [source](https://www.cryengine.com/docs/static/engines/cryengine-5/categories/23756813/pages/89457345):

Next, upload all of the `.pdb`, `.dll` and `.exe` files in the `bin` folder using [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload). Make sure to note the application name, version and database as you'll need these values later.

### Project Configuration

To point the CRYENGINE crash reporter at BugSplat you'll need to make a few modifications to the `.cryproject` file for your project. Open the `.cryproject` file in a text editor and add the following snippet of JSON:

```javascript
{
    ...
    "console_variables": {
        "sys_crashrpt": "1",
        "sys_crashrpt_appname": "{{application}}",
        "sys_crashrpt_appversion": "{{version}}",
        "sys_crashrpt_email": "support@bugsplat.com",
        "sys_crashrpt_privacypolicy": "https://bugsplat.com/privacy",
        "sys_crashrpt_server": "http://{{database}}.bugsplat.com/post/cryengine/index.php",
        "sys_target_platforms": "pc,ps4,xboxone,linux"
    },
    ...
}
```

Make sure to replace `{{application}}`, `{{version}}`, and `{{database}}` with values specific to your game. Note these values must match the values you used when you uploaded symbols for CRYENGINE.

### Building Your Game

By default, building your game should output `.pdb` files so that minidumps can be debugged by a remote machine. If your build does not output `.pdb` files, you will need to change the [MSVC flags](https://www.cryengine.com/docs/static/engines/cryengine-5/categories/23756816/pages/56658046) with `CMAKE` and regenerate the solution.

### Uploading Symbols

Symbol files are required to display function names, file names and line numbers of source code in crash reports. Once you've built your project's solution, upload the resulting files in `bin` using [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload).

### Generating a Crash Report

Right-click the `.cryproject` file for your game and select `Launch Game`. Once the game has launched, press the `` ` (backtick) `` key on your keyboard to display the console. Type `?crash` to ensure that all of the variables from the `Project Configuration` step have been loaded by your game.

To generate a crash report, enter `sys_crashrpt_generate` into the console:

![BugSplat CRYENGINE crash dialog](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2Fsync%2F7127469b75a6d8c756500261fe55c7504e454c81.png?generation=1631116988517199\&alt=media)

### Viewing the Crash Report

After you've submitted a crash report, navigate to the [Dashboard](https://app.bugsplat.com/v2/dashboard) page. Click the link in the `ID` column to see the details of your crash report. In this case, the last 4 stack frames are all related to the crash report generator, and the frame of interest is the 5th frame of the call stack. Create a [Group](/guides/grouping-crashes) by expanding the 5th row in the `Active Thread` and then click the `Create Subkey` button.

Navigate back to the crash and notice that the Stack Key is now `CrySystem!CXConsole::ExecuteCommand(2427)` instead of `CrySystem!CCrashHandler::GetExceptionPointers(1566)`.

![BugSplat CRYENGINE crash details](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2Fsync%2F3c7b6cd20a7255020528336b2978fcc1632ca01a.png?generation=1631116987665886\&alt=media)


# Nintendo Switch 2

BugSplat enables developers to automatically track crashes in Nintendo Switch 2 games during development and production.

Access to BugSplat’s Nintendo Switch 2 support is available exclusively to certified Nintendo developers. To get started, follow these steps:

1. **Verify Your Developer Status**\
   Log in to your Nintendo Developer account at <https://developer.nintendo.com/>, and navigate to the **Switch > Middleware** section.\
   Locate **BugSplat** and complete the required authorization process. This step ensures that BugSplat can verify your certification as a Nintendo developer.
2. **Access Tools and Documentation**\
   Once your status is confirmed by Nintendo, you can download the SDK and find comprehensive instructions by navigating to the Gaming Consoles tab on the [Database Integrations](https://app.bugsplat.com/v2/database/integrations) page, under the Nintendo (CRPORTAL) section. From there, you can also manage which Nintendo applications sync with BugSplat; crashes are synced automatically on an hourly basis.

If you have questions or need assistance, reach out to **<support@bugsplat.com>**.


# PlayStation

Process PS4 and PS5 crash reports with BugSplat. Available for certified PlayStation developers, our SDK enhances game stability

BugSplat allows developers to efficiently process crash reports from PlayStation consoles, including PS4 and PS5, for both development and production projects.

### Accessing the SDK

Access to the BugSplat SDK is limited to certified PlayStation developers. If you are a registered PlayStation developer, you can request access to the SDK by clicking here → <https://p.siedev.net/tm/verify/bugsplat>.

\
Once access is granted, you can download the SDK and find comprehensive instructions by navigating to the Gaming Consoles tab on the [Database Integrations](https://app.bugsplat.com/v2/database/integrations) page.

\
For more information about PlayStation crash reporting with BugSplat, please contact us via email at <support@bugsplat.com>.


# Unreal Engine

{% hint style="info" %}
If you are a developer looking to try BugSplat on your local machine, we've created a [Plugin](/integrations/game-development/unreal-engine/unreal-engine-plugin) to help you get started.
{% endhint %}

BugSplat’s Unreal Engine integration supports capturing crashes, errors, and user feedback in Windows, macOS, Linux, iOS, Android, Xbox, PlayStation and Switch 2 games. BugSplat also supports both Windows and Linux servers.

There are two options for configuring BugSplat. If you are integrating BugSplat for an organization that uses a dedicated build machine, please continue reading.

## Windows 🪟

You must upload symbol and executable files to create symbolic call stacks on Windows platforms. The easiest way to upload files is to use our [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload) command line utility. You can download `symbol-upload` [here](https://github.com/BugSplat-Git/symbol-upload/releases).

### Symbol Uploads

Add a step to your build pipeline that uploads `.exe`, `.dll`, and `.pdb` files via [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload). We recommend creating an [OAuth Client ID/Client Secret](/api-reference/oauth2#client-credentials) pair for authentication.

```bash
cd {your build folder}
symbol-upload-windows.exe -i {client id} -s {client secret} -b {database} -a {appName} -v {appVersion} -f "**/*.{pdb,exe,dll}"
```

The `appName` and `appVersion` parameters will be associated with your uploaded symbols, allowing logical grouping of files within BugSplat for easier symbol management. BugSplat will automatically remove symbol stores that have not been accessed recently. See [Managing Symbol Storage](/guides/working-with-symbol-files/managing-symbol-storage#automatic-symbol-cleanup) for a description of these rules.

### Packaging Settings

Package your game, and check the **Include Crash Reporter** and **Include Debug Files** options are selected in your build configuration:

![Integrating Unreal with BugSplat](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2Fsync%2F760cd017c7d2063d986ece8bd599540b59057461.png?generation=1631116601540894\&alt=media)

![UE4\_PackagingSetttings](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2Fsync%2Fd1df279ebe1de3dd30897eb7d538b1d833355146.png?generation=1631116602141682\&alt=media)

If you're building via the command line, please add the `-CrashReporter` flag to your build arguments to ensure CrashReportClient is included in your build output.

### Configuring Crash Report Client

Sending crash reports to BugSplat can be done via a simple configuration change to Unreal Engine's [CrashReportClient](https://blog.bugsplat.com/customizing-the-unreal-engine-crash-report-client/).

There are two options for configuring CrashReportClient. The first option is modifying the `DefaultEngine.ini` file for an engine install or source build. Modifying the engine's config file is the easiest approach but has the downside of affecting every game you build with this version. Alternatively, you can add `DefaultEngine.ini` to a specific path in your packaged build directory, which will overwrite values specified by the engine.

#### Option 1: Editor and Engine Crashes

Unreal Editor can also be configured to send crash reports to BugSplat. To do this, add the following DefaultEngine.ini file in `C:\Path\To\Engine_Install_or_Source_Checkout\Programs\CrashReportClient\Config\DefaultEngine.ini.`

```
[CrashReportClient]
CrashReportClientVersion=1.0
DataRouterUrl="https://{database}.bugsplat.com/post/ue4/{appName}/{appVersion}"
```

#### Option 2: Packaged Builds

To configure crash uploads to your BugSplat database, create a file named `DefaultEngine.ini` with the following contents:

```
[CrashReportClient]
CrashReportClientVersion=1.0
DataRouterUrl="https://{database}.bugsplat.com/post/ue4/{appName}/{appVersion}"
```

Replace `{database}`, `{appName}`, and `{appVersion}` with the names of your BugSplat database, application name, and version. The appName and appVersion parameters will be assigned to each crash report posted to your database, allowing you to group and filter crashes within BugSplat. These parameters should match the corresponding values used for SendPdbs.

{% hint style="warning" %}
**Be sure to URL encode spaces and special characters in {appName} or {appVersion}**
{% endhint %}

#### Unreal Engine 4.25 and older

For capturing crashes in packaged games in Unreal Engine 4.25 and earlier, copy `DefaultEngine.ini` to `{{output directory}}\Engine\Programs\CrashReportClient\Config\NoRedist` making sure to create folders that don't exist (where`{{output directory}}` is the location of your packaged build).

#### **Unreal Engine 4.26 and newer**

For capturing crashes in packaged games in Unreal Engine 4.26 and newer, copy`DefaultEngine.ini` to `{{output directory}}\Engine\Restricted\NoRedist\Programs\CrashReportClient\Config` making sure to create folders that don't exist (where`{{output directory}}` is the location of your packaged build).

If `DefaultEngine.ini` already exists, add the snippet above anywhere in the file. There are multiple `DefaultEngine.ini` files in your tree. Ensure you edit the right DefaultEngine.ini file; otherwise, crash reports will not be sent to BugSplat.

### Timeouts

When a user submits a crash report, it can take a considerable amount of time to upload, depending on the size of the crashing application, the contents of the crash report, and the user's network connection. Sometimes, the crash upload can fail because Unreal Engine's default HTTP timeout is 30 seconds. You can check if you're experiencing this issue by reviewing the Error page.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FTeIiW4MxbCnEaHYI6rBj%2Fimage.png?alt=media&amp;token=2c32b9ba-d038-478d-be0a-414212205034" alt="Unreal upload size mismatch error"><figcaption></figcaption></figure>

The simplest way to fix this issue is to add the following to `[Your Game]/Config/DefaultEngine.ini`:

```ini
[HTTP]
HttpConnectionTimeout=90
HttpActivityTimeout=90
HttpTotalTimeout=90
```

Alternatively, you can change the upload timeout for the crash upload without affecting the rest of the engine by modifying [CrashUpload.cpp](https://github.com/EpicGames/UnrealEngine/blob/803688920e030c9a86c3659ac986030fba963833/Engine/Source/Runtime/CrashReportCore/Private/CrashUpload.cpp#L815-L825).

```diff
auto Request = CreateHttpRequest();
Request->SetVerb(TEXT("POST"));
Request->SetHeader(TEXT("Content-Type"), TEXT("application/octet-stream"));
Request->SetURL(DataRouterUrl + UrlParams);
+ Request->SetTimeout(90.0f);
Request->SetContent(CompressedData.Data);
```

### Trigger a Crash

Run your game. For testing, a crash can be forced from the console using the command "debug crash". After posting the crash report, log in to BugSplat to view the report.

### Optional: Customize Crash Report Client

The default CrashReportClient contains text explaining to the user that the crash reports are being sent to Epic. However, by overwriting the CrashReportClient configuration settings, crash reports are instead sent to BugSplat. It is a good idea to change the text and rebuild CrashReportClient. Customizing CrashReportClient requires rebuilding the engine source.

Please see our [blog](https://blog.bugsplat.com/customizing-the-unreal-engine-crash-report-client/) for more information on how to [customize Unreal's CrashReportClient](https://blog.bugsplat.com/customizing-the-unreal-engine-crash-report-client/).

## Linux Servers 🐧

Special instructions for Linux servers:

* Package the crash reporter with your Linux server build by adding the `-CrashReporter` flag to `PackageBuildLinuxServer.bat`
* Force a test crash by running your server executable with the option `-ExecCmds="debug crash"`

Symbolic call stacks are resolved if you deploy symbols on your server. This is the typical case. However, if symbols aren't available locally, upload the Unreal Linux custom symbol files (`.psym` extension) using [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload).

## iOS 🍎

You will need to configure [bugsplat-ios](/integrations/mobile/ios) to capture iOS crash reports. Additionally, you'll need to upload `.dSYM` files for function names and line numbers to be included in crash reports. Symbol files can be uploaded automatically by invoking [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload). The BugSplat Unreal plugin also reports fatal main-thread hangs on iOS. See the plugin's [Hang Detection](/integrations/game-development/unreal-engine/unreal-engine-plugin#hang-detection-ios-and-android) section for details.

## Android 🤖

You will need to configure [Crashpad](/integrations/mobile/android) to capture Android crash reports. Additionally, you'll need to generate symbol files from your `.so` files for function names and line numbers to be included in crash reports. Symbol files can be generated and uploaded automatically by invoking [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload) with the `-m` flag. Application Not Responding (ANR) events are reported automatically on Android 11+. See the plugin's [Hang Detection](/integrations/game-development/unreal-engine/unreal-engine-plugin#hang-detection-ios-and-android) section for details.

## Xbox, PlayStation, and Nintendo Switch 2 🎮

BugSplat can provide instructions for implementing Unreal crash reporting on Xbox, PlayStation, and Nintendo Switch 2. Please email us at <support@bugsplat.com> for more info.

## Check, Verify, and Ensure Reporting ✅

Unreal Engine's `check`, `verify`, and `ensure` macros can all send crash reports to BugSplat. Checks and Verifies report automatically since they terminate the application. Ensures require additional configuration: in Shipping builds, you'll need to set `bUseChecksInShipping = true` in your `*.Target.cs` file to keep them active.

For the complete guide on configuring ensure reporting, controlling report volume, and troubleshooting, see [Unreal Assert, Check, and Ensure Reporting](/integrations/game-development/unreal-engine/unreal-assert-check-and-ensure-reporting).

## Custom Fields 📝

BugSplat extracts metadata from the `CrashContext.runtime-xml` file attached to Unreal Engine crash reports and convert those values into [Attributes](/education/how-tos/using-the-crash-attribute-feature) that can be displayed in the web application. See the [Unreal Engine Crash Reporting documentation](https://dev.epicgames.com/documentation/en-us/unreal-engine/crash-reporting-in-unreal-engine) for information on adding additional data.

The following XML fields, if created as child properties of `RuntimeProperties` or `GameData` can be used to set the specified BugSplat crash fields.

<table><thead><tr><th width="374">Property</th><th>Description</th></tr></thead><tbody><tr><td>BugSplatApplicationKey</td><td>Sets the value of the crash Key field</td></tr><tr><td>BugSplatDescription</td><td>Sets the value of the crash Description field</td></tr><tr><td>BugSplatNotes</td><td>Sets the value of the crash Notes field</td></tr><tr><td>UserEmail</td><td>Sets the value of the crash Email field</td></tr><tr><td>UserName</td><td>Sets the value of the crash User field. The UserID URL parameter will take precedence if it is set.</td></tr></tbody></table>

The BugSplat properties are [reserved attribute names](/education/how-tos/using-the-crash-attribute-feature#reserved-attribute-names) that work from any platform that sends attributes, not just Unreal's CrashContext XML. All other properties will be parsed as [Attributes](/education/how-tos/using-the-crash-attribute-feature).

<pre class="language-cpp"><code class="lang-cpp">#include "MyUnrealCrasherGameModeBase.h"
#include "GenericPlatform/GenericPlatformCrashContext.h"

AMyUnrealCrasherGameModeBase::AMyUnrealCrasherGameModeBase()
{
<strong>    // BugSplat override fields for overriding values on the Crash Details page
</strong>    FGenericCrashContext::SetGameData(TEXT("BugSplatApplicationKey"), TEXT("en-US"));
    FGenericCrashContext::SetGameData(TEXT("BugSplatDescription"), TEXT("Crashed while loading level 2"));
    FGenericCrashContext::SetGameData(TEXT("BugSplatNotes"), TEXT("Development Build"));
    FGenericCrashContext::SetGameData(TEXT("UserEmail"), TEXT("fred@bugsplat.com"));
    FGenericCrashContext::SetGameData(TEXT("UserName"), TEXT("wonderfulmuffin27"));

    // GameData values will be parsed as Attributes by BugSplat
    FGenericCrashContext::SetGameData(TEXT("CurrentWorld"), TEXT("Alpha Centari"));
    FGenericCrashContext::SetGameData(TEXT("GamePads"), TEXT("1"));
    FGenericCrashContext::SetGameData(TEXT("IsExternalQABuild"), TEXT("true"));
}
</code></pre>

## User Feedback 💬

In addition to crash reporting, BugSplat supports collecting non-crashing user feedback such as bug reports and feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title. For more information about how to add user feedback to your game please refer to the [BugSplat Unreal Plugin](/integrations/game-development/unreal-engine/unreal-engine-plugin#user-feedback) documentation.

## Support Response 🆘

BugSplat can display a custom support message to your end users immediately after a crash is submitted. You can append a `BugSplatApplicationKey` query parameter to your `DataRouterUrl` to control which message is shown, making it possible to deliver localized responses to your players using a [customized CrashReportClient](https://blog.bugsplat.com/customizing-the-unreal-engine-crash-report-client/).

```ini
DataRouterUrl="https://{database}.bugsplat.com/post/ue4/{appName}/{appVersion}?BugSplatApplicationKey=en-US"
```

Additionally, you can speed up the time it takes for BugSplat to return a response by including a `PCallStackHash` value.

```ini
DataRouterUrl="https://{database}.bugsplat.com/post/ue4/{appName}/{appVersion}?BugSplatApplicationKey=en-US&PCallStackHash=BDC1CA7AD7CB73BC100C41E5AA322C243521BD59"
```

For a full walkthrough, see [Bringing Custom Crash Responses to Unreal Engine](https://blog.bugsplat.com/bringing-custom-crash-responses-to-unreal-engine/).

## Licensee Builds 🤝

Some forks of Unreal (e.g., Oculus) are set up as a "Licensee" build. Regardless of other settings, crash reports won't be sent because of this [block of code](https://github.com/EpicGames/UnrealEngine/blob/5ccd1d8b91c944d275d04395a037636837de2c56/Engine/Source/Runtime/Core/Private/Unix/UnixPlatformCrashContext.cpp#L594-L600):

```cpp
if (BuildSettings::IsLicenseeVersion() && !UD_EDITOR)
{
    // do not send unattended reports in licensees' builds except for the editor, where it is governed
    bSendUnattendedBugReports = false;
    bAgreeToCrashUpload = false;
    bSendUsageData = false;
}
```

To upload crash reports to BugSplat, recompile with `bSendUnattendedBugReports = true`.


# Unreal Engine Plugin

{% hint style="danger" %}
The symbol-upload step in this plugin is designed for developer evaluation only! Do not release builds with Client ID and Client Secret in DefaultEngine.ini. Instead, configure an explicit [symbol-upload](https://github.com/BugSplat-Git/symbol-upload) step as part of your production build pipeline.
{% endhint %}

### 🏗 Installation

You may choose to add BugSplat through the Unreal Marketplace or add the plugin to your Unreal project manually.

#### Install from Marketplace

[Install BugSplat from the Unreal Marketplace](https://www.unrealengine.com/marketplace/en-US/product/bugsplat)

#### Install Manually

1. Navigate to your project folder containing your `[ProjectName].uproject` file.
2. Create a `Plugins` folder if it does not already exist.
3. Create a `BugSplat` folder in the `Plugins` folder and copy the contents of this repo into the `BugSplat` folder.
4. In the Unreal Editor, ensure you can access the BugSplat plugin via `Edit > Project Settings` and scroll to the `BugSplat` section under `Plugins`.

### ⚙️ Configuration

BugSplat's Unreal plugin currently supports adding crash reporting to Windows, macOS, Linux, Android, and iOS games. With a few clicks, the BugSplat plugin can be configured to automatically upload symbol files so crash report stack traces display function names and line numbers.

To get started, generate a Client ID and Client Secret via the [Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page.

Next, open the BugSplat plugin menu in the Unreal Editor via `Edit > Project Settings`. Scroll to the `BugSplat` section of `Project Settings` and add values for `Database`, `Application`, `Version`, `Client ID`, and `Client Secret`:

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FVKcgXPR7YVVr530oZau2%2Fimage.png?alt=media&amp;token=c0486848-c041-4039-b39c-5e7bc57597be" alt=""><figcaption></figcaption></figure>

#### Windows, macOS, and Linux

BugSplat leverages Unreal's `CrashReportClient` to provide crash reporting for Windows, macOS, and Linux games. Be sure to update your project settings and enable `Include Crash Reporter` and `Include Debug Files in Shipping Builds`:

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2F3CWEqO18ZRam6t3BpRsw%2Fimage.png?alt=media&amp;token=3a230ae3-7f8f-4648-8def-0b629af4bc72" alt=""><figcaption></figcaption></figure>

To configure `CrashReportClient` to post to BugSplat, the `DataRouterUrl` value needs to be added to `DefaultEngine.ini`. The `bugsplat-unreal` plugin automatically updates the value for `DataRouterUrl` when the `Update Engine DataRouterUrl` option is enabled. Please note the `DataRouterUrl` value is global and is shared across all packaged builds created by the affected engine. To override the `DataRouterUrl` value a package build uses, you may optionally use the `Update Packaged Game INI` button under the `Tools` section.

In order to get function names and line numbers in crash reports, you'll need to upload your game's `.exe`, `.dll`, and `.pdb` files. To upload debug symbols for each build, ensure that the `Enable Automatic Symbol Uploads` option is selected. When selected, a script to execute [symbol-upload](https://github.com/BugSplat-Git/symbol-upload) will be added to the `PostBuildSteps` field in `BugSplat.uplugin`. The symbol upload script will run automatically when your game is built.

**macOS**

To create a `.dSYM` file for a macOS build invoke `RunUAT.command` with the `-EnableDSym` flag per the example below:

```
../../../Engine/Build/BatchFiles/Mac/Build.sh -Project="../../my-unreal-crasher/MyUnrealCrasher.uproject" MyUnrealCrasher Mac Development -NoEditor -EnableDSym -TargetPath="~/Desktop/UnrealEngine"
```

#### iOS and Android

Before attempting to use the BugSplat plugin to capture crashes on Mobile, please ensure you've completed the [iOS](https://docs.unrealengine.com/5.0/en-US/setting-up-an-unreal-engine-project-for-ios/) and [Android](https://docs.unrealengine.com/5.0/en-US/android-support-for-unreal-engine/) quickstart guides.

To enable crash reporting, ensure the `Enable iOS Crash Reporting` and `Enable Android Crash Reporting` options are selected. Also, ensure that `Enable Automatic Symbol Uploads` is checked so that your crash reports contain function names and line numbers.

**iOS**

{% hint style="warning" %}
The Unreal iOS project's build process includes a `Build Phase called Generate dSYM for archive, and strip`, which executes after the Unreal PostBuildSteps. However, this Build Phase must complete before the `dSYM` file (debug symbols) is generated. Due to this timing, BugSplat cannot upload the `dSYM` immediately during the initial build. Instead, BugSplat will upload the `dSYM` during the next incremental build in Xcode. Alternatively, you can follow the [example](https://github.com/BugSplat-Git/bugsplat-apple/blob/main/Symbol_Upload_Examples/Build-Phase-symbol-upload.sh) in our bugsplat-apple repo to configure a custom Build Phase for symbol uploads.
{% endhint %}

To get function names and line numbers in your iOS crash reports, please make the following changes in the `iOS` section of `Project Settings`.

| Option                                                 | Value |
| ------------------------------------------------------ | ----- |
| Generate dSYMs for code debugging and profiling        | true  |
| Generate dSYMs as a bundle for third-party crash tools | true  |
| Support bitcode in shipping                            | false |

Note that sometimes iOS applications won't crash while the USB cable is connected. If this happens, disconnect the USB cable and re-run the application to trigger a crash.

**Android**

{% hint style="warning" %}
Code is aggressively optimized when building for Android. Oftentimes, Unreal's build process optimizes away code that generates simple errors used in testing. To test a null pointer dereference, you can add the `volatile` keyword to work around compiler optimizations.
{% endhint %}

Fatal Errors on Android raise a `SIGTRAP` and require extra configuration so that they can be reported to BugSplat.

<details>

<summary>Click to reveal Android Error Output Device code</summary>

[MyUnrealCrasherErrorOutputDevice.h](https://github.com/BugSplat-Git/my-unreal-crasher/blob/b0a805505a661d6729657bcae724e64dea31484b/Source/MyUnrealCrasher/MyUnrealCrasherAndroidErrorOutputDevice.h)

```cpp
#pragma once

#include "CoreMinimal.h"
#include "Misc/OutputDeviceError.h"

#if PLATFORM_ANDROID
class FMyUnrealCrasherAndroidErrorOutputDevice : public FOutputDeviceError
{
public:
	virtual ~FMyUnrealCrasherAndroidErrorOutputDevice() {}
	
	virtual void Serialize(const TCHAR* V, ELogVerbosity::Type Verbosity, const FName& Category) override;
	virtual void HandleError() override;
	
	static FOutputDeviceError* GetErrorOutputDevice();
	
private:
	void RequestExit(bool Force, const TCHAR* CallSite);
};
#endif
```

[MyUnrealCrasherErrorOutputDevice.cpp](https://github.com/BugSplat-Git/my-unreal-crasher/blob/b0a805505a661d6729657bcae724e64dea31484b/Source/MyUnrealCrasher/MyUnrealCrasherAndroidErrorOutputDevice.cpp)

```cpp
#include "MyUnrealCrasherAndroidErrorOutputDevice.h"

#include "CoreMinimal.h"
#include "CoreGlobals.h"
#include "Misc/OutputDevice.h"
#include "Misc/OutputDeviceHelper.h"
#include "Misc/App.h"
#include "Misc/CoreDelegates.h"
#include "Misc/FeedbackContext.h"
#include "HAL/PlatformMisc.h"
#include "HAL/PlatformCrt.h"

#if PLATFORM_ANDROID
#include "Android/AndroidPlatform.h" // For LogAndroid

FOutputDeviceError* FMyUnrealCrasherAndroidErrorOutputDevice::GetErrorOutputDevice()
{
	static FMyUnrealCrasherAndroidErrorOutputDevice ErrorOutputDevice;
	return &ErrorOutputDevice;
}

void FMyUnrealCrasherAndroidErrorOutputDevice::Serialize( const TCHAR* Msg, ELogVerbosity::Type Verbosity, const class FName& Category )
{
	FPlatformMisc::LowLevelOutputDebugString(*FOutputDeviceHelper::FormatLogLine(Verbosity, Category, Msg, GPrintLogTimes));

	static int32 CallCount = 0;
	int32 NewCallCount = FPlatformAtomics::InterlockedIncrement(&CallCount);
	if(GIsCriticalError == 0 && NewCallCount == 1)
	{
		// First appError.
		GIsCriticalError = 1;

		FCString::Strncpy(GErrorExceptionDescription, Msg, UE_ARRAY_COUNT(GErrorExceptionDescription));
	}
	else
	{
		UE_LOG(LogAndroid, Error, TEXT("Error reentered: %s"), Msg);
	}

	if (GIsGuarded)
	{
		UE_DEBUG_BREAK();
	}
	else
	{
		HandleError();
		RequestExit(true, TEXT("MyUnrealCrasherAndroidErrorOutputDevice::Serialize.!GIsGuarded"));
	}
}

void FMyUnrealCrasherAndroidErrorOutputDevice::HandleError()
{
	static int32 CallCount = 0;
	int32 NewCallCount = FPlatformAtomics::InterlockedIncrement(&CallCount);

	if (NewCallCount != 1)
	{
		UE_LOG(LogAndroid, Error, TEXT("HandleError re-entered."));
		return;
	}
	
	GIsGuarded = 0;
	GIsRunning = 0;
	GIsCriticalError = 1;
	GLogConsole = NULL;
	GErrorHist[UE_ARRAY_COUNT(GErrorHist) - 1] = 0;

	// Dump the error and flush the log.
#if !NO_LOGGING
	FDebug::LogFormattedMessageWithCallstack(LogAndroid.GetCategoryName(), __FILE__, __LINE__, TEXT("=== Critical error: ==="), GErrorHist, ELogVerbosity::Error);
#endif
	
	GLog->Panic();

	FCoreDelegates::OnHandleSystemError.Broadcast();
	FCoreDelegates::OnShutdownAfterError.Broadcast();
}


void FMyUnrealCrasherAndroidErrorOutputDevice::RequestExit( bool Force, const TCHAR* CallSite)
{

#if PLATFORM_COMPILER_OPTIMIZATION_PG_PROFILING
	// Write the PGO profiling file on a clean shutdown.
	extern void PGO_WriteFile();
	if (!GIsCriticalError)
	{
		PGO_WriteFile();
		// exit now to avoid a possible second PGO write when AndroidMain exits.
		Force = true;
	}
#endif

	UE_LOG(LogAndroid, Log, TEXT("FMyUnrealCrasherAndroidErrorOutputDevice::RequestExit(%i, %s)"), Force,
		CallSite ? CallSite : TEXT("<NoCallSiteInfo>"));
	if (GLog)
	{
		GLog->Flush();
	}

	if (Force)
	{
		abort(); // Abort to trigger a crash report
	}
	else
	{
		RequestEngineExit(TEXT("Android RequestExitWithCrashReporting")); // Called regardless in our version to set up the crash context
	}
}
#endif
```

[MyUnrealCrasherGameInstance.h](https://github.com/BugSplat-Git/my-unreal-crasher/blob/b0a805505a661d6729657bcae724e64dea31484b/Source/MyUnrealCrasher/MyUnrealCrasherGameInstance.h)

```cpp
#pragma once

#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "MyUnrealCrasherGameInstance.generated.h"

UCLASS()
class MYUNREALCRASHER_API UMyUnrealCrasherGameInstance : public UGameInstance
{
	GENERATED_BODY()

public:
	virtual void Init() override;
};
```

[MyUnrealCrasherGameInstance.cpp](https://github.com/BugSplat-Git/my-unreal-crasher/blob/b0a805505a661d6729657bcae724e64dea31484b/Source/MyUnrealCrasher/MyUnrealCrasherGameInstance.cpp)

```cpp
//  Copyright © BugSplat. All rights reserved.
#include "MyUnrealCrasherGameInstance.h"
#include "MyUnrealCrasherAndroidErrorOutputDevice.h"

#if PLATFORM_ANDROID
#include <android/log.h>
#endif

void UMyUnrealCrasherGameInstance::Init()
{
	Super::Init();
	UE_LOG(LogTemp, Log, TEXT("MyUnrealCrasherGameInstance::Init - Setting custom error output device"));

#if PLATFORM_ANDROID
	GError = FMyUnrealCrasherAndroidErrorOutputDevice::GetErrorOutputDevice();
#endif
}
```

</details>

**Setting Attributes (iOS and Android)**

The BugSplat plugin automatically adds several attributes from the crash context at initialization time. These attributes are not updated automatically after initialization. If you'd like to update them or add new ones, use the `SetAttribute` and `RemoveAttribute` functions.

To call `SetAttribute` from C++, add `BugSplatRuntime` to your module's `PrivateDependencyModuleNames` in your `.Build.cs` file:

```csharp
PrivateDependencyModuleNames.AddRange(new string[] { "BugSplatRuntime" });
```

Then include the header and call `SetAttribute`:

```cpp
#include "BugSplatAttributes.h"

UBugSplatAttributes::SetAttribute(TEXT("userId"), TEXT("12345"));
```

`SetAttribute` is also available as a Blueprint node under the BugSplat category.

**Hang Detection (iOS and Android)**

The BugSplat plugin reports fatal hangs on both mobile platforms: Application Not Responding (ANR) on Android and main-thread hangs on iOS. Reports appear alongside crashes in the BugSplat dashboard and upload on the launch *after* the hang.

On Android, detection is automatic once `Enable Android Crash Reporting` is checked. It uses the [`ApplicationExitInfo`](https://developer.android.com/reference/android/app/ApplicationExitInfo) API and requires Android 11+ (API 30+); on older versions it is silently a no-op. See the [Android ANR Detection](/integrations/mobile/android#anr-detection) docs for SDK-level detail.

On iOS, the plugin enables `enableHangDetection` with a `hangDetectionThreshold` of `2.0` seconds during init. No app code is required beyond having `Enable iOS Crash Reporting` checked. Only fatal hangs (watchdog kill or force-quit) are reported; hangs where the main thread eventually resumes are discarded. See the [iOS Hang Detection](/integrations/mobile/ios#hang-detection) docs for the underlying behavior and configuration knobs.

{% hint style="info" %}
iOS hang detection is suppressed while a debugger is attached. To verify on-device, detach the debugger and launch the app from the home screen before triggering a hang.
{% endhint %}

To trigger a test hang from Blueprint or C++, the plugin exposes:

```cpp
// Blueprint-callable. On Android, blocks the main thread via BugSplat.hang();
// on iOS, sleeps the main thread until the OS watchdog terminates the app.
// On desktop, logs a warning and is a no-op.
UFUNCTION(BlueprintCallable, Category = "BugSplat")
static void GenerateHang();

// BlueprintPure platform checks. Use IsMobile to gate UI to Android + iOS.
UFUNCTION(BlueprintPure, Category = "BugSplat")
static bool IsAndroid();

UFUNCTION(BlueprintPure, Category = "BugSplat")
static bool IsIOS();

UFUNCTION(BlueprintPure, Category = "BugSplat")
static bool IsMobile();
```

A typical demo wiring binds a button's `OnClicked` to `GenerateHang` and its `Visibility` to a function returning `Visible` when `IsMobile` is true and `Collapsed` otherwise. After a hang, relaunch the app once. The report uploads in the background on init.

#### Xbox, PlayStation, and Nintendo Switch 2

BugSplat can provide instructions for implementing Unreal crash reporting on Xbox, PlayStation, and Nintendo Switch 2. Please email us at <support@bugsplat.com> for more info.

### 🏃 Usage

Once you've installed the plugin, add the following C++ snippet to your game to generate a sample crash.

```cpp
UE_LOG(LogTemp, Fatal, TEXT("BugSplat!"));
```

Run your application and submit a crash report.

On Desktops, submit a crash report via the Unreal CrashReportClient dialog that appears at crash time. We have developed a handy guide on how you can customize the Unreal CrashReportClient dialog that is available [here](https://blog.bugsplat.com/customizing-the-unreal-engine-crash-report-client/).

On iOS, after a crash occurs, restart the game and tap the `Send Report` option when prompted. On Android, crashes are submitted automatically at crash time.

Once you've submitted a crash report, navigate to the [Crashes](https://app.bugsplat.com/v2/crashes) page. On the Crashes page, click the link in the ID column.

If everything is configured correctly, you should see something that resembles the following:

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FqIyPuDUwEnY2V6kOmvdF%2Fimage.png?alt=media&amp;token=97e7ba71-e084-4846-8704-2bd9daaaaf2d" alt=""><figcaption></figcaption></figure>

### 💬 User Feedback

In addition to crash reporting, BugSplat supports collecting non-crashing user feedback such as bug reports and feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title.

The BugSplat Unreal plugin provides two ways to collect user feedback:

#### Built-in Feedback Dialog

The plugin includes a ready-to-use feedback dialog. To add it to your game:

1. Open any Widget Blueprint (e.g., your HUD or main menu).
2. Add a **Button** widget and position it where you'd like the feedback trigger to appear.
3. In the button's **Events** section, click the **+** next to **On Clicked**.
4. In the Event Graph, search for **Show Feedback Dialog** (under the BugSplat category) and connect it to the On Clicked event.

The dialog includes a subject field, optional description, and an "Include application logs" checkbox that attaches the Unreal Engine log file. Crash context attributes (engine version, platform, CPU, GPU, memory, OS) are included automatically with every submission.

#### Custom Feedback UI

If you'd prefer to build your own feedback UI, call `UBugSplatFeedback::PostFeedback` directly. It reads Database, Application, and Version from your plugin settings and handles the HTTP submission, crash context attributes, and file attachments.

#### C++

```cpp
#include "BugSplatFeedback.h"

// Simple feedback
UBugSplatFeedback::PostFeedback(
    TEXT("Login button broken"),           // Title (required)
    TEXT("Nothing happens when I tap it"), // Description
    TArray<FString>(),                     // Attachments
    TEXT(""),                              // User
    TEXT(""),                              // Email
    TEXT(""),                              // AppKey
    TMap<FString, FString>()               // CustomAttributes
);
```

To include file attachments, user info, and custom attributes:

```cpp
#include "BugSplatFeedback.h"

TArray<FString> Attachments;
Attachments.Add(UBugSplatFeedback::GetLogFilePath());
Attachments.Add(FPaths::ProjectSavedDir() / TEXT("screenshot.png"));

TMap<FString, FString> CustomAttributes;
CustomAttributes.Add(TEXT("Level"), TEXT("Tutorial_03"));
CustomAttributes.Add(TEXT("PlaytimeMinutes"), TEXT("42"));

UBugSplatFeedback::PostFeedback(
    TEXT("Login button broken"),        // Title (required)
    TEXT("Nothing happens when I tap"), // Description
    Attachments,                        // File paths
    TEXT("Jane"),                        // User
    TEXT("jane@example.com"),           // Email
    TEXT(""),                            // AppKey
    CustomAttributes                    // Merged with crash context attributes
);
```

The full `PostFeedback` signature:

| Parameter          | Required | Description                                           |
| ------------------ | -------- | ----------------------------------------------------- |
| `Title`            | Yes      | Brief summary of the feedback (becomes the stack key) |
| `Description`      | No       | Additional details                                    |
| `Attachments`      | No       | Array of absolute file paths to attach                |
| `User`             | No       | Username of the person submitting                     |
| `Email`            | No       | Email of the person submitting                        |
| `AppKey`           | No       | Application key                                       |
| `CustomAttributes` | No       | Key-value pairs merged with crash context attributes  |

#### Handling completion (C++)

For C++ callers that need to handle success or failure (e.g., to update your own UI), use `PostFeedbackWithCallback`:

```cpp
UBugSplatFeedback::PostFeedbackWithCallback(
    TEXT("My title"), TEXT("Details"), Attachments,
    TEXT(""), TEXT(""), TEXT(""), TMap<FString, FString>(),
    FBugSplatFeedbackComplete::CreateLambda([](bool bSuccess, int32 HttpStatusCode)
    {
        if (bSuccess) { /* show success */ }
        else { /* show error */ }
    })
);
```

#### Blueprints

Call the **Post Feedback** node from `BugSplatFeedback`. The advanced parameters (User, Email, AppKey, CustomAttributes) are collapsed by default. Expand the node to access them. Use the **Get Log File Path** node to get the path to the current Unreal Engine log file.

For the full API, see [`BugSplatFeedback.h`](https://github.com/BugSplat-Git/bugsplat-unreal/blob/main/Source/BugSplatRuntime/Public/BugSplatFeedback.h). The built-in dialog in [`BugSplatFeedbackDialog.cpp`](https://github.com/BugSplat-Git/bugsplat-unreal/blob/main/Source/BugSplatRuntime/Private/BugSplatFeedbackDialog.cpp) serves as a reference implementation.

### 🧑‍💻 Contributing

BugSplat ❤️s open source! If you feel that this package can be improved, please open an [Issue](https://github.com/BugSplat-Git/bugsplat-unreal/issues). If you have an awesome new feature you'd like to implement, we'd love to merge your [Pull Request](https://github.com/BugSplat-Git/bugsplat-unreal/pulls). You can also send us an [email](mailto:support@bugsplat.com), join us on [Discord](https://discord.gg/K4KjjRV5ve), or message us via the in-app chat on [bugsplat.com](https://bugsplat.com/).


# Unreal Assert, Check, and Ensure Reporting

This guide explains how to configure Unreal Engine's assertion system to send crash reports to BugSplat for `check`, `verify`, and `ensure` failures.

## Overview

Unreal Engine has three types of assertions:

| Type                                | Terminates App | Use Case                                             |
| ----------------------------------- | -------------- | ---------------------------------------------------- |
| `check` / `checkf` / `verify`       | Yes            | Fatal errors that should never happen                |
| `ensure` / `ensureMsgf`             | No             | Non-fatal errors worth investigating                 |
| `ensureAlways` / `ensureAlwaysMsgf` | No             | Non-fatal errors that should report every occurrence |

**Checks** always send crash reports when they fire (since they terminate the application). **Ensures** require additional configuration to send reports, which is the focus of this guide.

## How Ensure Reporting Works

There are two layers that control ensure crash reporting: **compile-time** and **runtime**.

Compile-time: In Debug and Development builds, ensures are always compiled in (`DO_ENSURE=1`). In Test and Shipping builds, ensures are compiled out by default. They just evaluate the expression and return the result with no logging or reporting. To keep ensures active in Shipping, set `bUseChecksInShipping = true` in your `*.Target.cs` file (this also enables `USE_ENSURES_IN_SHIPPING` since it follows the check setting by default).

Runtime: Once ensures are compiled in, the CVar `core.EnsuresAreErrors` (default `1`) controls whether they actually send crash reports. When set to `1`, ensure failures log as errors and submit reports; when set to `0`, they log as warnings only and skip reporting entirely. You can set this via INI (`[SystemSettings]` section) or console command. There's also `core.EnsureAlwaysEnabled` (default `true`) which controls whether `ensureAlways` fires every time or just once per callsite like regular `ensure`. Finally, the `-nocrashreports` command-line flag disables all report submission regardless of other settings.

In short: For ensures to send crash reports to BugSplat, you need `DO_ENSURE=1` (automatic in Dev builds, requires `bUseChecksInShipping` in Shipping) AND `core.EnsuresAreErrors=1` (the default) AND no `-nocrashreports` flag.

## Configuration by Build Type

### Development Builds (Default - No Changes Needed)

Ensures are compiled in and report by default. Just ensure your `DefaultEngine.ini` has BugSplat configured:

```ini
[CrashReportClient]
CrashReportClientVersion=1.0
DataRouterUrl="https://{database}.bugsplat.com/post/ue4/{appName}/{appVersion}"
```

### Shipping Builds (Requires Target.cs Change)

To receive ensure reports from Shipping builds, modify your game's `*.Target.cs`:

```csharp
public class MyGameTarget : TargetRules
{
    public MyGameTarget(TargetInfo Target) : base(Target)
    {
        Type = TargetType.Game;
        DefaultBuildSettings = BuildSettingsVersion.Latest;

        // Enable checks and ensures in Shipping builds
        bUseChecksInShipping = true;
    }
}
```

This sets `USE_CHECKS_IN_SHIPPING=1` and `USE_ENSURES_IN_SHIPPING=1`, keeping assertion macros active in packaged builds.

## INI Configuration Reference

### DefaultEngine.ini

```ini
[CrashReportClient]
; BugSplat endpoint (required)
DataRouterUrl="https://{database}.bugsplat.com/post/ue4/{appName}/{appVersion}"
CrashReportClientVersion=1.0

; Auto-send crashes without showing UI (recommended for packaged games)
bImplicitSend=true
bAgreeToCrashUpload=true

; Include log file in crash reports
bSendLogFile=true

; Whether to create minidumps for ensures (default: true)
Ensure.RecordDump=true

[Core.System]
; Percentage of ensures to handle (0-100). Use to reduce volume in production.
; Default: 100 (handle all ensures)
HandleEnsurePercent=100

[SystemSettings]
; Whether ensures send crash reports (1) or just log warnings (0)
; Default: 1
core.EnsuresAreErrors=1

; Whether ensureAlways fires every time (true) or once per callsite (false)
; Default: true
core.EnsureAlwaysEnabled=true

[HTTP]
; Increase timeouts for large crash uploads
HttpConnectionTimeout=90
HttpActivityTimeout=90
HttpTotalTimeout=90
```

### Reducing Ensure Volume in Production

If ensures are generating too many reports, you have several options:

Option: Throttle ensures by percentage

```ini
[Core.System]
HandleEnsurePercent=25
```

Option: Disable ensure reporting entirely (keeps logging)

```ini
[SystemSettings]
core.EnsuresAreErrors=0
```

Option: Convert ensureAlways to first-failure-only

```ini
[SystemSettings]
core.EnsureAlwaysEnabled=false
```

## Command-Line Options

| Flag                     | Effect                                                         |
| ------------------------ | -------------------------------------------------------------- |
| `-nocrashreports`        | Disables all crash report submission                           |
| `-handleensurepercent=N` | Override HandleEnsurePercent (e.g., `-handleensurepercent=50`) |
| `-CrashReporter`         | Include crash reporter when packaging (required for reports)   |

## Quick Reference: What Gets Reported?

| Build Config | Checks Report? | Ensures Report? | Notes                                |
| ------------ | -------------- | --------------- | ------------------------------------ |
| Debug        | Yes            | Yes             | All assertions active                |
| Development  | Yes            | Yes             | All assertions active                |
| Test         | No\*           | No\*            | \*Unless `bUseChecksInShipping=true` |
| Shipping     | No\*           | No\*            | \*Unless `bUseChecksInShipping=true` |

With `bUseChecksInShipping=true` in your Target.cs, Test and Shipping builds behave like Development for assertion reporting.

## Verifying Your Configuration

{% stepper %}
{% step %}

### Add a test ensure to your code

```cpp
ensure(false && "BugSplat test ensure");
```

{% endstep %}

{% step %}

### Run your packaged build

{% endstep %}

{% step %}

### Check your BugSplat dashboard for the incoming report

{% endstep %}

{% step %}

### Remove the test ensure once confirmed

{% endstep %}
{% endstepper %}

## Troubleshooting

<details>

<summary>Ensures not appearing in BugSplat</summary>

* Verify `bUseChecksInShipping=true` is set in your Target.cs (for Shipping builds)
* Check that `core.EnsuresAreErrors` is not set to `0`
* Confirm `-nocrashreports` is not on the command line
* Ensure `DataRouterUrl` is correctly configured

</details>

<details>

<summary>Too many ensure reports</summary>

* Use `HandleEnsurePercent` to throttle
* Set `core.EnsureAlwaysEnabled=false` to reduce `ensureAlways` spam
* Consider fixing the underlying issues causing ensures

</details>

<details>

<summary>Reports timing out</summary>

* Increase HTTP timeouts in `[HTTP]` section
* Check network connectivity to BugSplat servers

</details>


# Unity

### 🏗 Installation

BugSplat's `com.bugsplat.unity` package can be added to your project via [OpenUPM](https://openupm.com/packages/com.bugsplat.unity/) or a URL to our git [repository](https://github.com/BugSplat-Git/bugsplat-unity.git).

#### OpenUPM

Information on installing OpenUPM can be found [here](https://openupm.com/). After installing OpenUPM, run the following command to add BugSplat to your project.

```
openupm add com.bugsplat.unity
```

#### Git

Information on adding a Unity package via a git URL can be found [here](https://docs.unity3d.com/Manual/upm-ui-giturl.html).

```
https://github.com/BugSplat-Git/bugsplat-unity.git
```

### 🧑‍🏫 Sample

{% hint style="success" %}
BugSplat recommends building with the IL2CPP backend for the best crash reporting experience. For more information, please see the [Player Settings](https://github.com/BugSPlat-Git/bugsplat-unity#-player-settings) section.
{% endhint %}

After installing `com.bugsplat.unity`, you can import a sample project to help you get started with BugSplat. Click here if you'd like to skip the sample project and get straight to the [usage](https://github.com/BugSPlat-Git/bugsplat-unity#usage) instructions.

To import the sample, click the caret next to **Samples** to reveal the **my-unity-crasher** sample. Click **Import** to add the sample to your project.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FgPV9zDnZ2WG44qoHz1OB%2Fimage.png?alt=media&amp;token=ebd8d3ac-f8df-46f6-8718-6067beb8d85b" alt=""><figcaption></figcaption></figure>

In the Project Assets browser, open the **Sample** scene from `Samples > BugSplat > Version > my-unity-crasher > Scenes`.

Next, select `Samples > BugSplat > Version > my-unity-crasher` to reveal the **BugSplatOptions** object. Click BugSplatOptions and replace the database value with your BugSplat database.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FUROfQDDh7GWRJxEbEUiA%2Fimage.png?alt=media&amp;token=7b9b44a3-e943-46d4-a715-5c6cc0a9c029" alt=""><figcaption></figcaption></figure>

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2F0H3iJ2DzKmun8niXyF8L%2Fimage.png?alt=media&amp;token=3d4bde16-ee9b-49ac-b6c3-b66ec404735f" alt=""><figcaption></figcaption></figure>

Click **Play** and click or tap one of the buttons to send an error report to BugSplat. To view the error report, navigate to the BugSplat [Dashboard](https://app.bugsplat.com/v2/dashboard) and ensure you have selected the correct database.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FeSujiFcB92vRKXshFvgn%2Fimage.png?alt=media&amp;token=2d1270cc-cb00-444d-991f-93b837f956fc" alt=""><figcaption></figcaption></figure>

Navigate to the [Crashes](https://app.bugsplat.com/v2/crashes) page, and click the value in the ID column to see the details of your report, including the call stack, log file, and screenshot of your app when the error occurred.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FRFu3A8izpHFHcB6ZFtnC%2Fimage.png?alt=media&amp;token=940b1797-2ba3-40f1-8bc2-3703f6604d42" alt=""><figcaption></figcaption></figure>

### 🧰 Player Settings

For best results, BugSplat recommends building with the `IL2CPP` backend. The `Mono` backend is supported, but has several limitations. With `IL2CPP`, BugSplat can capture fully symbolicated C# exception traces in production, as well as native crashes that contain call stacks mapped back to their original C# function names, file names, and line numbers.

To optimize your game for crash reporting, open `Player Settings` (`Edit > Player Settings`). Navigate to the `Configuration` section. For `Scripting Backend` choose `IL2CPP` and for `IL2CPP StackTrace Information` choose `Method Name, File Name, and Line Number`.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fr5vGRPt864PHqV7jGvSY%2Fimage.png?alt=media&amp;token=235f6dca-ac44-48ab-aeaf-56b6a51ccb89" alt=""><figcaption></figcaption></figure>

### ⚙️ Configuration

BugSplat's Unity integration is flexible and can be used in various ways. The easiest way to get started is to attach the `BugSplatManager` Monobehaviour to a GameObject.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FTs8CMComJDdo4UhyDUS9%2Fimage.png?alt=media&amp;token=9c5d8da1-bd8d-46dc-acb4-73dfd57ed8d5" alt=""><figcaption></figcaption></figure>

`BugSplatManager` needs to be initialized with a `BugSplatOptions` serialized object. A new instance of `BugSplatOptions` can be created through the Asset Create menu.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fj4kT59v4vlz3yasEsSig%2Fimage.png?alt=media&amp;token=88b10867-28f0-4f5b-998d-d20f19936ecb" alt=""><figcaption></figcaption></figure>

Configure fields as appropriate. Note that if Application or Version are left empty, `BugSplat` will default these values to `Application.productName` and `Application.version`, respectively.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FNmCJcsFdSop8MtsnjJZ4%2Fimage.png?alt=media&amp;token=4b578317-4e32-4fac-a685-f2b8de097ae6" alt=""><figcaption></figcaption></figure>

Finally, provide a valid `BugSplatOptions` to `BugSplatManager`.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FuSm7X7rMRymfrVbxsz67%2Fimage.png?alt=media&amp;token=d3cc8c42-14ff-4b1d-b2a1-31551f78f077" alt=""><figcaption></figcaption></figure>

### ⌨️ Usage

If you're using `BugSplatOptions` and `BugSplatManager`, BugSplat automatically configures an `Application.logMessageReceived` handler that will post reports when it encounters a log message of type `Exception`. You can also extend your BugSplat integration and [customize report metadata](https://github.com/BugSPlat-Git/bugsplat-unity#adding-metadata), [report exceptions in try/catch blocks](https://github.com/BugSPlat-Git/bugsplat-unity#trycatch-reporting), [prevent repeated reports](https://github.com/BugSPlat-Git/bugsplat-unity#preventing-repeated-reports), and [upload windows minidumps](https://github.com/BugSPlat-Git/bugsplat-unity#windows) from native crashes.

#### Adding Metadata

First, find your instance of `BugSplat`. The following is an example of how to find an instance of `BugSplat` via `BugSplatManager`:

```csharp
var bugsplat = FindObjectOfType<BugSplatManager>().BugSplat;
```

You can extend `BugSplat` by setting the following properties:

```csharp
bugsplat.Attachments.Add(new FileInfo("/path/to/attachment.txt"));
bugsplat.Description = "description!";
bugsplat.Email = "fred@bugsplat.com";
bugsplat.Key = "key!";
bugsplat.Notes = "notes!";
bugsplat.User = "Fred";
bugsplat.CaptureEditorLog = true;
bugsplat.CapturePlayerLog = false;
bugsplat.CaptureScreenshots = true;
```

You can use the `Notes` field to capture arbitrary data such as system information:

```csharp
void Start()
{
    bugsplat = FindObjectOfType<BugSplatManager>().BugSplat;
    bugsplat.Notes = GetSystemInfo();
}

private string GetSystemInfo()
{
    var info = new Dictionary<string, string>();
    info.Add("OS", SystemInfo.operatingSystem);
    info.Add("CPU", SystemInfo.processorType);
    info.Add("MEMORY", $"{SystemInfo.systemMemorySize} MB");
    info.Add("GPU", SystemInfo.graphicsDeviceName);
    info.Add("GPU MEMORY", $"{SystemInfo.graphicsMemorySize} MB");

    var sections = info.Select(section => $"{section.Key}: {section.Value}");
    return string.Join(Environment.NewLine, sections);
}
```

#### Try/Catch Reporting

Exceptions can be sent to BugSplat in a try/catch block by calling `Post`.

```csharp
try
{
    throw new Exception("BugSplat rocks!");
}
catch (Exception ex)
{
    StartCoroutine(bugsplat.Post(ex));
}
```

The default values specified on the instance of `BugSplat` can be overridden in the call to `Post`. Additionally, you can provide a `callback` to `Post` that will be invoked with the result once the upload is complete.

```csharp
var options = new ReportPostOptions()
{
    Description = "a new description",
    Email = "barney@bugsplat.com",
    Key = "a new key!",
    Notes = "some new notes!",
    User = "Barney"
};

options.AdditionalAttachments.Add(new FileInfo("/path/to/additional.txt"));

static void callback()
{
    Debug.Log($"Exception post callback!");
};

StartCoroutine(bugsplat.Post(ex, options, callback));
```

#### Preventing Repeated Reports

By default, BugSplat prevents reports from being sent at a rate greater than 1 per every 3 seconds. You can override the default crash report throttling implementation by setting `ShouldPostException` on your BugSplat instance. To override `ShouldPostException`, assign the property a new `Func<Exception, bool>` value. Be sure your new implementation can handle a null value for `Exception`!

The following example demonstrates how you could implement your own time-based report throttling mechanism:

```csharp
var lastPost = new DateTime(0);

bugsplat.ShouldPostException = (ex) =>
{
    var now = DateTime.Now;

    if (now - lastPost < TimeSpan.FromSeconds(3))
    {
        Debug.LogWarning("ShouldPostException returns false. Skipping BugSplat report...");
        return false;
    }

    Debug.Log("ShouldPostException returns true. Posting BugSplat report...");
    lastPost = now;

    return true;
};
```

#### Windows Minidumps (Crashes)

BugSplat can be configured to upload Windows minidumps created by the `UnityCrashHandler`. BugSplat will automatically pull Unity Player symbols from the [Unity Symbol Server](https://docs.unity3d.com/Manual/WindowsDebugging.html).

The methods `PostCrash`, `PostMostRecentCrash`, and `PostAllCrashes` can be used to upload minidumps to BugSplat. We recommend running `PostAllCrashes` when your game launches.

```csharp
void Start()
{
    bugsplat = FindObjectOfType<BugSplatManager>().BugSplat;
    StartCoroutine(bugsplat.PostAllCrashes());
}
```

Each of the methods that post crashes to BugSplat also accepts a `MinidumpPostOptions` parameter and a `callback`. The usage of `MinidumpPostOptions` and `callback` are nearly identical to the `ExceptionPostOptions` example listed above.

You can generate a test crash on Windows with any of the following methods.

```
Utils.ForceCrash(ForcedCrashCategory.Abort);
Utils.ForceCrash(ForcedCrashCategory.AccessViolation);
Utils.ForceCrash(ForcedCrashCategory.FatalError);
Utils.ForceCrash(ForcedCrashCategory.PureVirtualFunction);
```

#### Windows Symbols

To enable the uploading of plugin symbols, generate an OAuth2 Client ID and Client Secret on the BugSplat [Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page. Add your Client ID and Client Secret to the `BugSplatOptions` object you generated in the [Configuration](https://github.com/BugSPlat-Git/bugsplat-unity#%E2%9A%99%EF%B8%8F-configuration) section. Alternatively, you can set the `BUGSPLAT_CLIENT_ID` and `BUGSPLAT_CLIENT_SECRET` environment variables; if set, these are used instead of `SymbolUploadClientId`/`SymbolUploadClientSecret`. If your game contains Native Windows C++ plugins, `.dll` and `.pdb` files in the `Assets/Plugins/x86` and `Assets/Plugins/x86_64` folders will be uploaded by BugSplat's PostBuild script and used in symbolication.

For IL2CPP builds, BugSplat will also upload `LineNumberMappings.json`. Line mappings allow BugSplat to replace generated C++ function names, file names, and line numbers with their original C# equivalents.

#### Support Response

BugSplat has the ability to display a support response to users who encounter a crash. You can show your users a generalized support response for all crashes, or a custom support response that corresponds to the type of crash that occurred. Defining a support response allows you to alert users that bug has been fixed in a new version, or that they need to update their graphics drivers.

Next, pass a callback to `bugsplat.Post`. In the callback handler add code to open the support response in the user's browser. A full example can be seen in [ErrorGenerator.cs](https://github.com/BugSplat-Git/bugsplat-unity/blob/main/Samples~/my-unity-crasher/Scripts/ErrorGenerator.cs).

```csharp
private string infoUrl = "";

public void Event_CatchExceptionThenPostNewBugSplat()
{
    try
    {
        GenerateSampleStackFramesAndThrow();
    }
    catch (Exception ex)
    {
        var options = new ReportPostOptions()
        {
            Description = "a new description"
        };

        StartCoroutine(bugsplat.Post(ex, options, ExceptionCallback));
    }
}

void ExceptionCallback(ExceptionReporterPostResult result)
{
    UnityEngine.Debug.Log($"Exception post callback result: {result.Message}");

    if (result.Response == null) {
        return;
    }

    UnityEngine.Debug.Log($"BugSplat Status: {result.Response.status}");
    UnityEngine.Debug.Log($"BugSplat Crash ID: {result.Response.crashId}");
    UnityEngine.Debug.Log($"BugSplat Support URL: {result.Response.infoUrl}");

    infoUrl = result.Response.infoUrl;
}

private void OpenUrl(string url)
{
    var escaped = url.Replace("?", "\\?").Replace("&", "\\&").Replace(" ", "%20").Replace("!", "\\!");

#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN || UNITY_WSA
    Process.Start(url);
#elif UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
    Process.Start("open", escaped);
#elif UNITY_STANDALONE_LINUX || UNITY_EDITOR_LINUX
    Process.Start("xdg-open", escaped);
#else
    UnityEngine.Debug.Log($"OpenUrl unsupported platform: {Application.platform}");
#endif
}
```

When an exception occurs, a page similar to the following will open in the user's browser on Windows, macOS, and Linux.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FIpbn4r5bsaVlaWc7Ibx8%2Fimage.png?alt=media&amp;token=cd41b427-e2b2-482a-a954-519e9baf3d2e" alt=""><figcaption></figcaption></figure>

More information on support responses can be found [here](https://docs.bugsplat.com/introduction/production/setting-up-custom-support-responses).

### 🤖 Android

The bugsplat-unity plugin supports crash reporting for native C++ crashes on Android via Crashpad. To configure crash reporting for Android, set the `UseNativeCrashReportingForAndroid` and `UploadDebugSymbolsForAndroid` properties to `true` on the BugSplatManager instance.

You'll also need to configure the scripting backend to use IL2CPP, target ARM64 (ARMV7a is not supported), and set the Minimum API Level to Android 8.0 (API level 26) or higher.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2F3sfdYtrnBitV1NjWpDlb%2Fimage.png?alt=media&amp;token=0fd6c9f1-02e1-4ed6-828d-5c78816634ae" alt=""><figcaption></figcaption></figure>

When you build your app for Android, be sure to set `Create symbols.zip` to `Debugging`

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2F1GpljzR8BmHtgLzMRwUi%2Fimage.png?alt=media&amp;token=fc443d5a-8be2-4ed2-af06-e51ab8795062" alt=""><figcaption></figcaption></figure>

#### ANR Detection

When native crash reporting is enabled, the bugsplat-unity plugin also reports ANRs (Application Not Responding events). No additional configuration is required.

On the next app launch, the SDK queries the OS for ANRs that occurred during the previous session, reads the system-provided thread dump, and uploads it to BugSplat. ANR reports appear alongside crashes with the **`Android.ANR`** type. The sample project's **Hang / ANR** button triggers an ANR for testing.

{% hint style="info" %}
ANR detection requires Android 11 (API level 30) or higher at runtime. On older versions it is silently disabled, while native crash reporting continues to work.
{% endhint %}

### 🍎 iOS

The bugsplat-unity plugin supports crash reporting for native C++ crashes on iOS via bugsplat-apple. To configure crash reporting for iOS, set the `UseNativeCrashReportingForIos` and `UploadDebugSymbolsForIos` properties to `true` on the BugSplatManager instance.

#### Hang Detection

When native crash reporting is enabled, the bugsplat-unity plugin also detects fatal main-thread hangs. No additional configuration is required.

If the main thread stays unresponsive past the detection threshold and the app is then terminated without recovering (by the OS watchdog at launch or resume, or by the user force-quitting), BugSplat uploads a hang report on the next launch. Hangs the app recovers from are not reported. Hang reports carry the exception name **`App Hang (Fatal)`**. The sample project's **Hang / ANR** button triggers a hang for testing.

{% hint style="info" %}
Hang detection is suppressed while a debugger is attached. Test it on a build run without the Xcode debugger.
{% endhint %}

### 🖥 macOS

The bugsplat-unity plugin supports native crash reporting on macOS via bugsplat-apple, which uses PLCrashReporter to capture crashes via Mach exception handling. Native macOS crash reporting requires the `IL2CPP` scripting backend.

To configure crash reporting for macOS, set the `UseNativeCrashReportingForMac` and `UploadDebugSymbolsForMac` properties to `true` on your `BugSplatOptions` asset. For IL2CPP builds, BugSplat will upload dSYMs and `LineNumberMappings.json` for full symbolication.

### 🧩 API

The following API methods are available to help you customize BugSplat to fit your needs.

#### BugSplatManager

| Setting                       | Description                                                                                |
| ----------------------------- | ------------------------------------------------------------------------------------------ |
| DontDestroyManagerOnSceneLoad | Should the BugSplat Manager persist through scene loads?                                   |
| RegisterLogMessageReceived    | Register a callback function and allow BugSplat to capture instances of LogType.Exception. |

#### BugSplat Options

| Option                            | Description                                                                                                                                                                                                                                         |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Database                          | The name of your BugSplat database.                                                                                                                                                                                                                 |
| Application                       | The name of your BugSplat application. Defaults to Application.productName if no value is set.                                                                                                                                                      |
| Version                           | The version of your BugSplat application. Defaults to Application.version if no value is set.                                                                                                                                                       |
| Description                       | A default description that can be overridden by call to Post.                                                                                                                                                                                       |
| Email                             | A default email that can be overridden by call to Post.                                                                                                                                                                                             |
| Key                               | A default key that can be overridden by call to Post.                                                                                                                                                                                               |
| Notes                             | A default general purpose field that can be overridden by call to post                                                                                                                                                                              |
| User                              | A default user that can be overridden by call to Post                                                                                                                                                                                               |
| CaptureEditorLog                  | Should BugSplat upload Editor.log when Post is called                                                                                                                                                                                               |
| CapturePlayerLog                  | Should BugSplat upload Player.log when Post is called                                                                                                                                                                                               |
| CaptureScreenshots                | Should BugSplat a screenshot and upload it when Post is called                                                                                                                                                                                      |
| PostExceptionsInEditor            | Should BugSplat upload exceptions when in editor                                                                                                                                                                                                    |
| PersistentDataFileAttachmentPaths | Paths to files (relative to Application.persistentDataPath) to upload with each report                                                                                                                                                              |
| ShouldPostException               | Settable guard function that is called before each BugSplat report is posted                                                                                                                                                                        |
| SymbolUploadClientId              | An OAuth2 Client ID value used for uploading [symbol files](https://docs.bugsplat.com/introduction/development/working-with-symbol-files) generated via BugSplat's [Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page     |
| SymbolUploadClientSecret          | An OAuth2 Client Secret value used for uploading [symbol files](https://docs.bugsplat.com/introduction/development/working-with-symbol-files) generated via BugSplat's [Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page |
| UseNativeCrashReportingForMac     | Should BugSplat enable native crash reporting on macOS                                                                                                                                                                                              |
| UploadDebugSymbolsForMac          | Should BugSplat upload dSYMs and LineNumberMappings.json for macOS builds                                                                                                                                                                           |

### 💬 User Feedback

In addition to crash reporting, BugSplat supports collecting non-crashing user feedback such as bug reports and feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title.

```csharp
var bugsplat = FindFirstObjectByType<BugSplatManager>().BugSplat;
StartCoroutine(bugsplat.PostFeedback("Login button broken", "Nothing happens when I tap it"));
```

You can customize feedback submissions with `ReportPostOptions`:

```csharp
var options = new ReportPostOptions()
{
    Email = "jane@example.com",
    User = "Jane",
    Description = "The sidebar overlaps the main content."
};
options.AdditionalAttachments.Add(new FileInfo("/path/to/screenshot.png"));

StartCoroutine(bugsplat.PostFeedback("UI rendering issue", "The sidebar overlaps.", options));
```

### 🧑‍💻 Contributing

BugSplat ❤️s open source! If you feel that this package can be improved, please open an [Issue](https://github.com/BugSplat-Git/bugsplat-unity/issues). If you have an awesome new feature you'd like to implement, we'd love to merge your [Pull Request](https://github.com/BugSplat-Git/bugsplat-unity/pulls). You can also send us an [email](mailto:support@bugsplat.com), join us on [Discord](https://discord.gg/K4KjjRV5ve), or message us via the in-app chat on [bugsplat.com](https://bugsplat.com/).


# Xbox

Integrate BugSplat for crash reporting in Xbox games (Series X, S, One). Our SDK supports GDK and GDKX projects, helping certified developers enhance game stability.

Using BugSplat enables developers to automatically track crashes in Xbox games, including Xbox Series X, Xbox Series S, and Xbox One, during both development and production phases. Our crash reporting tool supports projects developed with both GDK and GDKX frameworks.

### Accessing the SDK

To request access to the BugSplat SDK, navigate to the [Microsoft Games middleware request page](https://developer.microsoft.com/en-us/games/support/request-gdkx-middleware), select **BugSplat** from the Middleware Partner dropdown, and submit your request. Once Microsoft processes your request and access is granted, BugSplat will deliver the SDK download package and instruction set via the Gaming Consoles tab on the [Database Integrations](https://app.bugsplat.com/v2/database/integrations) page.

For verification of your Xbox Partner status or to learn more about BugSplat's support for Xbox, please contact us at <support@bugsplat.com>.


# Custom Engine Support

BugSplat supports crash reporting for engines and frameworks not listed in our official documentation.

### How it works

BugSplat's crash reporting is built on open standards. If your engine can produce a minidump, a [Breakpad](/integrations/desktop/breakpad)/[Crashpad](/integrations/desktop/crashpad) report, a PLCrashReporter log (iOS/macOS), or expose a crash callback where you can invoke a handler, BugSplat can likely ingest and process your crashes. On Android and Linux, Crashpad is the supported path.

### Uploading crashes

The recommended upload path is a three-step process using presigned URLs:

1. **Request a presigned upload URL** - `GET https://{{database}}.bugsplat.com/api/getCrashUploadUrl`
2. **Upload your zipped crash file** - `PUT {{presigned_url}}` with `Content-Type: application/octet-stream`
3. **Commit the upload** - `POST https://{{database}}.bugsplat.com/api/commitS3CrashUpload`

Full details and a working Python example are available in the [Crash Post Endpoints documentation](https://docs.bugsplat.com/introduction/development/web-services/crash).

When committing the upload in step 3, you'll specify a `crashType` that tells BugSplat how to process the report. Common values for custom engine scenarios:

| Format                                        | crashType         |
| --------------------------------------------- | ----------------- |
| Windows minidump                              | `Windows.Native`  |
| Breakpad / Crashpad (Windows, Linux, Android) | `Crashpad`        |
| iOS / macOS PLCrashReporter                   | `PLCrashReporter` |
| Custom XML report                             | `XmlReport`       |

For platforms that cannot upload via presigned URLs, BugSplat also supports direct POST endpoints for Crashpad, XML, PS4, PS5, and others. See the [Crash Post Endpoints documentation](https://docs.bugsplat.com/introduction/development/web-services/crash) for the full list.

#### XML as a fallback

If your engine doesn't produce a standard crash format, the XML endpoint (`POST https://{{database}}.bugsplat.com/post/xml/index.php`) accepts a custom-structured report. You provide the stack frames, module list, and exception data in BugSplat's XML schema. This is the most flexible path for fully custom engines, and it also works well for scripting languages (Lua, Python, etc.) embedded in your engine where a native crash handler isn't practical.

### Symbol upload

BugSplat's symbol upload API accepts standard symbol formats. As long as you can produce symbols during your build process, stack traces can be symbolicated regardless of engine.

### What we need from you

The right integration path depends on your engine's crash handling architecture, platform targets, and build pipeline. Before reaching out, it helps to know:

* What platforms you're targeting (Windows, Linux, macOS, iOS, console)
* How your engine handles crashes today (signal handler, SEH, custom callback, none)
* Whether your engine produces minidumps, Breakpad reports, PLCrashReporter logs, or raw crash data
* Whether you have a symbol generation step in your build

### Get in touch

If you're building on a custom or proprietary engine and want to know whether BugSplat will work for you, email <joey@bugsplat.com> with a brief description of your setup. We'll give you a straight answer.


# Mobile Apps

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.

{% content-ref url="/pages/-MeQvUfwCB3wyphC\_\_m9" %}
[Android](/integrations/mobile/android)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRVzNXS2buhwOQS83i" %}
[Ionic](/integrations/mobile/ionic)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg28rhV67Dj\_VBY9c2p" %}
[iOS](/integrations/mobile/ios)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg28vqsApPnLS-nMNAQ" %}
[React Native](/integrations/mobile/react-native)
{% endcontent-ref %}

{% hint style="info" %}
**Not finding what you're looking for?** Please reach out to <support@bugsplat.com> to request the language or environment you'd like BugSplat to integrate with next!
{% endhint %}


# Android

### 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.

### Requirements 📋

* **Android Gradle Plugin (AGP)**: 8.5.1 or higher (for 16KB page size support)
* **Android NDK**: r27 or higher recommended
* **minSdkVersion**: 21 or higher
* **targetSdkVersion**: 35 or higher recommended

{% hint style="info" %}
Starting November 1st, 2025, Google Play requires all new apps and updates targeting Android 15+ to [support 16 KB page sizes](https://developer.android.com/guide/practices/page-sizes). The BugSplat Android SDK is built with 16KB ELF alignment to comply with this requirement.
{% endhint %}

### Integration 🏗️

`bugsplat-android` supports multiple installation methods.

#### Gradle (Recommended)

Add the BugSplat dependency to your app's `build.gradle` file:

```gradle
dependencies {
    implementation 'com.bugsplat:bugsplat-android:1.3.0'
}
```

BugSplat is hosted on Maven Central, which is included by default in most Android projects. If needed, ensure `mavenCentral()` is in your `settings.gradle.kts`:

```kotlin
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
    }
}
```

#### Manual Setup

To integrate BugSplat using the AAR file:

1. Go to the [Releases](https://github.com/BugSplat-Git/bugsplat-android/releases) page and download the latest `bugsplat-android-x.y.z.aar` file.
2. Copy the AAR into your app module's `libs/` directory.
3. In your app-level `build.gradle`, add:

```gradle
dependencies {
    implementation files('libs/bugsplat-android-x.y.z.aar')
}
```

4. In your `AndroidManifest.xml`, add the required permissions:

```xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
```

### Usage 🧑‍💻

#### Loading config from local.properties (recommended)

Keeping your `database`, `application`, and `version` values in one place avoids drift between runtime (`BugSplat.init`) and symbol upload. The pattern most BugSplat users adopt:

**1.** Add the database name to the gitignored `local.properties`:

```properties
bugsplat.database=your_database
```

**2.** In your app module's `build.gradle`, load it and expose it (plus `applicationId` and `versionName`) as `BuildConfig` fields:

```gradle
def localProps = new Properties()
def localPropsFile = rootProject.file('local.properties')
if (localPropsFile.exists()) {
    localPropsFile.withInputStream { localProps.load(it) }
}

android {
    defaultConfig {
        applicationId "com.example.myapp"
        versionName "1.0.0"

        buildConfigField "String", "BUGSPLAT_DATABASE",
            "\"${localProps.getProperty('bugsplat.database')}\""
        buildConfigField "String", "BUGSPLAT_APP_NAME",
            "\"${applicationId}\""
        buildConfigField "String", "BUGSPLAT_APP_VERSION",
            "\"${versionName}\""
    }
    buildFeatures { buildConfig true }
}
```

{% hint style="info" %}
This same `bugsplat.database` value is picked up by the symbol upload task below, so there's a single source of truth across the whole build. See [`example/build.gradle`](https://github.com/BugSplat-Git/bugsplat-android/blob/main/example/build.gradle) for the complete setup.
{% endhint %}

#### Initialization

Initialize BugSplat from your launch `Activity`, typically in `onCreate`:

**Java**

```java
import com.bugsplat.android.BugSplat;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        BugSplat.init(
            this,
            BuildConfig.BUGSPLAT_DATABASE,
            BuildConfig.BUGSPLAT_APP_NAME,
            BuildConfig.BUGSPLAT_APP_VERSION
        );
    }
}
```

**Kotlin**

```kotlin
import com.bugsplat.android.BugSplat

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        BugSplat.init(
            this,
            BuildConfig.BUGSPLAT_DATABASE,
            BuildConfig.BUGSPLAT_APP_NAME,
            BuildConfig.BUGSPLAT_APP_VERSION
        )
    }
}
```

#### Custom Attributes

Attach arbitrary key/value pairs to crash reports. Attributes can be set at init time or updated at any time afterward:

```java
// At init
Map<String, String> attributes = new HashMap<>();
attributes.put("environment", "development");
attributes.put("build_flavor", "internal");
BugSplat.init(
    this,
    BuildConfig.BUGSPLAT_DATABASE,
    BuildConfig.BUGSPLAT_APP_NAME,
    BuildConfig.BUGSPLAT_APP_VERSION,
    attributes
);

// Or at any time after init
BugSplat.setAttribute("user_tier", "premium");
BugSplat.removeAttribute("user_tier");
```

Keys and values are each limited to 255 bytes.

#### Attachments

Attach files to crash reports by passing their paths to `init`:

```java
String attachmentPath = getFileStreamPath("log.txt").getAbsolutePath();
String[] attachments = new String[]{attachmentPath};
BugSplat.init(
    this,
    BuildConfig.BUGSPLAT_DATABASE,
    BuildConfig.BUGSPLAT_APP_NAME,
    BuildConfig.BUGSPLAT_APP_VERSION,
    attachments
);
```

#### ANR Detection

`bugsplat-android` automatically detects and reports Application Not Responding (ANR) events on Android 11+ (API 30+) using the [`ApplicationExitInfo`](https://developer.android.com/reference/android/app/ApplicationExitInfo) API.

When the system kills your app due to an ANR, the event is recorded by Android. On the next app launch, the SDK queries `ActivityManager.getHistoricalProcessExitReasons()` for new ANRs, reads the system-provided thread dump, and uploads it to BugSplat. ANR reports appear alongside crashes with the **"Android.ANR"** type.

The thread dump includes:

* Full Java stack traces for all threads in the process
* Native stack frames with BuildIds (symbolicated against uploaded `.sym` files)
* Lock contention information

ANR detection is enabled automatically when you call `BugSplat.init()`, with no additional configuration required. The SDK persists the timestamp of the last reported ANR in `SharedPreferences` to avoid duplicate uploads.

{% hint style="info" %}
ANR detection requires Android 11+ (API 30+). On older versions, `ApplicationExitInfo` is unavailable and ANR detection is silently disabled.
{% endhint %}

To test ANR detection, call `BugSplat.hang()` from the main thread:

```java
// Blocks the main thread in a native infinite loop.
// Tap the screen to trigger the system ANR dialog (~5s).
BugSplat.hang();
```

#### User Feedback

Submit non-crashing feedback (bug reports, feature requests) using `BugSplat.postFeedback`. Feedback reports appear in BugSplat with the **"User Feedback"** type.

```java
// Async (returns immediately, runs on background thread)
BugSplat.postFeedback(
    BuildConfig.BUGSPLAT_DATABASE,
    BuildConfig.BUGSPLAT_APP_NAME,
    BuildConfig.BUGSPLAT_APP_VERSION,
    "Login button broken",      // title (required)
    "Nothing happens on tap",   // description
    "Jane",                     // user
    "jane@example.com",         // email
    null                        // appKey
);

// Blocking variant (returns true on success)
boolean ok = BugSplat.postFeedbackBlocking(
    BuildConfig.BUGSPLAT_DATABASE,
    BuildConfig.BUGSPLAT_APP_NAME,
    BuildConfig.BUGSPLAT_APP_VERSION,
    "Login button broken", "Nothing happens on tap",
    "Jane", "jane@example.com", null
);
```

File attachments can be included by passing a `List<File>`:

```java
List<File> attachments = new ArrayList<>();
attachments.add(new File(getFilesDir(), "app.log"));

BugSplat.postFeedback(
    BuildConfig.BUGSPLAT_DATABASE,
    BuildConfig.BUGSPLAT_APP_NAME,
    BuildConfig.BUGSPLAT_APP_VERSION,
    "Login button broken", "Nothing happens on tap",
    "Jane", "jane@example.com", null,
    attachments
);
```

Custom key/value attributes can also be attached to the feedback report. They're JSON-encoded into the `attributes` field on the commit request:

```java
Map<String, String> attributes = new HashMap<>();
attributes.put("environment", "production");
attributes.put("user_tier", "premium");

BugSplat.postFeedback(
    BuildConfig.BUGSPLAT_DATABASE,
    BuildConfig.BUGSPLAT_APP_NAME,
    BuildConfig.BUGSPLAT_APP_VERSION,
    "Login button broken", "Nothing happens on tap",
    "Jane", "jane@example.com", null,
    null,        // attachments
    attributes
);
```

**Shake-to-Feedback**

A common UX pattern for beta builds is to open the feedback dialog when the user shakes the device. The SDK doesn't ship a built-in shake detector, but it's a small amount of code on top of `SensorManager`: register for `Sensor.TYPE_ACCELEROMETER`, watch for a few accelerometer samples above \~2.7G inside a 1s window, then invoke whichever UI surfaces your `postFeedback` call:

```java
SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
sm.registerListener(new SensorEventListener() {
    @Override public void onSensorChanged(SensorEvent e) {
        float gx = e.values[0] / SensorManager.GRAVITY_EARTH;
        float gy = e.values[1] / SensorManager.GRAVITY_EARTH;
        float gz = e.values[2] / SensorManager.GRAVITY_EARTH;
        if (Math.sqrt(gx*gx + gy*gy + gz*gz) > 2.7f) {
            showFeedbackDialog();  // your UI that calls BugSplat.postFeedback
        }
    }
    @Override public void onAccuracyChanged(Sensor s, int a) {}
}, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
```

See [`ShakeDetector.java`](https://github.com/BugSplat-Git/bugsplat-android/blob/main/example/src/main/java/com/bugsplat/example/ShakeDetector.java) in the example app for a copy-pasteable implementation that adds debouncing and a cooldown to avoid spurious triggers.

#### Native Library Packaging

To ensure native libraries (and their debug info) are properly deployed, configure your app's `build.gradle`:

```gradle
android {
    defaultConfig {
        ndk {
            // Match the ABI filters from the library
            abiFilters 'arm64-v8a', 'x86_64', 'armeabi-v7a'
        }
    }

    packagingOptions {
        jniLibs {
            keepDebugSymbols += ['**/*.so']
            // Use uncompressed shared libraries with 16KB zip alignment
            // (required for Android 15+ devices with 16KB page sizes).
            useLegacyPackaging false
        }
        doNotStrip '**/*.so'
    }
}
```

### Symbol Upload 🔣

To symbolicate native stack frames in crash and ANR reports, upload your app's unstripped `.so` files to BugSplat as Breakpad `.sym` files. There are three ways to do this.

#### 1. Gradle Build Integration (Recommended)

Wire symbol upload into your Gradle build so it runs automatically after `assembleDebug` / `assembleRelease`. Credentials are loaded from the gitignored `local.properties` to avoid committing them.

**Step 1: Add credentials to `local.properties`:**

```properties
bugsplat.database=your_database
bugsplat.clientId=your_client_id
bugsplat.clientSecret=your_client_secret
```

**Step 2: In `build.gradle`, load credentials and register per-ABI upload tasks:**

```gradle
def localProps = new Properties()
def localPropsFile = rootProject.file('local.properties')
if (localPropsFile.exists()) {
    localPropsFile.withInputStream { localProps.load(it) }
}

ext {
    bugsplatDatabase = localProps.getProperty('bugsplat.database')
    bugsplatClientId = localProps.getProperty('bugsplat.clientId', '')
    bugsplatClientSecret = localProps.getProperty('bugsplat.clientSecret', '')
    bugsplatAppName = android.defaultConfig.applicationId
    bugsplatAppVersion = android.defaultConfig.versionName
}

// See the example app for the full implementation, which:
//  - Downloads the symbol-upload binary if not present
//  - Registers per-ABI upload tasks (one per ABI in defaultConfig.ndk.abiFilters)
//  - Chains the per-ABI tasks serially in an AllAbis task via mustRunAfter
//    (the symbol-upload binary uses a shared temp dir)
//  - Reads merged_native_libs from AGP 8.6+ intermediate path:
//    build/intermediates/merged_native_libs/{buildType}/merge{BuildType}NativeLibs/out/lib/{abi}/

tasks.whenTaskAdded { task ->
    if (task.name == 'assembleDebug') {
        task.finalizedBy(tasks.named('uploadBugSplatSymbolsDebugAllAbis'))
    }
}
```

See [`example/build.gradle`](https://github.com/BugSplat-Git/bugsplat-android/blob/main/example/build.gradle) in the SDK repo for the complete, copy-pasteable implementation.

Get your `clientId` and `clientSecret` from the [BugSplat Integrations page](https://app.bugsplat.com/v2/database/integrations#oauth).

#### 2. Built-in Programmatic Upload

The SDK exposes `BugSplat.uploadSymbols` to upload symbols at runtime (useful if you need to kick this off from app code rather than Gradle):

```java
// Async
BugSplat.uploadSymbols(
    context,
    "your_database",
    "your_app",
    "1.0.0",
    "your_client_id",
    "your_client_secret",
    nativeLibsDir
);

// Blocking
try {
    BugSplat.uploadSymbolsBlocking(
        context, "your_database", "your_app", "1.0.0",
        "your_client_id", "your_client_secret", nativeLibsDir
    );
} catch (IOException e) {
    Log.e("MyApp", "Failed to upload symbols", e);
}
```

This requires bundling the `symbol-upload` binary in your app's assets. See the [Example App README](https://github.com/BugSplat-Git/bugsplat-android/blob/main/example/README.md) for details.

#### 3. Command-Line Tool

You can also invoke [`symbol-upload`](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload) directly from the command line:

```sh
# Download the binary
curl -sL -O "https://app.bugsplat.com/download/symbol-upload-macos" && chmod +x symbol-upload-macos

# Upload .sym files generated from unstripped .so files
./symbol-upload-macos \
    -b DATABASE -a APPLICATION -v VERSION \
    -i CLIENT_ID -s CLIENT_SECRET \
    -d /path/to/native/libs \
    -f "**/*.so" -m
```

Please refer to the [symbol-upload documentation](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload) for full usage details.

### Sample Application 🧑‍🏫

The `bugsplat-android` repository includes a full example app that demonstrates:

* Initializing the SDK at app startup
* Triggering a native crash
* Triggering an ANR (via `BugSplat.hang()`) to test ANR detection and native frame symbolication
* Submitting user feedback via a dialog (also openable by shaking the device)
* Setting custom attributes via a dialog
* Uploading symbols via Gradle

To run it:

1. Clone [`bugsplat-android`](https://github.com/BugSplat-Git/bugsplat-android).
2. Open in Android Studio.
3. Add your BugSplat credentials to `local.properties` as described in the **Symbol Upload** section above.
4. Select the `example` run configuration and click Run.

See the [Example App README](https://github.com/BugSplat-Git/bugsplat-android/blob/main/example/README.md) for more details.


# Ionic

## Overview

[Ionic](https://ionicframework.com/) is an open-source SDK for hybrid mobile app development, and an excellent tool for developing cross-platform applications. Our integration allows you to track crashes from your Ionic application - giving you detailed insight into your critical issues.

To enable your Ionic application to work with BugSplat crash reporting, view our [Angular](/integrations/web/angular) doc.

If you have any questions please email us at <support@bugsplat.com>.


# iOS

### 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.

### Requirements 📋

* BugSplat for iOS supports iOS 13 and later.
* BugSplat for macOS supports macOS 10.13 and later.

### Integration 🏗️

BugSplat supports multiple methods for installing the xcfamework in a project.

#### Swift Package Manager (SPM)

Add the following URL to your project's `Additional Package Dependencies`:

```
https://github.com/BugSplat-Git/bugsplat-apple
```

#### CocoaPods

Add the following to your `Podfile`:

```ruby
pod 'BugSplat', '~> 3.0'
```

Then run `pod install`.

#### Manual Setup

To manually install BugSplat.xcframework in your project:

1. Download the latest release (BugSplat.xcframework.zip) from the [Releases](https://github.com/BugSPlat-Git/bugsplat-apple/releases) page. The zip will contain BugSplat.xcframework.
2. Unzip the archive.
3. In Xcode, select your app target, then go to the General tab, scroll down to Framework, Libraries, and Embedded Content, then click the "+" and navigate to where you unzipped the archive in step 2. Select BugSplat.xcframework, then tap the "Add" button. Once added, select Embed & Sign.

### Usage 🧑‍💻

#### Configuration

BugSplat requires a few Xcode configuration steps to integrate the xcframework with your BugSplat account.

Add the following case-sensitive key to your app's `Info.plist` replacing `DATABASE_NAME` with your customer-specific BugSplat database name.

```xml
<key>BugSplatDatabase</key>
<string>DATABASE_NAME</string>
```

{% hint style="info" %}
For macOS apps, you must enable `Outgoing network connections (client)` in the Signing & Capabilities of the Target.
{% endhint %}

#### Symbol Upload

To symbolicate crash reports, you must upload your app's `dSYM` files to the BugSplat server. There are scripts to help with this.

Download BugSplat's cross-platform tool, [symbol-upload-macos](https://docs.bugsplat.com/introduction/development/working-with-symbol-files/upload-symbols-with-symbol-upload) for Apple Silicon by entering the following command in your terminal.

```bash
curl -sL -O "https://app.bugsplat.com/download/symbol-upload-macos"
```

Alternatively, you can download the Intel version via the following command.

```bash
curl -sL -O "https://app.bugsplat.com/download/symbol-upload-macos-intel"
```

Make `symbol-upload-macos` executable

```bash
chmod +x symbol-upload-macos
```

Several options exist to integrate `symbol-upload-macos` into the app build process.

* Create an Xcode build-phase script to upload dSYM files after every build. See example script [Symbol\_Upload\_Examples/Build-Phase-symbol-upload.sh](https://github.com/BugSplat-Git/bugsplat-apple/blob/main/Symbol_Upload_Examples/Build-Phase-symbol-upload.sh)
* Create an Xcode Archive post-action script in the target's Build Scheme in order to upload dSYM files after the app is archived and ready for submission to TestFlight or the App Store. The build-phase script above can be adapted for this purpose.
* Manually upload an `xcarchive` or `dSYM` file generated by Xcode via BugSplat's [Versions](https://app.bugsplat.com/v2/versions) page.

{% hint style="info" %}
For the build-phase script to create dSYM files, change Build Settings `DEBUG_INFORMATION_FORMAT` from `DWARF` to `DWARF with dSYM File`. See inline notes within each script for modifications to Xcode Build Settings required for each script to work.
{% endhint %}

Please refer to our [documentation](https://docs.bugsplat.com/introduction/development/working-with-symbol-files/upload-symbols-with-symbol-upload) to learn more about how to use `symbol-upload-macos`.

#### Initialization

Several iOS and macOS test app examples are included within the [Example\_Apps](https://github.com/BugSplat-Git/bugsplat-apple/blob/main/Example_Apps) folder to show how simple and quickly BugSplat can be integrated into an app, and ready to submit crash reports.

You can instantiate BugSplat by following the language-specific examples below.

**Swift (UIKit)**

```swift
import BugSplat

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Initialize BugSplat
        BugSplat.shared().delegate = self
        BugSplat.shared().autoSubmitCrashReport = false
        BugSplat.shared().start()

        return true
    }
}

extension AppDelegate: BugSplatDelegate {
    // MARK: BugSplatDelegate
    func bugSplatWillSendCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillSendCrashReportsAlways(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatDidFinishSendingCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillCancelSendingCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillShowSubmitCrashReportAlert(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplat(_ bugSplat: BugSplat, didFailWithError error: Error) {
        print("\(#file) - \(#function)")
    }
}
```

**Swift (SwiftUI)**

```swift
import BugSplat

@main
struct BugSplatTestSwiftUIApp: App {
    private let bugSplat = BugSplatInitializer()

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

@objc class BugSplatInitializer: NSObject, BugSplatDelegate {
    override init() {
        super.init()
        BugSplat.shared().delegate = self
        BugSplat.shared().autoSubmitCrashReport = false
        BugSplat.shared().start()
    }

    // MARK: BugSplatDelegate
    func bugSplatWillSendCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillSendCrashReportsAlways(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatDidFinishSendingCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillCancelSendingCrashReport(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplatWillShowSubmitCrashReportAlert(_ bugSplat: BugSplat) {
        print("\(#file) - \(#function)")
    }

    func bugSplat(_ bugSplat: BugSplat, didFailWithError error: Error) {
        print("\(#file) - \(#function)")
    }
}
```

**Obj-C**

```objectivec
#import <BugSplat/BugSplat.h>

@interface AppDelegate () <BugSplatDelegate>
@end

@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Initialize BugSplat
    [[BugSplat shared] setDelegate:self];
    [[BugSplat shared] setAutoSubmitCrashReport:NO];
    [[BugSplat shared] start];
}

#pragma mark - BugSplatDelegate

- (void)bugSplatWillSendCrashReport:(BugSplat *)bugSplat {
    NSLog(@"bugSplatWillSendCrashReport called");
}

- (void)bugSplatWillSendCrashReportsAlways:(BugSplat *)bugSplat {
    NSLog(@"bugSplatWillSendCrashReportsAlways called");
}

- (void)bugSplatDidFinishSendingCrashReport:(BugSplat *)bugSplat {
    NSLog(@"bugSplatDidFinishSendingCrashReport called");
}

- (void)bugSplatWillCancelSendingCrashReport:(BugSplat *)bugSplat {
    NSLog(@"bugSplatWillCancelSendingCrashReport called");
}

- (void)bugSplatWillShowSubmitCrashReportAlert:(BugSplat *)bugSplat {
    NSLog(@"bugSplatWillShowSubmitCrashReportAlert called");
}

- (void)bugSplat:(BugSplat *)bugSplat didFailWithError:(NSError *)error {
    NSLog(@"bugSplat:didFailWithError: %@", [error localizedDescription]);
}
```

#### Attributes

BugSplat supports custom attributes that can be added to a crash report. These attributes are searchable in the BugSplat dashboard.

```swift
BugSplat.shared().setValue("Value of Attribute", forAttribute: "AttributeName")
```

```objectivec
[[BugSplat shared] setValue:@"Value of Attribute" forAttribute:@"AttributeName"];
```

Please see the framework-specific [sample applications](#sample-applications) for more examples demonstrating how to use attributes.

#### Application Name and Version

By default, BugSplat uses values from your app's `Info.plist` (`CFBundleDisplayName`/`CFBundleName` for application name and `CFBundleShortVersionString` for version). You can override these values programmatically:

```swift
BugSplat.shared().applicationName = "MyCustomAppName"
BugSplat.shared().applicationVersion = "2.0.0-beta"
BugSplat.shared().start()
```

```objectivec
[[BugSplat shared] setApplicationName:@"MyCustomAppName"];
[[BugSplat shared] setApplicationVersion:@"2.0.0-beta"];
[[BugSplat shared] start];
```

#### Application Key

Set an `appKey` to identify your application build, environment, or user locale. In the BugSplat dashboard, you can configure custom localized support responses for crash groups based on the `appKey` value using the "Support Response" button on the Crash Group page. See [Support Responses](https://docs.bugsplat.com/introduction/production/setting-up-custom-support-responses) for more information.

```swift
BugSplat.shared().appKey = "en-US"
```

```objectivec
[[BugSplat shared] setAppKey:@"en-US"];
```

#### Notes

Add arbitrary additional data to include with crash reports. Notes can also be modified in the BugSplat dashboard after a crash is submitted.

```swift
BugSplat.shared().notes = "Debug build, feature-x enabled"
```

```objectivec
[[BugSplat shared] setNotes:@"Debug build, feature-x enabled"];
```

#### Crash Reporter Customization

There are several ways to customize your BugSplat crash reporter.

**Custom Banner Image**

* BugSplat for macOS provides the ability to configure a custom image to be displayed in the crash reporter UI for branding purposes. The image view dimensions are 440x110 and will scale down proportionately. There are 2 ways developers can provide an image:
  1. Set the image property directly on BugSplat
  2. Provide an image named `bugsplat-logo` in the main app bundle or asset catalog

**User Details**

* Set `askUserDetails` to `NO` to prevent the name and email fields from displaying in the crash reporter UI. Defaults to `YES`.

**Auto Submit**

* By default, BugSplat will auto-submit crash reports for iOS and prompt the end user to submit a crash report for macOS. This default can be changed using the `autoSubmitCrashReport` property. Set `autoSubmitCrashReport` to `YES` in order to send crash reports to the server automatically without presenting the crash reporter dialogue. On iOS, when set to `NO`, the user is presented with an alert with options: "Send", "Don't Send", and "Always Send".

**Persist User Details**

* Set `persistUserDetails` to `YES` to save and restore the user's name and email when presenting the crash reporter dialogue. Defaults to `NO`.

**Expiration Time**

* Set `expirationTimeInterval` to a desired value (in seconds) whereby if the difference in time between when the crash occurred and the next launch is greater than the set expiration time, auto-send the report without presenting the crash reporter dialogue. Defaults to `-1`, which represents no expiration.

**Attachments**

BugSplat supports uploading attachments with crash reports. There's a delegate method provided by `BugSplatDelegate` that can be implemented to provide attachments to be uploaded.

**Associating Per-Session Files with Crash Reports**

Crash reports are processed and uploaded at the next launch after a crash, not at crash time. By the time `BugSplatDelegate` asks your app for attachments, your app is running a new session, so a fixed file path that gets overwritten each launch (e.g. `app.log`) no longer contains the crashed session's data.

To make this association reliable, BugSplat exposes a per-launch session ID: `BugSplat.shared().sessionID`, a `UUID`/`NSUUID` generated when the `BugSplat` instance is first created, stable for the lifetime of the process, and readable before or after `start()` is called. SessionID-aware delegate callbacks pass the crashed session's ID back to you at the next launch: `attachment(for:sessionID:)` (Obj-C: `attachmentForBugSplat:sessionID:`), `applicationLog(for:sessionID:)` (Obj-C: `applicationLogForBugSplat:sessionID:`), `bugSplatWillSendCrashReport(_:sessionID:)`, `bugSplatDidFinishSendingCrashReport(_:sessionID:)`, and `bugSplat(_:didFailWithError:sessionID:)`. When a sessionID-aware method is implemented, it is called instead of its legacy counterpart, and the `sessionID` parameter is `nil` for crash reports recorded by SDK versions that predate session tracking.

The recommended pattern is to name session-scoped files after the session ID, then return and clean up the crashed session's file from the sessionID-aware delegate callbacks:

```swift
func attachment(for bugSplat: BugSplat, sessionID: UUID?) -> BugSplatAttachment? {
    guard let sessionID else { return nil } // report predates session tracking
    // Return the file this session wrote to `<sessionID>.log`, if it still exists.
}
```

```objectivec
- (BugSplatAttachment *)attachmentForBugSplat:(BugSplat *)bugSplat sessionID:(NSUUID *)sessionID
{
    if (!sessionID) return nil; // report predates session tracking
    // Return the file this session wrote to `<sessionID>.log`, if it still exists.
}
```

See the `Example_Apps` folder in the [bugsplat-apple repo](https://github.com/BugSplat-Git/bugsplat-apple) for a complete implementation of this pattern.

**Bitcode**

Bitcode was introduced by Apple to allow apps sent to the App Store to be recompiled by Apple itself and apply the latest optimization. Bitcode has now been officially deprecated by Apple and should be removed or disabled. If Bitcode is enabled, the symbols generated for your app in the store will be different than the ones from your own build system. We recommend that you disable bitcode in order for BugSplat to reliably symbolicate crash reports. Disabling bitcode significantly simplifies symbols management and currently doesn't have any known downsides for iOS apps.

### 💬 User Feedback

In addition to crash reporting, BugSplat supports collecting non-crashing user feedback such as bug reports and feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title.

```objectivec
[[BugSplat shared] postFeedback:@"Login button broken"
                    description:@"Nothing happens when I tap it"
                       userName:@"Jane"
                      userEmail:@"jane@example.com"
                         appKey:@"pro-tier"
                    attachments:nil
                     completion:^(NSError *error) {
    if (error) {
        NSLog(@"Feedback failed: %@", error);
    } else {
        NSLog(@"Feedback submitted successfully");
    }
}];
```

To include file attachments such as screenshots:

```objectivec
BugSplatAttachment *screenshot = [[BugSplatAttachment alloc] initWithFilename:@"screenshot.png"
                                                              attachmentData:imageData
                                                                 contentType:@"image/png"];
[[BugSplat shared] postFeedback:@"Login button broken"
                    description:@"Nothing happens when I tap it"
                       userName:@"Jane"
                      userEmail:@"jane@example.com"
                         appKey:nil
                    attachments:@[screenshot]
                     completion:^(NSError *error) {
    if (error) {
        NSLog(@"Feedback failed: %@", error);
    } else {
        NSLog(@"Feedback submitted successfully");
    }
}];
```

### ⏱️ Hang Detection

BugSplat can detect fatal main-thread hangs and upload them on the next launch using the same pipeline as crash reports. When enabled, BugSplat watches the main thread; if it stays unresponsive for longer than the configured threshold and the app is then terminated without the main thread recovering (a launch/resume watchdog kill or user force-quit), a hang report is uploaded on the next launch. Non-fatal hangs (those where the main thread eventually resumes) are discarded automatically.

Enable hang detection by setting `enableHangDetection` to `YES` **before** calling `start`. `start` must be invoked on the main thread when this property is enabled.

```swift
BugSplat.shared().enableHangDetection = true
BugSplat.shared().hangDetectionThreshold = 2.0 // optional, defaults to 2.0 seconds
BugSplat.shared().start()
```

```objectivec
[[BugSplat shared] setEnableHangDetection:YES];
[[BugSplat shared] setHangDetectionThreshold:2.0]; // optional, defaults to 2.0 seconds
[[BugSplat shared] start];
```

Hang reports carry the exception name `App Hang (Fatal)` and include attributes prefixed with `bugsplat-hang-` (duration, detection time, app state, launch id) that can be used to correlate them with crashes from the same launch.

{% hint style="info" %}
Detection is suppressed while a debugger is attached or while the app is not active in the foreground. As a consequence, hangs that begin while the app is in the background (including those terminated by background-task expiration) are not reported. Hang detection is also a no-op inside app extensions.
{% endhint %}

The `hangDetectionThreshold` property accepts values in seconds. Typical production values are between 1.0 and 5.0 seconds. Pick a value that comfortably exceeds any work your app may legitimately do on the main thread (image decoding, JSON parsing, etc.) to avoid false positives. Values below `0.1` are clamped to `0.1`.

### Sample Applications 🧑‍🏫

`Example_Apps` includes several iOS and macOS BugSplat Test apps. Integrating BugSplat only requires the xcframework and a few lines of code.

1. Clone the [bugsplat-apple repo](https://github.com/BugSplat-Git/bugsplat-apple).
2. Open `BugSplat.xcworkspace` in Xcode. This workspace contains the SDK and all example apps. Select an example app scheme to run. For iOS, set the destination to be your iOS device. After running from Xcode, stop the process and relaunch from the iOS device directly.
3. Once the app launches, click the "crash" button when prompted.
4. Relaunch the app on the iOS device. At this point a crash report should be submitted to bugsplat.com
5. Visit BugSplat's [Crashes](https://app.bugsplat.com/v2/crashes) page. When prompted for credentials, enter user `fred@bugsplat.com` and password `Flintstone`. The crash you posted from BugSplatTester should be at the top of the list of crashes.
6. Click the "Crash ID" link to view more details about your crash.


# React Native

### Introduction 👋

BugSplat's [`@bugsplat/expo`](https://www.npmjs.com/package/@bugsplat/expo) package provides crash and error reporting for React Native (Expo) apps across iOS, Android, and Web. BugSplat collects native crash reports, JavaScript errors, and custom metadata so that you can fix bugs and deliver a better user experience. Visit [bugsplat.com](https://www.bugsplat.com/) for more information and to sign up for an account.

| Platform    | Native Crashes                                                                     | JS Error Reporting                                         |
| ----------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| **iOS**     | [bugsplat-apple](https://github.com/BugSplat-Git/bugsplat-apple) (PLCrashReporter) | HTTP POST to `/post/js/`                                   |
| **Android** | [bugsplat-android](https://github.com/BugSplat-Git/bugsplat-android) (Crashpad)    | HTTP POST to `/post/js/`                                   |
| **Web**     | N/A                                                                                | [bugsplat-js](https://github.com/BugSplat-Git/bugsplat-js) |

### Requirements 📋

* The `bugsplat-android` SDK requires Android minSdk 26 (Android 8.0+).
* An [Expo](https://expo.dev/) managed or bare workflow project.

### Installation 🏗️

Install the `@bugsplat/expo` package:

```sh
npx expo install @bugsplat/expo
```

### Configuration ⚙️

Add the BugSplat config plugin to your `app.json` or `app.config.js`. Credentials for symbol upload can be set via environment variables (`BUGSPLAT_CLIENT_ID`, `BUGSPLAT_CLIENT_SECRET`) or directly in the plugin config.

```json
{
  "expo": {
    "plugins": [
      ["@bugsplat/expo", {
        "database": "your-database",
        "enableSymbolUpload": true
      }],
      ["expo-build-properties", {
        "android": {
          "minSdkVersion": 26
        }
      }]
    ]
  }
}
```

{% hint style="info" %}
If your project's `minSdkVersion` is already >= 26, the `expo-build-properties` plugin is not needed.
{% endhint %}

#### Plugin Options

| Option                     | Required | Description                                                            |
| -------------------------- | -------- | ---------------------------------------------------------------------- |
| `database`                 | **Yes**  | BugSplat database name                                                 |
| `enableSymbolUpload`       | No       | Enable automatic symbol upload for iOS (dSYMs) and Android (.so files) |
| `symbolUploadClientId`     | No       | BugSplat API client ID (or set `BUGSPLAT_CLIENT_ID` env var)           |
| `symbolUploadClientSecret` | No       | BugSplat API client secret (or set `BUGSPLAT_CLIENT_SECRET` env var)   |

### Usage 🧑‍💻

#### Initialization

Call `init()` before using any other BugSplat functions. Replace `your-database`, `YourApp`, and `1.0.0` with your BugSplat database name, application name, and version.

```typescript
import { init } from '@bugsplat/expo';

await init('your-database', 'YourApp', '1.0.0', {
  userName: 'user@example.com',
  userEmail: 'user@example.com',
  appKey: 'optional-key',
});
```

**Options:**

* `appKey?: string`: Queryable metadata key
* `userName?: string`: User name for reports
* `userEmail?: string`: User email for reports
* `autoSubmitCrashReport?: boolean`: Auto-submit crashes (iOS only, default: `true`)
* `attributes?: Record<string, string>`: Custom key-value attributes
* `attachments?: string[]`: File paths to attach (native only)
* `description?: string`: Default description

#### Reporting Errors

Manually report caught errors using `post()`:

```typescript
import { post } from '@bugsplat/expo';

try {
  riskyOperation();
} catch (error) {
  const result = await post(error);
  console.log(result.success ? 'Reported!' : result.error);
}
```

#### Error Boundary

Wrap your component tree in `<ErrorBoundary>` to catch React render errors and report them to BugSplat automatically. This works on all platforms: iOS, Android, and Web.

```tsx
import { ErrorBoundary } from '@bugsplat/expo';

function App() {
  return (
    <ErrorBoundary fallback={<Text>Something went wrong</Text>}>
      <MyComponent />
    </ErrorBoundary>
  );
}
```

The `fallback` prop accepts a React node or a render function:

```tsx
<ErrorBoundary
  fallback={({ error, resetErrorBoundary }) => (
    <View>
      <Text>{error.message}</Text>
      <Button title="Try again" onPress={resetErrorBoundary} />
    </View>
  )}
>
  <MyComponent />
</ErrorBoundary>
```

#### User Feedback

In addition to crash reporting, BugSplat supports collecting non-crashing user feedback such as bug reports and feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title. This works on all platforms: iOS, Android, and Web.

Submit feedback imperatively from anywhere after `init()`:

```typescript
import { postFeedback } from '@bugsplat/expo';

const result = await postFeedback('Login button broken', {
  description: 'Nothing happens when I tap sign in',
});
console.log(result.success ? `Feedback #${result.crashId} posted` : result.error);
```

**Options:**

* `description?: string`: Longer body of the feedback
* `user?: string`: Override default user name
* `email?: string`: Override default user email
* `appKey?: string`: Override default app key

Or drive a feedback form with the `useFeedback` hook, which tracks loading and error state:

```tsx
import { useFeedback } from '@bugsplat/expo';

function FeedbackForm() {
  const { postFeedback, loading, error } = useFeedback();

  return (
    <Button
      title={loading ? 'Sending…' : 'Send feedback'}
      disabled={loading}
      onPress={() =>
        postFeedback('Login button broken', {
          description: 'Nothing happens when I tap sign in',
        })
      }
    />
  );
}
```

#### User Info

Update user info for subsequent reports:

```typescript
import { setUser } from '@bugsplat/expo';

setUser('Jane Doe', 'jane@example.com');
```

#### Attributes

Set custom key-value attributes that are searchable in the BugSplat dashboard:

```typescript
import { setAttribute } from '@bugsplat/expo';

setAttribute('environment', 'production');
```

{% hint style="info" %}
Custom attributes via `setAttribute` are not supported on web.
{% endhint %}

### Symbol Upload 📦

Production crash reports require debug symbols to produce readable stack traces. When `enableSymbolUpload` is set in your plugin config, symbols are uploaded automatically during iOS and Android release builds.

For manual uploads or CI/CD workflows, use [`@bugsplat/symbol-upload`](https://github.com/BugSplat-Git/symbol-upload):

```sh
npm install --save-dev @bugsplat/symbol-upload
```

**iOS dSYMs:**

```sh
npx @bugsplat/symbol-upload \
  -b your-database -a YourApp -v 1.0.0 \
  -i $BUGSPLAT_CLIENT_ID -s $BUGSPLAT_CLIENT_SECRET \
  -d /path/to/build/Products/Release-iphoneos \
  -f "**/*.dSYM"
```

**Android .so files:**

```sh
npx @bugsplat/symbol-upload \
  -b your-database -a YourApp -v 1.0.0 \
  -i $BUGSPLAT_CLIENT_ID -s $BUGSPLAT_CLIENT_SECRET \
  -d android/app/build/intermediates/merged_native_libs \
  -f "**/*.so" -m
```

**JavaScript source maps** (after `npx expo export --source-maps`):

```sh
npx @bugsplat/symbol-upload \
  -b your-database -a YourApp -v 1.0.0 \
  -i $BUGSPLAT_CLIENT_ID -s $BUGSPLAT_CLIENT_SECRET \
  -d dist \
  -f "**/*.map"
```

Run `npx @bugsplat/symbol-upload --help` for all options.

### Testing Native Crashes 🧪

To test native crash reporting, you must run a **release build**, because the debugger intercepts crashes in debug builds.

```sh
# iOS
npx expo run:ios --configuration Release

# Android
npx expo run:android --variant release
```

Trigger a test crash to verify your integration:

```typescript
import { crash } from '@bugsplat/expo';

// Triggers a native crash (iOS/Android) or throws an error (web)
crash();
```

{% hint style="info" %}
**iOS:** Crash reports are captured at crash time and **uploaded on the next app launch** when `init()` is called again. After triggering a test crash, relaunch the app to upload the pending report.

**Android:** Crash reports are captured and **uploaded immediately at crash time** by the Crashpad handler process.
{% endhint %}

### Troubleshooting 🔧

#### Android: Crashes not uploading on emulator

The Crashpad handler process requires native libraries to be extracted to disk. The `@bugsplat/expo` config plugin sets `extractNativeLibs=true` automatically. If you're still not seeing crashes:

* Use a **`google_apis`** emulator image (not `google_apis_playstore`). The Play Store emulator images have restrictions that prevent Crashpad's handler process from executing.
* Alternatively, test on a **physical Android device** where this is not an issue.

#### iOS: No crash report after test crash

Make sure you **relaunch the app and call `init()` again** after the crash. PLCrashReporter saves the crash to disk and uploads it on the next launch.

{% hint style="info" %}
**Not finding what you're looking for?** Please reach out to <support@bugsplat.com> for further assistance.
{% endhint %}


# Web

The web platform is an increasingly popular solution for delivering highly approachable and highly visible applications. Web applications are often the primary means of communication between your business and your customers. Businesses can't afford to put anything less than their best foot forward. BugSplat crash reporting can help your team dance their way toward more stable web applications. BugSplat also supports server-side JavaScript and TypeScript runtimes, including [Node.js](/integrations/web/node.js) and [Deno](/integrations/web/deno).

{% content-ref url="/pages/-MeQxcg-zqaGITt11RPi" %}
[Angular](/integrations/web/angular)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg29AcvRgz8fAyWms6Y" %}
[JavaScript](/integrations/web/javascript)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg293QjQow3zAIW7VHg" %}
[React](/integrations/web/react)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg296jB18ShFc9aUbC9" %}
[Vue](/integrations/web/vue)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRXRpKp3KQxkGy3IUU" %}
[Node.js](/integrations/web/node.js)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRTIcz\_lnLU8uBeCz-" %}
[Deno](/integrations/web/deno)
{% endcontent-ref %}

{% hint style="info" %}
**Not finding what you're looking for?** Please reach out to <support@bugsplat.com> to request the language or environment you'd like BugSplat to integrate with next!
{% endhint %}


# Angular

### ⚙️ Integration

To collect errors and crashes in your Angular application, run the following command in the terminal at the root of your project to install [bugsplat-ng](https://github.com/BugSplat-Git/bugsplat-ng):

```bash
npm i bugsplat-ng --save
```

Add a `database` property in your package.json that corresponds to your BugSplat database:

```json
{
  "database": "your_bugsplat_database"
}
```

Add values for your BugSplat `database`, `application`, and `version` to your application's environment files.

[environment.prod.ts](https://github.com/BugSplat-Git/bugsplat-ng/blob/8c12d9b3544f2b618491467e6c40d84b6139eb2a/src/environments/environment.prod.ts#L1)

```javascript
const packageJson = require('../../package.json');
export const environment = {
  production: true,
  bugsplat: {
    database: packageJson.database,
    application: packageJson.name,
    version: packageJson.version
  }
};
```

For Angular applications using standalone components, import and configure BugSplat directly in your `main.ts` file:

[main.ts](https://github.com/BugSplat-Git/bugsplat-ng/blob/22fa88dc642294f1a6240a0a1bf4b4acd16f727d/projects/my-angular-crasher/src/main.ts#L6-L29)

```typescript
import { BugSplatModule } from 'bugsplat-ng';

bootstrapApplication(AppComponent, {
  providers: [
    importProvidersFrom(
      BugSplatModule.initializeApp(environment.bugsplat)
    )
  ]
})
.catch(err => console.log(err));
```

Alternatively, add an import for `BugSplatModule` to your `AppModule`:

```typescript
import { BugSplatModule } from 'bugsplat-ng';

@NgModule({
  imports: [
    BugSplatModule.initializeApp(environment.bugsplat)
  ]
})
```

Throw a new error in your application to test the bugsplat-ng integration:

[app.component.ts](https://github.com/BugSplat-Git/bugsplat-ng/blob/8c12d9b3544f2b618491467e6c40d84b6139eb2a/src/app/app.component.ts#L37)

```typescript
throw new Error("foobar!");
```

Navigate to the [Crashes](https://app.bugsplat.com/v2/crashes) page in BugSplat, and you should see a new crash report for the application you just configured. Click the link in the ID column to see details about your crash on the Crash page:

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FHM6PC096udwXz5w071lJ%2Fimage.png?alt=media&amp;token=fbe6d06c-15c5-42d6-a635-fcca79ecaf48" alt=""><figcaption></figcaption></figure>

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FscS0fNmPKQ3XFOtzXYCC%2Fimage.png?alt=media&amp;token=e3a55656-36e3-4537-80a3-d9a14f6c3573" alt=""><figcaption></figcaption></figure>

### 🗺 Source Maps

BugSplat supports unwinding uglified and minified JavaScript stack traces via source maps. To upload source maps to BugSplat during your build, install [@bugsplat/symbol-upload](https://www.npmjs.com/package/@bugsplat/symbol-upload).

```bash
npm i -D @bugsplat/symbol-upload
```

Configure your `angular.json` file to output source maps. We suggest enabling source maps for both your application code and any vendor chunks generated by Angular.

```json
{
  "projects": {
    "main": {
      "architect": {
        "build": {
          "options": {
            "sourceMap": {
              "scripts": true,
              "styles": true,
              "vendor": true
            },
          },
        }
      }
    }
  }
}
```

Add `SYMBOL_UPLOAD_CLIENT_ID` and `SYMBOL_UPLOAD_CLIENT_SECRET` environment variables for the BugSplat user that you will use to upload symbols. You can create these values as system environment variables or use [dotenv](https://www.npmjs.com/package/dotenv).

```
SYMBOL_UPLOAD_CLIENT_ID=your-client-id
SYMBOL_UPLOAD_CLIENT_SECRET=your-client-secret
```

Add a script to `package.json` that reads a `.env` file and calls `symbol-upload` to upload source maps after your production build. Replace `my-angular-crasher` with the name of your Angular project.

```json
{
  "scripts": {
    "postbuild": "node -r dotenv/config ./node_modules/@bugsplat/symbol-upload/dist/bin/index.js -d ./dist/my-angular-crasher/browser"
  }
}
```

For best results, please upload source maps for every released version of your application.

### 🧰 Extended Integration

You can post additional information by creating a service that implements ErrorHandler. In the `handlerError` method, make a call to `BugSplat.post` passing it the error and an optional options object:

[my-angular-error-handler.ts](https://github.com/BugSplat-Git/bugsplat-ng/blob/main/projects/my-angular-crasher/src/app/my-angular-error-handler.ts)

```
import { ErrorHandler, Injectable } from '@angular/core';
import { BugSplat } from 'bugsplat-ng';

@Injectable()
export class MyAngularErrorHandler implements ErrorHandler {

    constructor(public bugsplat: BugSplat) { }
    
    async handleError(error: Error): Promise<void> {
        return this.bugsplat.post(error, {
            description: 'New description from MyAngularErrorHandler.ts'
        });
    }
}
```

BugSplat provides the following properties and methods that allow you to customize its functionality:

[bugsplat.ts](https://github.com/BugSplat-Git/bugsplat-ng/blob/master/projects/bugsplat-ng/src/lib/bugsplat.ts)

```
BugSplat.description: string; // Additional info about your crash that gets reset after every post
BugSplat.email: string; // The email of your user 
BugSplat.key: string; // A unique identifier for your application
BugSplat.user: string; // The name or id of your user
BugSplat.files: Array<file>; // A list of files to be uploaded at post time
BugSplat.getObservable(): Observable<BugSplatPostEvent>; // Observable that emits BugSplat crash post events results in your components.
async BugSplat.post(error): Promise<void>; // Post an Error object to BugSplat manually from within a try/catch
```

In either `bootstrapApplication` or `NgModule`, add a provider for your new `ErrorHandler`:

[main.ts](https://github.com/BugSplat-Git/bugsplat-ng/blob/22fa88dc642294f1a6240a0a1bf4b4acd16f727d/projects/my-angular-crasher/src/main.ts#L6-L29)

```typescript
import { BugSplatModule } from 'bugsplat-ng';
import { MyAngularErrorHandler } from './app/my-angular-error-handler';

bootstrapApplication(AppComponent, {
  providers: [
    importProvidersFrom(
      BugSplatModule.initializeApp(environment.bugsplat)
    ),
    {
      provide: ErrorHandler,
      useClass: MyAngularErrorHandler
    }
  ]
})
.catch(err => console.log(err));
```

You can also configure BugSplat's logging preferences and provide your own logging implementation. Create a provider for BugSplatLogger with useValue set to a new instance of BugSplatLogger. Pass one of the BugSplatLogLevel options as the first parameter to BugSplatLogger. You can provide an instance of your own custom logger as the second parameter granted it has an error, warn, info, and log methods. If no custom logger is provided, the console will be used:

[main.ts](https://github.com/BugSplat-Git/bugsplat-ng/blob/22fa88dc642294f1a6240a0a1bf4b4acd16f727d/projects/my-angular-crasher/src/main.ts#L6-L29)

```typescript
import { BugSplatLogger, BugSplatLogLevel, BugSplatModule } from 'bugsplat-ng';
import { MyAngularErrorHandler } from './app/my-angular-error-handler';

bootstrapApplication(AppComponent, {
  providers: [
    importProvidersFrom(
      BugSplatModule.initializeApp(environment.bugsplat)
    ),
    {
      provide: ErrorHandler,
      useClass: MyAngularErrorHandler
    },
    {
      provide: BugSplatLogger,
      useValue: new BugSplatLogger(BugSplatLogLevel.log)
    }
  ]
})
.catch(err => console.log(err));
```

### 💬 User Feedback

In addition to crash reporting, BugSplat supports collecting non-crashing user feedback such as bug reports and feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title.

Inject the `BugSplat` service and call `postFeedback`:

```typescript
import { Component } from '@angular/core';
import { BugSplat } from 'bugsplat-ng';

@Component({ ... })
export class FeedbackComponent {
  constructor(private bugsplat: BugSplat) {}

  async submitFeedback() {
    await this.bugsplat.postFeedback('Login button broken', {
      description: 'Nothing happens when I tap it',
      email: 'jane@example.com',
    });
  }
}
```

You can also attach files such as screenshots:

```typescript
async submitWithScreenshot(file: File) {
  await this.bugsplat.postFeedback('UI rendering issue', {
    description: 'The sidebar overlaps the main content.',
    attachments: [
      { filename: file.name, data: file },
    ],
  });
}
```

### 🧑‍🏫 Sample

This repository includes a sample `my-angular-crasher` application that has been pre-configured with BugSplat. Get started by cloning the repository and navigating to the root of the project:

```bash
git clone https://github.com/BugSplat-Git/bugsplat-ng
cd bugsplat-ng
```

Before you can run the app, you'll need to create an OAuth2 Client ID & Client Secret pair that corresponds to your BugSplat database, as shown [here](https://docs.bugsplat.com/introduction/development/web-services/oauth2). Please also take note of the BugSplat `database` that this OAuth2 Client ID & Client Secret pair corresponds to.

First, add a `database` property in your package.json that corresponds to your BugSplat database:

```json
{
  "database": "your_bugsplat_database"
}
```

Next, create a [dotenv](https://github.com/motdotla/dotenv) file with the name `.env` at the root of the repository and populate it with the correct values substituted for `your-client-id` and `your-client-secret`:

```
SYMBOL_UPLOAD_CLIENT_ID=your-client-id
SYMBOL_UPLOAD_CLIENT_SECRET=your-client-secret
```

To start the sample app, run `npm start` in the root of the repository.

```
npm start
```

The `npm start` command will build the sample application and upload [source maps](https://docs.bugsplat.com/introduction/development/working-with-symbol-files/source-maps) to BugSplat so that the JavaScript call stack can be mapped back to TypeScript. Once the build has completed, the source maps will be uploaded and `http-server` will serve the app.

Navigate to the URL displayed in the console by `http-server` (usually [localhost:8080](http://127.0.0.1:8080/)). Click any button in the sample app to generate an error report. A link to the error report should display in the app shortly after clicking a button. Click the link to the error report, and when prompted, log in to BugSplat.

If everything worked correctly, you should see information about your error as well as a TypeScript stack trace.

### 🧑‍💻 Contributing

BugSplat loves open-source software! If you have suggestions on how we can improve this integration, please reach out to <support@bugsplat.com>, create an [issue](https://github.com/BugSplat-Git/bugsplat-ng/issues) in our [GitHub repo](https://github.com/BugSplat-Git/bugsplat-ng) or send us a [pull request](https://github.com/BugSplat-Git/bugsplat-ng/pulls).

With ❤️,

The BugSplat Team


# JavaScript

## 🧩 SPA Integrations

{% hint style="info" %}
BugSplat supports unwinding uglified and minified JavaScript stack traces via source maps. More information about configuring your application to upload source maps to BugSplat is available [here](/guides/working-with-symbol-files/source-maps).
{% endhint %}

BugSplat supports JavaScript and TypeScript error reporting in a variety of environments. We offer platform-specific integrations for [Angular](https://angular.dev/), [React](https://react.dev/), and [Node.js](https://nodejs.org/en) for your convenience.

Follow the links below for instructions on how to configure BugSplat in your application:

{% content-ref url="/pages/-MeQxcg-zqaGITt11RPi" %}
[Angular](/integrations/web/angular)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg293QjQow3zAIW7VHg" %}
[React](/integrations/web/react)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg296jB18ShFc9aUbC9" %}
[Vue](/integrations/web/vue)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRTrBwNQFMT8JiWLql" %}
[Electron](/integrations/desktop/electron)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRXRpKp3KQxkGy3IUU" %}
[Node.js](/integrations/web/node.js)
{% endcontent-ref %}

If a platform or framework your team is leveraging is not listed above, never fear! You can leverage our bugsplat [npm package](https://www.npmjs.com/package/bugsplat) to add error reporting to any browser-based app or [bugsplat-node](https://www.npmjs.com/package/bugsplat-node) to add error reporting to any Node.js based app.

## 🌐 Browsers

Using the browser directly is awesome! BugSplat fully supports applications that don't use SPA frameworks. Follow the directions below to integrate with bugsplat in a browser-based JavaScript application.

### ⚙️ Integrating

Import [bugsplat](https://github.com/BugSplat-Git/bugsplat-js) from [esm.sh](https://esm.sh/)

```html
<script type="module">
    import { BugSplat } from 'https://esm.sh/bugsplat@8.0.1';
</script>
```

Create a new instance of BugSplat with your database, application, and version

```javascript
const bugsplat = new BugSplat('fred', 'my-javascript-crasher', '1.0.0');
```

Configure bugsplat to listen to `window.onerror` and `window.onunhandledrejection` events

```javascript
window.onerror = function (message, source, lineno, colno, error) {
    bugsplat.post(error);
};

window.addEventListener('unhandledrejection', function (event) {
    bugsplat.post(event.reason);
});
```

Trigger an error to see it reported in BugSplat

```javascript
throw new Error('todo bg');
```

### 💬 User Feedback

In addition to crash reporting, BugSplat supports collecting non-crashing user feedback such as bug reports and feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title.

```javascript
await bugsplat.postFeedback('Login button broken', {
    description: 'Nothing happens when I tap it',
    email: 'jane@example.com',
});
```

You can also attach files such as screenshots:

```javascript
const screenshot = document.querySelector('input[type="file"]').files[0];

await bugsplat.postFeedback('UI rendering issue', {
    description: 'The sidebar overlaps the main content.',
    attachments: [
        { filename: 'screenshot.png', data: screenshot },
    ],
});
```

### 🧪 Sample

Clone the [my-javascript-crasher](https://github.com/BugSplat-Git/my-javascript-crasher) repository

```sh
git clone https://github.com/BugSplat-Git/my-javascript-crasher
```

Install the dependencies

```sh
cd my-javascript-crasher
npm i
```

Start the server

```shell
npm start
```

Open your browser and navigate to [http://localhost:8080](http://localhost:8080/), then click the button to trigger an error.

### 📈 Viewing Reports

Navigate to the BugSplat [Crashes](https://app.bugsplat.com/v2/crashes?database=Fred\&c0=appName\&f0=CONTAINS\&v0=my-javascript-crasher) page to view your report

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-dbc004621a7c3390beacb55101858625f9ef6fe0%2Fimage.png?alt=media" alt=""><figcaption><p>BugSplat Crashes Page</p></figcaption></figure>

Click on the ID of the most recent error to view the details of your report

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-9c678d20ff0d71f758569888e029f8581ba25600%2Fimage.png?alt=media" alt=""><figcaption><p>BugSplat Crash Page</p></figcaption></figure>


# React

## Overview

BugSplat supports the collection of errors in React applications. The [@bugsplat/react](https://www.npmjs.com/package/@bugsplat/react) npm package implements an [ErrorBoundary](https://reactjs.org/docs/error-boundaries.html) component in order to capture rendering errors in child components and post them to BugSplat where they can be tracked and managed. Adding BugSplat to your React application is extremely easy.

## Get Started

To start using BugSplat in your React application, run the following command at the root of your project. This will install @bugsplat/react and it's sub-dependency, [bugsplat](https://github.com/BugSplat-Git/bugsplat-js).

```shell
npm i @bugsplat/react --save
```

In addition to standard `package.json` properties `name` and `version`, include a `database` property to your `package.json` file with the value of your BugSplat database. Make sure to replace `{{YOUR_DATABASE_NAME}}` with your actual database name.

```
// package.json
{
  "name": "my-app",
  "version": "1.2.0",
  "database": "{{YOUR_DATABASE_NAME}}"
  // ...
}
```

In the root of your project, import your project's `package.json`. Use it's `name`, `database`, and `version` properties to initialize the BugSplat client for sending crashes. This will instantiate a new client instance and store it internally.

```jsx
// src/index.tsx

import { createRoot } from 'react-dom/client';
import { init } from '@bugsplat/react';
import App from './App';
import * as packageJson from '../package.json';

init({
  database: packageJson.database,
  application: packageJson.name,
  version: packageJson.version,
});

const root = createRoot(document.getElementById('root'));

root.render(<App />);
```

You can now wrap your component trees with `ErrorBoundary` to capture rendering errors and automatically post them to BugSplat with the internal client instance we initialized earlier.

```jsx
// src/App.tsx

import { ErrorBoundary } from '@bugsplat/react';

export default function App() {
  return (
    <ErrorBoundary fallback={<h1>Oops, there was a problem.</h1>}>
      <Content>...</Content>
    </ErrorBoundary>
  );
}
```

You can also access the stored `BugSplat` instance anywhere by calling `getBugSplat()`

```jsx
// src/App.tsx

import { getBugSplat } from '@bugsplat/react';

export default function App() {
  const handleClick = () => {
    getBugSplat().post('There was a problem');
  };

  return (
    <div>
      <h1>Hello, world!</h1>
      <button onClick={handleClick}>Post Error Report</button>
    </div>
  );
}
```

## Further Integration

Want your error boundary to also handle errors that are not caught by `ErrorBoundary`, such as async errors or event handlers? No problem! `useErrorHandler` to the rescue. Pass your error to the callback returned from `useErrorHandler` in order to propagate the error to the nearest `ErrorBoundary`. You can also pass your error directly to `useErrorHandler` if you manage the error state yourself or get it from another library.

```jsx
// src/App.tsx

import { useState } from 'react'
import { ErrorBoundary, useErrorHandler } from '@bugsplat/react';

function NestedComponent() {
  const handleError = useErrorHandler();

  const handleClick = async () => {
    try {
      await doThing();
    } catch (err) {
      handleError(err);
    }
  };

  return <button onClick={handleClick}>Do Thing</button>;
}

function NestedComponent2() {
  const [error, setError] = useState<Error>()

  useErrorHandler(error)

  const handleClick = async () => {
    try {
      await doThing()
    } catch (err) {
      setError(err)
    }
  }

  return <button onClick={handleClick}>Do Thing</button>;
}

export default function App() {
  return (
    <ErrorBoundary fallback={<h1>Oops, there was a problem.</h1>}>
      <NestedComponent />
      <NestedComponent2 />
    </ErrorBoundary>
  );
}
```

Providing an instance of BugSplat will allow `ErrorBoundary` to automatically post errors it catches to BugSplat.

The `ErrorBoundary` component is packed with props that can be used to customize it to fit your needs:

* `fallback`
* `onMount`
* `onUnmount`
* `onError`
* `beforePost`
* `onReset`
* `onResetKeysChange`
* `disablePost`

We strongly recommend passing a `fallback` prop that will be rendered when `ErrorBoundary` encounters an error.

The `fallback` prop can be any valid element:

```jsx
function Component() {
  return (
    <ErrorBoundary fallback={<div>Oops, there was a problem.</div>}>
      ...
    </ErrorBoundary>
  );
}
```

...or a function that renders one

```jsx
function Component() {
  return (
    <ErrorBoundary
      fallback={(fallbackProps) => <div>Oops, there was a problem.</div>}
    >
      ...
    </ErrorBoundary>
  );
}
```

If `fallback` is a function, it will be called with

* `error` - the error caught be `ErrorBoundary`
* `componentStack` - the component stack trace of the error
* `response` - the BugSplat response of posting error to BugSplat, if applicable
* `resetErrorBoundary` - a function to call in order to reset the `ErrorBoundary` state

The fallback will render any time the `ErrorBoundary` catches an error. It is useful to have a fallback UI to gracefully handle errors for your users, while still sending errors to BugSplat behind the scenes.

`ErrorBoundary` accepts a `resetKeys` prop that you can pass with an array of values that will cause it to automatically reset if one of those values changes. This gives you the power to control the error state from outside of the component.

```jsx
function App() {
  const [error, setError] = useState<Error | null>();

  return (
    <ErrorBoundary
      fallback={(props) => <Fallback {...props} />}
      onReset={() => setError(null)}
      resetKeys={[error]}
    >
      {}
    </ErrorBoundary>
  );
}
```

## Advanced Usage

### The `scope` property

If you know what you're doing and want ErrorBoundary functionality beyond what is possible through props and callbacks, you can extend the BugSplat client and pass it to the ErrorBoundary through it's `scope` property.

```jsx
import { BugSplat } from 'bugsplat';
import { ErrorBoundary } from '@bugsplat/react';
import SomeService from '@some/service';

class CustomBugSplatClient extends BugSplat {
  async post(error: CustomError) {
    await SomeService.post(error);

    return super.post(error);
  }
}

const client = new CustomBugSplatClient();

function App() {
  <ErrorBoundary scope={{ getClient: () => client }}>
    <ChildComponents />
  </ErrorBoundary>;
}
```

## API

This package re-exports all exports from [bugsplat-js](https://github.com/BugSplat-Git/bugsplat-js).

### `init()`

```ts
interface BugSplatInit {
  /**
   * BugSplat database name that crashes should be posted to
   */
  database: string;
  /**
   * Name of application
   */
  application: string;
  /**
   * Version of application.
   */
  version: string;
}

/**
 * Initialize a new BugSplat instance and store the reference in scope
 *
 * @returns function with a callback argument that will be
 * called with the freshly initialized BugSplat instance
 *
 * - Useful to subscribe to events or set default properties
 */
export function init({
  database,
  application,
  version,
}: BugSplatInit): (initializer: (client: BugSplat) => void) => void;

/**
 * @example
 */
init({
  database: 'fred',
  application: 'my-react-crasher',
  version: '3.2.1',
})((bugSplat) => {
  bugSplat.setDefaultAppKey('Key!');
  bugSplat.setDefaultUser('User!');
  bugSplat.setDefaultEmail('fred@bedrock.com');
  bugSplat.setDefaultDescription('Description!');
});
```

### `getBugSplat()`

```ts
/**
 * Get `BugSplat` instance from application scope
 */
const getBugSplat: () => BugSplat | null;
```

### `ErrorBoundary`

```typescript
interface FallbackProps {
  /**
   * Error that caused crash
   */
  error: Error;
  /**
   * Component stack trace leading to error
   */
  componentStack: string | null;
  /**
   * Crash post response
   */
  response: BugSplatResponse | null;
  /**
   * Reset error boundary state.
   *
   * This will pass any arguments to the end of onReset when it is called
   */
  resetErrorBoundary: (...args: unknown[]) => void;
}

type FallbackElement = ReactElement | null;

type FallbackRender = (props: FallbackProps) => FallbackElement;

/**
 * All props in ErrorBoundaryProps are optional,
 * but we recommend at least setting the fallback prop.
 */
interface ErrorBoundaryProps {
  /**
   * Callback called before error post to BugSplat.
   *
   * This will be awaited if it is a promise
   */
  beforePost: (
    bugSplat: BugSplat,
    error: Error | null,
    componentStack: string | null
  ) => void | Promise<void>;

  /**
   * Callback called when ErrorBoundary catches an error in componentDidCatch()
   *
   * This will be awaited if it is a promise
   */
  onError: (
    error: Error,
    componentStack: string,
    response: BugSplatResponse | null
  ) => void | Promise<void>;

  /**
   * Callback called on componentDidMount().
   */
  onMount: () => void;

  /**
   * Callback called on componentWillUnmount().
   */
  onUnmount: (state: ErrorBoundaryState) => void;

  /**
   * Callback called before ErrorBoundary resets internal state,
   * resulting in rendering children again. This should be
   * used to ensure that rerendering of children would not
   * repeat the same error that occurred.
   *
   * *This method is not called when ErrorBoundary is reset from a
   * change in resetKeys - use onResetKeysChange for that.*
   * @param state - Current error boundary state
   * @param ...args - Additional arguments passed from where it is called
   */
  onReset: (state: ErrorBoundaryState, ...args: unknown[]) => void;

  /**
   * Callback called when keys passed to resetKeys are changed.
   */
  onResetKeysChange: (prevResetKeys?: unknown[], resetKeys?: unknown[]) => void;

  /**
   * Array of values passed from parent scope. When ErrorBoundary
   * is in an error state, it will check each passed value
   * and automatically reset if any of the values have changed.
   */
  resetKeys?: unknown[];

  /**
   * Provide a fallback to render when ErrorBoundary catches an error.
   * Not required, but it is highly recommended to provide a value for this.
   *
   * This can be an element or a function that renders an element.
   */
  fallback?: FallbackElement | FallbackRender;

  /**
   * If true, caught errors will not be automatically posted to BugSplat.
   */
  disablePost?: boolean;

  /**
   * Child elements to be rendered when there is no error
   */
  children?: ReactNode | ReactNode[];

  /**
   * __Advanced Use__
   *
   * Object used by ErrorBoundary to retrieve a BugSplat client instance.
   *
   * Advanced users can extend the `BugSplat` class and use this property
   * to pass their own scope that will inject the client for use by
   * ErrorBoundary.
   */
  scope: { getClient(): BugSplat | null };
}

interface ErrorBoundaryState {
  error: Error | null;
  componentStack: string | null;
  response: BugSplatResponse | null;
}

/**
 * Handle errors that occur during rendering by wrapping
 * your component tree with ErrorBoundary. Any number of ErrorBoundary
 * components can be rendered in the tree and any rendering error will
 * propagate to the nearest one.
 */
class ErrorBoundary extends Component<
  ErrorBoundaryProps,
  ErrorBoundaryState
>
```

### `withErrorBoundary`

```typescript
/**
 * Higher order component to wrap your component tree with ErrorBoundary
 */
function withErrorBoundary<P extends Record<string, unknown>>(
  Component: ComponentType<P>,
  errorBoundaryProps: ErrorBoundaryProps = {}
): ComponentType<P>;
```

### `useErrorHandler`

```typescript
/**
 * Utility hook to declaratively or imperatively propagate an
 * error to the nearest error boundary.
 *
 * *Should be called from a child of ErrorBoundary*
 *
 * Propagate error:
 *
 * * Declaratively - by passing an error prop
 * * Imperatively - by calling the returned handler with an error
 *
 * @param errorProp - Will throw when a truthy value is passed
 * @returns Error handler that will throw when called with a truthy value
 */
function useErrorHandler(errorProp?: unknown): (error: unknown) => void;
```

## User Feedback

In addition to crash reporting, BugSplat supports collecting non-crashing user feedback such as bug reports and feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title.

### Using the `useFeedback` hook

The `@bugsplat/react` package provides a `useFeedback` hook for submitting feedback:

```jsx
import { useFeedback } from '@bugsplat/react';

function FeedbackForm() {
  const { postFeedback, loading, error } = useFeedback();

  const handleSubmit = async () => {
    await postFeedback('Login button broken', {
      description: 'Nothing happens when I tap it',
      email: 'jane@example.com',
    });
  };

  return (
    <button onClick={handleSubmit} disabled={loading}>
      Send Feedback
    </button>
  );
}
```

### Attaching files

You can attach files such as screenshots:

```jsx
const handleSubmit = async (file: File) => {
  await postFeedback('UI rendering issue', {
    description: 'The sidebar overlaps the main content.',
    attachments: [
      { filename: file.name, data: file },
    ],
  });
};
```

### Using the client directly

You can also call `postFeedback` directly on the BugSplat client instance:

```jsx
import { getBugSplat } from '@bugsplat/react';

const client = getBugSplat();
await client.postFeedback('Feature request', {
  description: 'It would be great to have dark mode.',
});
```

## Test Suite

This package contains both unit and integration tests. To run them, use the package.json scripts provided.

| Tests       | Command                    |
| ----------- | -------------------------- |
| Unit        | `npm run test`             |
| Integration | `npm run test:integration` |

### **Contributing**

BugSplat ❤️s open source! If you feel that this integration can be improved, please open an [Issue](https://github.com/BugSplat-Git/bugsplat-react/issues). If you have an awesome new feature you'd like to implement, we'd love to merge your [Pull Request](https://github.com/BugSplat-Git/bugsplat-react/pulls). You can also reach out to us via an email to <support@bugsplat.com> or the in-app chat on bugsplat.com.


# Vue

## Integration

To begin integrating your app with BugSplat, install the bugsplat package via npm:

```
npm i bugsplat
```

Import or require BugSplat at the entry point of your application.

```typescript
import { BugSplat } from 'bugsplat';
```

Add a database property to your package.json.

```typescript
{
  "name": "my-vue-crasher",
  "version": "1.0.0",
  "database": "{{ your database here}}",
  ...
}
```

In index.js, create a new instance of BugSplat passing the constructor values for database, application, and version from your package.json.

```typescript
const packageJson = require('../package.json');
const bugsplat = new BugSplat(packageJson.database, packageJson.name, packageJson.version);
```

Add event handlers to window\.onunhandledrejection and window\.onerror so that errors are posted to BugSplat.

```typescript
window.onunhandledrejection = async (rejection) => {
  await bugsplat.post(rejection.reason);
}

window.onerror = async (event, source, lineno, colno, error) => {
  await bugsplat.post(error);
}
```

You can also use BugSplat to capture errors in catch blocks.

```typescript
try {
    throw new Error('BugSplat rocks!');
} catch (error) {
    await bugsplat.post(error);
}
```

After posting an error, navigate to the [Crashes](https://app.bugsplat.com/v2/crashes) page in BugSplat and you should see a new error report for the application you just configured. Click the link in the ID column to see details about your crash on the Crash page.


# Node.js

## Configuration

To add the bugsplat package to your application, run the following shell command at the root of your project’s directory:

```bash
npm i bugsplat-node --save
```

Require bugsplat at the entry point of your application (usually main.js) by adding the following code snippet:

```typescript
const { BugSplatNode } = require('bugsplat-node');
```

Create a new instance of the BugSplat class being sure to replace the database, application, and version with the correct values for your application:

```typescript
const bugsplat = new BugSplatNode(database, application, version);
```

Set the bugsplat.post function as an event handler for uncaught exceptions:

```typescript
process.on('uncaughtException', async (error) => await bugsplat.postAndExit(error));
```

You will also want to listen for unhandled promise rejections. Please note that this will only work for native promises:

```typescript
process.on('unhandledRejection', async (error) => await bugsplat.postAndExit(error))
```

Throw an exception after the event handler has been added:

```typescript
throw new Error('BugSplat!');
```

You can also use bugsplat-node to post errors from non-fatal promise rejections and errors that originate inside of try-catch blocks:

```typescript
Promise.reject(new Error('BugSplat!')).catch(async (error) => await bugsplat.post(error, options));
```

```typescript
try {
  throw new Error('BugSplat!');
} catch (error) {
  await bugsplat.post(error, options);
}
```

After posting an error with bugsplat-node, navigate to the [Crashes](https://app.bugsplat.com/v2/crashes) page in BugSplat and you should see a new crash report for the application you just configured. Click the link in the ID column to see details about your crash on the Crash page:

![Node.js Crashes](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2Fsync%2Fbb76c0c2a92cce59e74075ef297dea547c7ee044.png?generation=1631198778305798\&alt=media)

![Node.js Crash](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-MeRQauxiHezSfRqR_hS%2F-MeRYBdECmqfJRzNVQYo%2Felectron-node-js-crash.png?alt=media\&token=44ef0860-2961-411c-a6af-68f6dbbff027)

That’s it! Your application is now configured to post crash reports to BugSplat.

### Source Maps

BugSplat has the ability to map uglified and minified JavaScript function names, file names, and line numbers back to their original values via source maps. For information on how to configure your application to upload source maps to BugSplat, please see the link below.

{% content-ref url="/pages/-Mg\_UpA3JIjWidH0gSp6" %}
[Source Maps](/guides/working-with-symbol-files/source-maps)
{% endcontent-ref %}

### API

In addition to the configuration demonstrated above, there are a few public methods that can be used to customize your BugSplat integration:

```typescript
bugsplat.setDefaultAppKey(appKey); // Additional metadata that can be queried via BugSplat's web application
bugsplat.setDefaultUser(user); // The name or id of your user
bugsplat.setDefaultEmail(email); // The email of your user 
bugsplat.setDefaultDescription(description); // A description placeholder that can be overridden at crash time
bugsplat.setDefaultAdditionalFilePaths([paths]); // Paths to files to be sent to BugSplat at post time (limit 10MB) 
bugsplat.postAndExit(error, options); // Wrapper for post that calls process.exit(1) after posting error to BugSplat
bugsplat.post(error, options); // Async function that posts an arbitrary Error object to BugSplat
// If the values options.appKey, options.user, options.email, options.description, options.additionalFilePaths are set the corresponding default values will be overwritten
// Returns a promise that resolves with properties: error (if there was an error posting to BugSplat), response (the response from the BugSplat crash post API), and original (the error passed by bugsplat.post)
```

### User Feedback

In addition to crash reporting, BugSplat supports collecting non-crashing user feedback such as bug reports and feature requests. Feedback reports appear in BugSplat with the "User Feedback" type, grouped by title.

```typescript
await bugsplat.postFeedback('Login button broken', {
  description: 'Nothing happens when I tap it',
  email: 'jane@example.com',
});
```

You can also include file attachments by passing `additionalFilePaths`. The SDK reads the files from disk and uploads them automatically:

```typescript
await bugsplat.postFeedback('UI rendering issue', {
  description: 'The sidebar overlaps the main content.',
  additionalFilePaths: ['/path/to/screenshot.png'],
});
```

### Additional Considerations

It is recommended that you exit and restart your application after an uncaughtException or unhandledRejection occurs. Packages such as [pm2](https://www.npmjs.com/package/pm2) and [forever](https://www.npmjs.com/package/forever) can be configured to restart your application.

Additionally you can use [domains](https://nodejs.org/api/domain.html#domain_warning_don_t_ignore_errors) to handle errors differently across various parts of your application. Domains are pending deprecation according the the Node.js [documentation](https://nodejs.org/api/domain.html), however a suitable replacement has not been added yet.

More information regarding domain deprecation can be found [here](https://github.com/nodejs/node/issues/10843).

## Contributing

BugSplat loves open source software! Please check out our project on [GitHub](https://github.com/BugSplat-Git/bugsplat-node) and send us a pull request.


# Deno

## 👀 Getting Started

Adding BugSplat error reporting to your [Deno](https://deno.com/) application, web worker, or serverless function only takes a few lines of code. Once integrated, BugSplat will capture stack traces, logs, and other valuable insight when your code encounters a problem. BugSplat's [bugsplat-js](https://github.com/BugSplat-Git/bugsplat-js) package is fully typed and easily imported via [esm.sh](https://esm.sh/).

## ⚙️ Integrating

Add an import from [bugsplat-js](https://github.com/BugSplat-Git/bugsplat-js) via [esm.sh](https://esm.sh/):

```typescript
import { BugSplat } from 'https://esm.sh/bugsplat@8.0.1';
```

Create a new instance of the `BugSplat` class with the name of your BugSplat database, the name of your application, and the version of your application:

```typescript
const bugsplat = new BugSplat('DatabaseName', 'AppName', '1.0.0');
```

Use the `bugsplat` instance to capture errors that originate inside of try-catch blocks:

```typescript
try {
  throw new Error("BugSplat");
} catch (error) {
  await bugsplat.post(error);
}
```

Use `bugsplat` to post errors from promise rejections:

```typescript
Promise.reject(new Error("BugSplat!")).catch(error => bugsplat.post(error, {}));
```

You can also attach a file to your error post by passing a `BugSplatOptions` object containing with a value for `additionalFormDataParams` property.

```typescript
await bugsplat.post(error, getAdditionalOptionsWithLogFile());

function getAdditionalOptionsWithLogFile() {
  const filename = 'log.txt';
  return {
    additionalFormDataParams: [{
      key: 'file',
      value: new File([Deno.readFileSync(filename)], filename),
      filename: filename,
    }],
  };
}
```

## 🧪 Sample

Clone the [my-deno-crasher](https://github.com/BugSplat-Git/my-deno-crasher) repository:

```bash
git clone https://github.com/BugSplat-Git/my-deno-crasher
```

Set your current directory to `my-deno-crasher`.

```bash
cd my-deno-crasher
```

Run the sample with the `--allow-net` and `--allow-read` flags to allow BugSplat to post an error to our backend and read the log file respectively.

```bash
deno run --allow-net --allow-read main.ts
```

## 📈 Viewing Reports

After posting an error, navigate to the [Crashes](https://app.bugsplat.com/v2/crashes) page. You should see a new crash report for the application you just configured. Click the link in the ID column to see details about your crash on the [Crashes](https://app.bugsplat.com/v2/crashes) page:

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-2559c9fe5156b085f4971c3f02af3154b0756766%2Fimage.png?alt=media" alt=""><figcaption><p>Deno Error Reports</p></figcaption></figure>

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-734d136e1b2cc59a299e96a4e24a019a1715ae7d%2Fimage.png?alt=media" alt=""><figcaption><p>Deno Error Report</p></figcaption></figure>

That’s it! Your application is now configured to post error reports to BugSplat.

## 🧩 API

In addition to the configuration demonstrated above, there are a few public methods that can be used to customize your BugSplat integration:

```typescript
bugsplat.setDefaultAppKey(appKey); // Additional metadata that can be queried via BugSplats web application
bugsplat.setDefaultUser(user); // The name or id of your user
bugsplat.setDefaultEmail(email); // The email of your user
bugsplat.setDefaultDescription(description); // Additional info about your crash that gets reset after every post
async bugsplat.post(error, options); // Posts an arbitrary Error object to BugSplat
// If the values options.appKey, options.user, options.email, options.description are set the corresponding default values will be overwritten
// Returns a promise that resolves with properties: error (if there was an error posting to BugSplat), response (the response from the BugSplat crash post API), and original (the error passed by bugsplat.post)
```

## 🤝 Contributing

BugSplat loves open-source software! Please check out our project on [GitHub](https://github.com/BugSplat-Git/bugsplat-js) and send us a Pull Request.


# Downloads

Direct links to platform downloads.  Note that all links can also be found in their platform specific document.

### 💻 Desktop Software

|                      |                                                                                                                               |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Windows (Native C++) | [Download](https://app.bugsplat.com/browse/download_item.php?item=native)                                                     |
| Windows (.NET)       | [NuGet](https://www.nuget.org/packages/BugSplat) or [Download](https://app.bugsplat.com/browse/download_item.php?item=dotnet) |
| macOS                | See platform docs ([here](/integrations/desktop/macos))                                                                       |
| Linux                | See platform docs ([here](/integrations/desktop/linux))                                                                       |
| Electron             | See platform docs ([here](/integrations/desktop/electron))                                                                    |
| Qt                   | See platform docs ([here](/integrations/desktop/qt))                                                                          |
| Java                 | [Download](https://app.bugsplat.com/browse/download_item.php/?item=java)                                                      |
| Python               | See platform docs ([here](/integrations/desktop/python))                                                                      |
| Crashpad             | [Download](https://app.bugsplat.com/browse/download_item.php/?item=crashpad)                                                  |

### 🎮 Game Development

|               |                                                                          |
| ------------- | ------------------------------------------------------------------------ |
| CRYENGINE     | See platform docs ([here](/integrations/game-development/cryengine))     |
| PlayStation   | See platform docs ([here](/integrations/game-development/playstation))   |
| Unreal Engine | See platform docs ([here](/integrations/game-development/unreal-engine)) |
| Unity         | See platform docs ([here](/integrations/game-development/unity))         |
| Xbox          | See platform docs ([here](/integrations/game-development/xbox))          |

### 📱 Mobile Apps

|              |                                                               |
| ------------ | ------------------------------------------------------------- |
| Android      | See platform docs ([here](/integrations/mobile/android))      |
| Ionic        | See platform docs ([here](/integrations/mobile/ionic))        |
| iOS          | See platform docs ([here](/integrations/mobile/ios))          |
| React Native | See platform docs ([here](/integrations/mobile/react-native)) |

### 🕸️ Web

|            |                                                          |
| ---------- | -------------------------------------------------------- |
| Angular    | See platform docs ([here](/integrations/web/angular))    |
| JavaScript | See platform docs ([here](/integrations/web/javascript)) |
| React      | See platform docs ([here](/integrations/web/react))      |
| Vue        | See platform docs ([here](/integrations/web/vue))        |
| Node.js    | See platform docs ([here](/integrations/web/node.js))    |
| Deno       | See platform docs ([here](/integrations/web/deno))       |

### Symbols

|               |                                                                                      |
| ------------- | ------------------------------------------------------------------------------------ |
| symbol-upload | See GitHub releases ([here](https://github.com/BugSplat-Git/symbol-upload/releases)) |


# Using BugSplat

This section includes articles that are useful for using BugSplat and getting the most out of the app.

[**Using the App**](/guides/using-the-app) - is a walkthrough of the different pages in the app, how to navigate inside the app, and how to begin using the app to view crash data.

[**Symbol Files**](/guides/working-with-symbol-files) - are a critical component of getting useful data from your crashes. They're also a common stumbling block for new users.

[**Table Filtering**](/guides/searching/search) - contains instructions on how to search application crash data to find and isolate specific crashes or crash groups.

[**Table Grouping**](/guides/searching/grouping) - is an overview of how to compare groups of crashes to see into crash and stability trends.

[**Grouping Crashes**](/guides/grouping-crashes) - define rules that group a set of crashes at some level other than the top level of the call stack.

[**Commenting**](/guides/commenting) - is BugSplat's built-in comment tool and issue tracker.

[**3rd Party Tools**](/guides/integrating-with-tools) - compliment your workflow by integrating BugSplat with your issue tracker, messaging app, or another tool.

[**API**](/api-reference/web-services) – is an overview of the BugSplat API.


# Using the App

The BugSplat web application consists of four main pages: [Dashboard](https://app.bugsplat.com/v2/dashboard), [Crashes](https://app.bugsplat.com/v2/crashes), [Summary](https://app.bugsplat.com/v2/summary), and [Versions](https://app.bugsplat.com/v2/versions). These pages sort and organize an application's crash data, helping users quickly and simply navigate to the information they need.

Each of the main pages has subpages that provide more detail on individual [crashes](/education/bugsplat-terminology#crash-report), errors, [stack keys](/education/bugsplat-terminology#stack-key), and other important data.

Want a quick run-through of the app? Watch this video here - > [BugSplat Walkthrough.](/education/videos/bugsplat-product-walkthrough)

## Dashboard

The [Dashboard](https://app.bugsplat.com/v2/dashboard) page is the application’s home and where users land first inside the application. It provides users with an overview of their application's performance and lists the most recently submitted crashes.

Additionally, the Dashboard page provides a view of your top Crash Groups in a donut chart allowing you to visualize which defects are most critical to fix right now.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FBiypMPr7XYxkKb8CGPGx%2Fbugsplat-dashboard-may-9-2023.png?alt=media&amp;token=cd438029-429e-4c9f-9496-3cf1466c21d7" alt=""><figcaption><p>Dashboard Page</p></figcaption></figure>

## Navigating with Breadcrumbs

BugSplat provides a breadcrumb navigation control so that users always know where they are in their data, what they're looking for, and how to get back to where they were.

The breadcrumb control is laid out as follows `Database / Applications / Versions / ID`

The database, application, and version controls contain searchable dropdowns that allow users to quickly find what they're looking for. Select a database to enable the applications dropdown. Next, select an application or multiple applications to reveal the versions dropdown. Select a version or multiple versions to filter the data further. Click the **ID** of a crash to see its details or click a crash's Stack Key to see information about the crash's group.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-Mel-Okgecozcgrq5tfc%2F-Mel4rOp68VrR8SyZj-A%2Fnavigating-with-breadcrumbs.gif?alt=media\&token=a084717f-1f3b-4836-9c77-4c762d2c318d)

## Crashes

The [Crashes](https://app.bugsplat.com/v2/crashes) page contains all an application's crashes organized with the most recent crashes at the top of the table by default.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-MekfcNmD1btSK4qMo7a%2F-Mekx5MO6BLTpibur2WS%2FScreen%20Shot%202021-07-16%20at%201.03.48%20PM.png?alt=media\&token=8297160d-f775-42e0-bcba-3c8f144e4805)

From here, users can manipulate the table in multiple ways to view specific sets of data.

First, users can filter the crashes using the [Searching](/guides/searching/search) and [Grouping](/guides/searching/grouping) tools to find specific crashes. The **Timeframe** filter on the top right can also choose a specific time period.

Second, users can select different data types using the **Column Visibility** dropdown to change what data is visible.

Third, users can sort by ascending or descending order in a column by clicking on the header text of that column.

Fourth, users can click the **>** on each individual row to expand that row and view more details about a specific crash. These details include crash metadata, the call stack of the crashing thread, and a list of files that were attached to the crash report.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-Mel-Okgecozcgrq5tfc%2F-Mel-meApC-ySSVhFtz-%2Fexpando-row-crashes.gif?alt=media\&token=01559b33-b0ec-4327-9bf0-439971fab86d)

Finally, if a specific crash seems important and worthy of further investigation, click on the numbered link in the ID column to navigate to the corresponding report.

## Crash

The **Crash** page allows users to get information critical for understanding and fixing the defect which originally caused the issue.

### Report Details

The **Report Details** panel contains information about the crash and the user who experienced it. It displays who crashed, where they crashed (IP address), and the description provided by the user in the crash dialog, as well as details such as the crashing function, line number where the crash occurred, information regarding what type of crash took place, when the crash happened, and what OS and SDK the crashing application was running on. This information is sometimes [obfuscated to protect users](/guides/production/security-privacy-and-compliance/gdpr), like it is in the image below.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-Mel56hR6uxWXVI50yWP%2F-Mel9cY3PusGCqWe6z1z%2Fuser-details-modal.png?alt=media\&token=e89b806a-3c71-46dd-bce7-51afcaf2fb42)

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-Mel56hR6uxWXVI50yWP%2F-Mel9Z6zbAX6BIeeCpaX%2Fcrash-details-modal.png?alt=media\&token=e0820560-38ec-4779-b0ab-d36621811f55)

### Active Thread

The **Method** column contains a list of functions in the stack trace of the thread that caused the program to crash. Depending on the [platform](/integrations/integrations) you may see methods that don't match your source code. This is because platforms such as [Windows Native](/integrations/desktop/cplusplus), [.NET](/integrations/desktop/bugsplat-for-dot-net), [Crashpad](/integrations/desktop/crashpad), [Breakpad](/integrations/desktop/breakpad), [macOS](/integrations/desktop/macos), [Unity Native](/integrations/game-development/unity), and [Unreal](/integrations/game-development/unreal-engine) require you to upload [symbols](/guides/working-with-symbol-files) for each version you release in order to calculate the correct method names. For more information on how to upload symbols please see the documentation for your [platform](/integrations/integrations).

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-Mel56hR6uxWXVI50yWP%2F-Mel5qNrrXH5FztBX1hY%2Factive-thread-july-21.png?alt=media\&token=0d54b3d9-2cce-47ae-b8ca-832c5ca915cc)

Clicking the **>** (greater than symbol) in the left-most column will expand the **Row Details** view.

The **Row Details** view will display the **Group Rules**, **Ignore Function**, and **Ignore File** buttons that will allow you to [modify the way your reports are grouped](/guides/grouping-crashes). Grouping at a different level of the call stack is called [subkeying](/education/bugsplat-terminology#subkey) and is useful in cases such as a crash that occurs in a 3rd party library, or when additional stack frames are added by a crash reporter.

Additionally, for [Windows Native](/integrations/desktop/cplusplus) crashes the **Row Details** view will show a table of [Local Variables and Function Arguments.](https://blog.bugsplat.com/local-variables-function-arguments/)

The Crash page includes valuable information like crash time, environment, corresponding function name and line number, containing [stack key](/education/bugsplat-terminology#stack-key), and much more.

### Additional Information

All data covered to this point on the Crash page are found under the **Overview** tab. To access additional information about crashes like **Other Threads**, **Registers**, **Modules**, **Attributes**, **Debugger Output**, and **Attachments**, use the tabs found above the **Report Details** module.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-Mel56hR6uxWXVI50yWP%2F-Mel84A4-4F6P0rVjMbl%2Fviewing-tabs-crashreport.gif?alt=media\&token=b09ab130-a882-40b4-9dc0-d8e879bc2324)

#### Previewing Attached Files

To preview or download an attached file, simply navigate to the **Attachments** tab in a crash report and click on the right arrow next to the attachment name in order to load a preview of the attached text.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FnXkdSiWBnpDqPrwFLtgW%2Flog-viewer-bs.gif?alt=media\&token=cc3f2003-7e57-4474-b253-2b3a92913a7b)

## Summary

The [Summary](https://app.bugsplat.com/v2/summary) page shows a view of an application's crash data which automatically groups crashes by the top line of the call stack, allowing users to see which defects are occurring most frequently.

You can group by other levels of the call stack as well to differentiate defects using [Crash Grouping](/guides/grouping-crashes).

The **Summary** page allows for similar table navigation as the [Crashes](#crashes) page. Users can search, manipulate column size, alter column visibility, and expand rows.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-MelOK7Ei8jpfgQXIH99%2F-MelORpI60x7n2z9Nnwi%2Fsummary-page.png?alt=media\&token=d2ee548e-0307-4221-8bdd-17d0cc3bf368)

The Summary page has a line chart at the top of the page which shows the top stack key by default, although you can select multiple stack keys to display on the chart.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-Mel9rlIAGiKulZB5NMy%2F-MelNbef8S1_-j_H2LEG%2Fcharting-stack-keys.gif?alt=media\&token=50e58706-0896-4629-9168-16ac70b6126d)

## Crash Group Page

The **Crash Group** page shows a more in-depth view of all crashes found in a [stack key](/education/bugsplat-terminology#stack-key) and allows users to explore individual crashes, leave comments for team members, create defects based on the crash group, and more.

Companies that are using BugSplat's [Windows C++ SDK](/integrations/desktop/cplusplus) can create [Custom Support Responses](/guides/production/setting-up-custom-support-responses) to alert their end-users to known issues identified with BugSplat. Support responses are a valuable tool for communicating with end-users about known fixes or pointing them toward specific helpful docs.


# Symbol Files

Symbol files are critical to getting useful data from your crashes. [Windows](/integrations/desktop/cplusplus), [Breakpad](/integrations/desktop/breakpad), [Crashpad](/integrations/desktop/crashpad), [MacOS](/integrations/desktop/macos), [Xbox](/integrations/game-development/xbox), [PlayStation](/integrations/game-development/playstation), [Nintendo Switch 2](/integrations/game-development/nintendo), and some [JavaScript](/integrations/web/javascript) applications require uploading symbol files to generate call stacks that contain function names and line numbers. The symbol upload process can be automated as part of your build. Many of our SDKs require symbols, which can be uploaded and managed via the [Versions](https://app.bugsplat.com/v2/versions) page.

For additional information regarding Symbol files, please visit the [documentation](/integrations/integrations) specific to your application's platform.

### What are Symbols?

Symbols are files containing information to map the crash report's call stack to file names and line numbers in source code.

### Using Symbols

[Windows C++](/integrations/desktop/cplusplus) and [.NET](/integrations/desktop/bugsplat-for-dot-net) symbol files have **.exe**, **.pdb**, and **.dll** extensions.

For [Crashpad](/integrations/desktop/crashpad) applications, symbols files contain **.sym** extensions.

For [macOS](/integrations/desktop/macos) applications, symbols files end with a **.dSYM** extension.

For TypeScript and [JavaScript](/integrations/web/javascript) applications, symbols are files with a **.js.map** extension.

Symbol files can be uploaded via [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload). Additionally, Crashpad **.sym** files can be [generated automatically](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload#improving-upload-speeds-1) by invoking symbol-upload with the `-m` argument.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-260022dba412af8e35feac5150235803dacab8d2%2Fimage.png?alt=media" alt=""><figcaption><p>BugSplat Versions Page</p></figcaption></figure>

## Additional Resources

{% content-ref url="/pages/9CbMAPqdIADsTxgNylgM" %}
[Upload Symbols with symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload)
{% endcontent-ref %}

{% content-ref url="/pages/-MeWLeYh35WEExN\_2fue" %}
[How to Manually Upload Symbols](/guides/working-with-symbol-files/how-to-manually-upload-symbols)
{% endcontent-ref %}

{% content-ref url="/pages/AW8j5JTuLSk6IkJ00R1y" %}
[Managing Symbol Storage](/guides/working-with-symbol-files/managing-symbol-storage)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg\_UpA3JIjWidH0gSp6" %}
[Source Maps](/guides/working-with-symbol-files/source-maps)
{% endcontent-ref %}

{% content-ref url="/pages/-MeWLPNUInpcGqKnaZDt" %}
[Working with Symbol Files in Windows Environments](/guides/working-with-symbol-files/working-with-windows-symbols-in-bugsplat)
{% endcontent-ref %}


# Upload Symbols with symbol-upload

How to upload symbol files to BugSplat with symbol-upload, covering CLI usage, authentication, dSYM, self-hosted symbol servers, and GitHub Actions

## Overview 👀

Symbol-upload is a cross-platform application that automatically uploads [symbol files](/guides/working-with-symbol-files) as part of your build process and is the successor of [SendPdbs](/guides/working-with-symbol-files/sendpdbs-legacy). Each build of your product that sends crash reports must have an exact set of matching symbol files uploaded to BugSplat.

{% hint style="info" %}
Uploaded symbols but still seeing missing function names or line numbers? See [Why are crashes missing symbols?](/education/faq/why-are-crashes-missing-symbols-function-names-and-or-line-numbers) to diagnose.
{% endhint %}

The symbol-upload tool can be installed by [npm](https://npmjs.com/package/@bugsplat/symbol-upload) and used as a [CLI tool](https://github.com/BugSplat-Git/symbol-upload?tab=readme-ov-file#command-line) or a [javascript library](https://github.com/BugSplat-Git/symbol-upload?tab=readme-ov-file#api). We also provide a [GitHub Action](https://github.com/BugSplat-Git/symbol-upload?tab=readme-ov-file#action) that can be added to your build workflow.

```bash
npm i -g @bugsplat/symbol-upload
```

Alternatively, you can use one of the following terminal commands to download prebuilt binaries of [symbol-upload](https://github.com/BugSplat-Git/symbol-upload), or download with your web browser via the [GitHub releases page](https://github.com/BugSplat-Git/symbol-upload/releases).

{% hint style="warning" %}
If you download symbol-upload-macos via a web browser, Gatekeeper will block the application from running. To add the application to the system's allow list, run the following command in terminal

```bash
xattr -r -d com.apple.quarantine ./symbol-upload-macos
```

{% endhint %}

#### Windows

```powershell
Invoke-WebRequest -Uri "https://app.bugsplat.com/download/symbol-upload-windows.exe" -OutFile "symbol-upload-windows.exe"
```

#### macOS

```bash
curl -sL -O "https://app.bugsplat.com/download/symbol-upload-macos" && chmod +x symbol-upload-macos
```

#### Linux

```bash
curl -sL -O  "https://app.bugsplat.com/download/symbol-upload-linux" && chmod +x symbol-upload-linux
```

A group of symbols identified by their application name and version is called a **symbol store**. Symbol-upload automatically creates a new symbol store each time you upload symbols to a unique application and version combination. Send symbols to BugSplat for every build on your build/integration server. There is no limit on the number of symbols you can post to BugSplat. By default, each symbol file must be smaller than **25 GB**, and each symbol store is limited to **100 GB**. Both limits are configurable per database. BugSplat automatically removes symbols that haven't been referenced recently; see [Managing Symbol Storage](/guides/working-with-symbol-files/managing-symbol-storage) for the cleanup rules and how to remove symbols manually.

## Using symbol-upload 🧑‍💻

Running symbol-upload in a command window without any arguments shows the following usage information:

```bash
bobby@BugSplat % ~ % symbol-upload -h

@bugsplat/symbol-upload v10.5.0

  symbol-upload contains a command-line utility and a set of libraries to help  
  you upload symbol files to BugSplat.                                          

Usage

  -h, --help                             Print this usage guide.                                                       
  -b, --database string                  Your BugSplat database name. The value of database must match the value used  
                                         to post crash reports. This value can also be provided via the                
                                         BUGSPLAT_DATABASE environment variable.                                       
  -a, --application string               The name of your application. If not provided symbol-upload will attempt to   
                                         use the value of the name field in package.json if it exists in the current   
                                         working directory.                                                            
  -v, --version string                   Your application's version. If not provided symbol-upload will attempt to use 
                                         the value of the version field in package.json if it exists in the current    
                                         working directory.                                                                                                                   
  -i, --clientId string (optional)       An OAuth2 Client Credentials Client ID for the specified database. If         
                                         provided --clientSecret must also be provided. This value can also be         
                                         provided via the SYMBOL_UPLOAD_CLIENT_ID environment variable.                
  -s, --clientSecret string (optional)   An OAuth2 Client Credentials Client Secret for the specified database. If     
                                         provided --clientId must also be provided. This value can also be provided    
                                         via the SYMBOL_UPLOAD_CLIENT_SECRET environment variable.                     
  -r, --remove                           Removes symbols for a specified database, application, and version. If this   
                                         option is provided no other actions are taken.                                
  -f, --files string (optional)          Glob pattern that specifies a set of files to upload. For example,            
                                         **/*.{pdb,exe,dll} will recursively search for .pdb, .exe, and .dll files.    
                                         Defaults to "*.js.map"                                                        
  -d, --directory string (optional)      Path of the base directory used to search for symbol files. This value will   
                                         be combined with the --files glob. Defaults to '.'                            
  -m, --dumpSyms boolean (optional)      Use dump_syms to generate and upload sym files for specified binaries.        
  -l, --localPath string (optional)      Path to a directory to copy symbols to. If provided, the files will be copied   
                                         to the provided path instead of being uploaded to BugSplat. Useful for        
                                         creating a self-hosted symbol server.                                                                                                       
                                                                                
  The -i and -s arguments are not required if you set the environment variables 
  SYMBOL_UPLOAD_CLIENT_ID and SYMBOL_UPLOAD_CLIENT_SECRET, or provide a user    
  and password.                                                                 

Example

  symbol-upload -b your-bugsplat-database -a your-application-name -v your-     
  version -f "*.js.map" -d "/path/to/containing/dir" -i your-client-id -s your-client-secret 

Links

  🐛 https://bugsplat.com                          
                                                   
  💻 https://github.com/BugSplat-Git/symbol-upload 
                                                   
  💌 support@bugsplat.com 
```

### Example

The following is an example of how to invoke symbol-upload and search a directory recursively for `.dll`, `.pdb`, and `.exe` files. Replace the values of `your-bugsplat-database`, `your-email`, and `your-password` with your BugSplat database, email, and password. You can specify a [glob](https://github.com/isaacs/node-glob) for the `-f` argument to match for files based on a pattern.

```bash
symbol-upload -b your-bugsplat-database -a my-awesome-app -v 1.0 -i your-clientId -s your-clientSecret -d "/path/to/build -f "**/*.+(exe|dll|pdb)"
```

You can use the `-r` flag to remove a symbol store instead of uploading. This is helpful when you create a new build but don't want to increment the build number.

### Authentication

OAuth2 Client ID and Client Secret credentials are required via the `-i` and `-s` arguments and are created on the [OAuth Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page. Note that you only need the 'Symbols' scope. We no longer accept username/password for symbol uploads.

### Apple <a href="#improving-upload-speeds" id="improving-upload-speeds"></a>

MacOS and iOS builds typically generate `.app` or `.xcarchive` files. To upload bundled `.dSYM` files, point symbol-upload at the `.app` or `.xcarchive` file, and use a glob that instructs symbol-upload to search for `.dSYM` files recursively.

```bash
symbol-upload ... -d "/path/to/build.xcarchive -f "**/*.dSYM"
```

### Dump Syms <a href="#improving-upload-speeds" id="improving-upload-speeds"></a>

BugSplat can generate [Crashpad symbol files](https://github.com/google/breakpad/blob/master/docs/symbol_files.md) as part of the upload process. The Crashpad symbol files have a `.sym` format and are useful for cross-platform applications. BugSplat has integrated [Mozilla's dump-syms](https://github.com/mozilla/dump_syms) into symbol-upload, which allows developers to skip building Breakpad. To generate a `.sym` file at upload time, specify the `-m` flag when invoking symbol-upload.

### Self-Hosted Symbol Servers

The symbol-upload tool can be used to create a [SymSrv](https://learn.microsoft.com/en-us/windows/win32/debug/symbol-servers-and-symbol-stores) directory structure for Windows and Xbox symbols that is compatible with both BugSplat and [Microsoft Visual Studio](https://learn.microsoft.com/en-us/visualstudio/debugger/specify-symbol-dot-pdb-and-source-files-in-the-visual-studio-debugger?view=vs-2022#configure-location-of-symbol-files-and-loading-options). Additionally, symbol-upload can also create a SymSrv directory structure for macOS/iOS, Linux/Android (Crashpad), PlayStation, and Nintendo Switch 2 symbols that is compatible with BugSplat.

To upload symbols to a local directory, provide the `-l` flag and a path where the symbols will be copied.

```powershell
symbol-upload -f "**/*.{pdb,exe,dll}" -l "C:\path\to\output"
```

Next, use a sync tool to upload the directory to a cloud services provider. The following is an example that uses `s3 sync` via the [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html).

```bash
aws s3 sync . s3://your-bucket-name-here
```

To connect BugSplat to your self-hosted symbol server, please refer to our Symbol Server [documentation](/guides/working-with-symbol-files/symbol-servers).

### GitHub Actions

The symbol-upload repo also includes a GitHub Action that's compatible with the default Windows, macOS, and Linux images. Here's a snippet you can add to your workflow:

```yaml
- name: Symbols 📦
      uses: BugSplat-Git/symbol-upload@main
      with:
        clientId: "${{ secrets.SYMBOL_UPLOAD_CLIENT_ID }}"
        clientSecret: "${{ secrets.SYMBOL_UPLOAD_CLIENT_SECRET }}"
        database: "${{ secrets.BUGSPLAT_DATABASE }}"
        application: "MyConsoleCrasher"
        version: "1.0.0"
        files: "*.{pdb,exe,dll}"
        directory: "BugSplat\\Win32\\release"
```

We have also created an [example repo](https://github.com/BugSplat-Git/github-action-example) demonstrating how to use the @bugsplat/symbol-upload action to upload symbols to BugSplat.

### Improving Upload Speeds <a href="#improving-upload-speeds" id="improving-upload-speeds"></a>

Customers located far away from our US-East hosting location, especially those with high-latency and high-bandwidth connections, sometimes report slow upload speeds. We have several reports of significantly faster uploads after following the advice in the Microsoft technical note: <https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/tcpip-performance-known-issues>


# How to Manually Upload Symbols

[Symbols](/education/bugsplat-terminology#symbols) are used to display the original source code function names and line numbers from the [call stacks](/education/bugsplat-terminology#call-stack) of compiled applications.

## Step 1

Navigate to the [Versions](https://app.bugsplat.com/v2/versions) page.

## Step 2

Click the **Upload Symbols** button to open the Symbol Upload modal. Alternatively, you can expand a row in the table and upload symbols to an existing version.

![Manual Symbol Upload](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-b378fdcf39b23145e1efd1ea9761be9e21783502%2Fmanual-symbol-upload.png?alt=media)

## Step 3

Enter values in the **Application** and **Version** fields if they are displayed. These values **must** match the application and version values you used to configure BugSplat in your application.

## Step 4

Drag and drop the files you would like to upload, or use the **Select Files** link to choose the files in your system file explorer.

Choose all of the symbol files that correspond to your application. Windows symbol files have `.exe`, `.dll`, and `.pdb` file extensions. MacOS symbol files can be extracted from a `.xcarchive`, or you can upload `.dSYM` files. Crashpad and Breakpad symbol files have a `.sym` file extension. TypeScript and JavaScript symbol files have a `.js.map` extension.

## Step 5

Symbols that have been uploaded successfully will display a green checkmark next to their names. Once all files have been uploaded the Close button will be enabled and you can safely close the dialog.

![Successful Symbol Upload](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-2fba5b20045ece6147ba7b1394f621b43337bb94%2Fsymbol-upload-success.png?alt=media)


# Managing Symbol Storage

How BugSplat stores symbols, cleans them up automatically, how to remove symbol files, and how to manage your symbol space

Symbols consume storage space in your account, so removing unused symbols helps reduce storage costs. BugSplat automatically removes symbols that haven't been referenced recently, and you can also remove them manually at any time. BugSplat customers are responsible for retaining their own long-term copies of symbol files.

For many customers, the automatic rules need no further explanation. If your symbol storage space is large and you'd like to optimize costs, read on.

### Symbol Stores

When you upload symbols to BugSplat, a **symbol store** is created. A [symbol store](/education/bugsplat-terminology#symbol-store) is a collection of symbols identified by their application name and version. BugSplat groups these symbols together for easy reference and management.

### Automatic Symbol Cleanup

Once a database contains more than **5 GB** of symbol data, our cleanup algorithm will automatically remove symbols that have not been referenced recently. Symbol files shared between symbol stores (i.e., uploaded multiple times) are only deleted when no symbol store references the file.

**Cleanup Rules**

1. Symbol stores not referenced by a crash report in more than the configured expiry period (default **90 days**) will be removed.
2. New symbol stores not referenced by a crash report within **15 days** will be removed.
3. Individual symbol files not accessed in more than the configured expiry period (default **90 days**) will be removed.

{% hint style="info" %}
You can configure the symbol expiry period for your database on the [Symbols](https://app.bugsplat.com/v2/database/symbols) settings page. The default value is 90 days.
{% endhint %}

{% hint style="info" %}
Avoid uploading common symbols with every build. Library symbols that change infrequently should be placed in a dedicated symbol store rather than being re-uploaded with each new build of your application. This allows the 15-day "new symbol store" rule to remove individual builds that aren't referenced and ensures more efficient cleanup.
{% endhint %}

### How do I remove symbol files?

You can remove symbol stores at any time from the [Versions](https://app.bugsplat.com/v2/versions) page. Select the checkbox next to the versions containing the symbols you want to remove, then click the **Delete Symbols** button. The application name/version row won't be deleted, but it will show a size of zero.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-a7c4d19a78cf0fd893cc055650ddb0c096dbbe24%2Fremove-symbols-manually.gif?alt=media" alt="Removing symbols manually from the Versions page"><figcaption><p>Removing Symbols Manually</p></figcaption></figure>

You can also remove a symbol store from your build machine by invoking [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload) with the `-r` flag.

### Managing Symbols with the API

If BugSplat's automatic cleanup rules aren't optimal for your team, you can implement your own cleanup logic using the [BugSplat API](/api-reference/api).

### Best practices for managing symbol space

* **Assign a unique version to each build.** This lets BugSplat's automatic cleanup rules remove symbols specific to builds that are no longer referenced.
* **Upload only the symbols you need.** BugSplat automatically de-duplicates identical symbol files across builds, so there's no need to prune duplicates yourself, but skip third-party, system, or game editor symbols you'll never need call stacks for.
* **Monitor symbol usage.** Keep an eye on the size of your symbol data and how often symbols are accessed so you can anticipate when automatic cleanup will occur.
* **Use manual removal when needed.** Periodically review your symbol stores and delete those you no longer need.


# Symbol Servers

BugSplat can process crashes using symbol files stored in external symbol servers. BugSplat supports accessing HTTP/HTTPS servers and Amazon S3 Buckets. BugSplat caches files from external symbol servers, ensuring fast crash calculation. Please note that if BugSplat requests a file not present on your external symbol server, it will not try to access the file again for 6 hours. See [Miss-Cache](#miss-cache) below.

{% hint style="info" %}
Some organizations restrict access to their symbol servers by IP address. To allow access to BugSplat, add the IP addresses [23.22.79.2](https://www.whatismyip.com/23.22.79.2/?iref=home), [3.93.104.250](https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#ElasticIpDetails:AllocationId=eipalloc-0da0d84b88eed6812), and [34.194.164.107](https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#ElasticIpDetails:AllocationId=eipalloc-0cd966956c064a2e4) to your whitelist.
{% endhint %}

### Miss-Cache

If BugSplat processes a crash that needs a symbol file your external symbol server doesn't have yet (or refuses to deliver for any other reason), BugSplat records that miss and won't ask your server for that file again for 6 hours. This keeps a burst of crashes referencing an unavailable symbol from turning into a request storm against your server.

The trade-off shows up when symbols arrive shortly after the crashes do. If you've recently uploaded symbols and call stacks still aren't resolving, the miss-cache is a likely culprit. Navigate to the [Symbols](https://app.bugsplat.com/v2/database/symbols) page, expand your symbol server's row, and click **Clear Miss-Cache**. BugSplat will report how many entries it dropped and will request those files from your server again on the next lookup.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-066c5ca306dafdc65ecece1e07bfc3ddcfa65f1f%2Fclear-miss-cache.png?alt=media" alt="Expanded symbol server row showing the Clear Miss-Cache button"><figcaption><p>Clearing the miss-cache for an external symbol server</p></figcaption></figure>

Clearing the miss-cache only affects future symbol lookups. Crashes that were already processed without symbols need to be [reprocessed](/education/how-tos/reprocessing-crashes) to pick up the newly available symbol files.

### Directory Structure

The [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload) tool can be used to create a [SymSrv](https://learn.microsoft.com/en-us/windows/win32/debug/symbol-servers-and-symbol-stores) directory structure for Windows and Xbox symbols that is compatible with both BugSplat and [Microsoft Visual Studio](https://learn.microsoft.com/en-us/visualstudio/debugger/specify-symbol-dot-pdb-and-source-files-in-the-visual-studio-debugger?view=vs-2022#configure-location-of-symbol-files-and-loading-options). Additionally, symbol-upload can also create a SymSrv directory structure for macOS/iOS, Linux/Android (Crashpad), PlayStation, and Nintendo Switch 2 symbols that is compatible with BugSplat.

To upload symbols to a local directory, provide the `-l` flag and a path where the symbols will be copied.

```bash
symbol-upload -f "**/*.{pdb,exe,dll}" -l "C:\path\to\output"
```

### HTTPS

BugSplat can access symbol files over HTTPS. This method also supports [Windows SymStore/SymProxy](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/symbol-stores-and-symbol-servers) symbol servers. To connect an HTTPS symbol server to BugSplat, navigate to the [Symbols](https://app.bugsplat.com/v2/database/symbols?) page. Click the **+ Add Server** button, and add a **Host** value.

For symbol servers hosted on Azure, you'll need to generate a [Personal Access Token](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\&tabs=Windows#create-a-pat) that has the **Symbols (read)** scope. Enter your **Username** and use the PAT for **Password**. Optionally, you may test the connection to your server by providing a path relative to the **Host** URL.

When testing a path, BugSplat will make a **HEAD** request to **http\[s]://username:<token@your-server.com>/path/to/test.pdb**. Please ensure your server accepts **HEAD** requests with Basic Authentication to access this path.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2F68mybftfdyrOy4Hs5aZw%2Fazure-symbol-server.gif?alt=media&amp;token=6a1f2f72-f88a-4bc9-b40d-ca7982784cfa" alt=""><figcaption></figcaption></figure>

### AWS S3

For AWS S3 symbol servers, create a minimally permissive [IAM User](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html#id_users_create_console) so BugSplat can access your S3 bucket. Modify this example policy and attach it to your newly created IAM User.

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::{your-s3-bucket}",
                "arn:aws:s3:::{your-s3-bucket}/*"
            ]
        }
    ]
}
```

Once you create your IAM user, generate an [access key/secret](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) to allow BugSplat to access your S3 bucket. Navigate to the [Symbols](https://app.bugsplat.com/v2/database/symbols) page and click **+ Add Server**. Select **AWS-S3** in the **Type** dropdown. Enter values for **Access Key**, **Secret Key**, **Region**, and **Bucket Name**, and click **Add.**

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FTHdKaooNuGHTx6kGlDYW%2Foutput.gif?alt=media&amp;token=e80f4c6b-55c2-4b4c-84ce-87f26ccd2b6a" alt=""><figcaption><p>Adding an External S3 Symbol Server</p></figcaption></figure>


# Working with Symbol Files in Windows Environments

A common stumbling block for new BugSplat users is properly uploading symbols for Windows (native and .NET). [Symbols](/education/bugsplat-terminology#symbols) are files that contain information to map the data in a crash file to file names and line numbers in source code.

To make this issue easier, we’ve added a way to check whether symbols have been uploaded properly.

## How it works: <a href="#how-it-works" id="how-it-works"></a>

At the top of the Crash page, you will see a warning if you're missing symbols.

![Missing Symbols Alert](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2Fsync%2F7f69e2f3e8198da251d5f9ea6f68d2678396c542.png?generation=1631201324779957\&alt=media)

Once the data is obtained, the Function, Location, Exception Code, Environment, and Exception Message fields will be populated with all available information. If a crash is missing symbols, there will be various messages under the 'File' column in the 'Active Thread' tab indicating which symbols were missing. Make sure to upload the missing symbols (`.exe`,`.pdb`, and `.dll` files as indicated by the 'Active Thread' tab) to the symbol store for your application name and version via the [Versions](https://app.bugsplat.com/v2/versions) page. Or use [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload) to upload symbols using the command line. When uploading using [symbol-upload](https://docs.bugsplat.com/introduction/development/working-with-symbol-files/upload-symbols-with-symbol-upload), symbols are matched to crashes by their internal GUID. The application name and version used when uploading do not need to match those of the crash report.

![Missing Symbols in Active Thread](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2Fsync%2F7568308b84760ca11714eeaf72b21bb9e8de4cdf.png?generation=1631201324731611\&alt=media)

Additionally, you can click the 'Modules' tab to view information about all modules that were loaded on the system at crash time. In the modules table, you’ll be able to view if symbols have been properly uploaded for each module by looking at the value under the 'Status' column.

![Missing Symbols in Modules](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2Fsync%2F58f3d513be0f5f770a75ee1edc650c9a91cd799a.png?generation=1631201324851410\&alt=media)

The values under the status column are as follows:

* **deferred**: the debugger doesn’t need the module’s exe, dll, or pdb files to unwind the stack.
* **file not found**: the debugger needs the module’s exe, dll, or pdb files to unwind the stack, but the exe/dll with matching debug signature cannot be located.
* **no symbols loaded**: the debugger needs the module’s exe, dll, or pdb files to unwind the stack and the matching exe/dll has been located, but not the symbols.
* **pdb symbols** (or **private pdb symbols**): debugger needs the module’s exe, dll, or pdb files to unwind the stack and they have been loaded successfully.

Unfortunately, Microsoft doesn’t provide symbol information for all operating system modules, so “file not found” errors are fairly common.

The presence of a call stack warning that reads, “Stack unwind information not available. Following frames may be wrong,” indicates that the debugger lacked access to the files it needed.


# Source Maps

BugSplat has the ability to convert uglified and minified JavaScript stack traces into function names and line numbers from the original source. You can upload [source map](https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Use_a_source_map) files to BugSplat during your build process by leveraging [@bugsplat/symbol-upload](https://www.npmjs.com/package/@bugsplat/symbol-upload).

In order to correctly unwind uglified stack traces, you’ll need to ensure that the filename of the source map matches the file name of the original source file. For instance, if your build process generates a file `main.153ee63b.chunk.js`, the corresponding source map file should be named `main.153ee63b.chunk.js.map`.

{% hint style="info" %}
Be sure to upload source maps for each released version of your application for best results.
{% endhint %}

If BugSplat is unable to convert the uglified stack trace back to the original source the **Debugger Output** tab will display diagnostic information from the BugSplat backend that will help you troubleshoot.


# SendPdbs (Legacy)

{% hint style="warning" %}
SendPdbs is BugSplat's legacy, Windows-only symbol upload tool and is no longer the recommended approach. New integrations should use our cross-platform successor, [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload). SendPdbs symbol uploads will no longer be supported as of 31-Dec-2026. This page is retained for teams still running SendPdbs.
{% endhint %}

SendPdbs.exe is a BugSplat application used to automate the upload of Windows symbols and executables. Each build of your product that sends crash reports must have an exact set of matching symbol files uploaded to BugSplat.

Feel free to send symbols to BugSplat for every build on your build/integration server. There is no limit on the total amount of symbols you can post to BugSplat. However, by default, any single symbol file must be smaller than 25 GB.

Uploading symbols with SendPdbs creates a 'symbol store,' which is just a group of symbols identified by their application name and version. BugSplat will automatically remove symbol stores that haven't been accessed recently. See below for those rules. Using our web application, you can manually delete a symbol store.

{% hint style="warning" %}
BugSplat will automatically remove unreferenced symbols in large symbol sets. If your database contains more than 5 gigabytes of symbol data, our cleanup algorithm will automatically remove symbols not referenced by a crash report in more than the configured expiry period (default 90 days). Additionally, newly posted symbols not referenced by a crash report within 15 days will be removed. You can configure the symbol expiry period on the [Symbols](https://app.bugsplat.com/v2/database/symbols) settings page.
{% endhint %}

Older versions of SendPdbs (prior to version 4.0.0.0) required the application name and version used with SendPdbs to match the application name and version used to initialize BugSplat in your code. This restriction has been lifted, and any symbols uploaded to your database are now available to all crash reports in that database. In addition, older versions of SendPdbs limited the maximum size of a symbol store. This limit is no longer enforced. Instead, customers now have a storage quota size associated with their subscriptions.

Credentials can be provided to SendPdbs via the /u and /p command-line arguments. Alternatively, you can save these credentials in the Windows Credentials Manager. To use values from Windows Credential Manager, create a new Generic Credentials entry and provide the entry name as the value for the /credentials argument.

Credentials can also be provided using an OAuth2 client id/client secret created on our [OAuth Integrations](https://app.bugsplat.com/v2/database/integrations#oauth) page. Just supply these values as the username/password.

Running SendPdbs.exe in a command window without any arguments shows the following usage information:

```
 USAGE: This utility searches your build tree for Windows symbol/executable
  files and uploads them to the BugSplat server.

    Specify BugSplat credentials using either:
    /u USER
    /p PASSWORD
    -or-
    /credentials WINDOWS-CREDENTIAL-MANAGER-GENERIC-CREDENTIALS

  Other required parameters:
    /b DATABASE  BugSplat database
    /a APPNAME   AppName for the symbol files (e.g. /a MyApp)
    /v VERSION   Version number of AppName (e.g. /v 1.0), required if /l not set
    /l LIBRARY   Library from which to extract file version info (e.g. /l MyApp.exe), required if /v not set

  Upload is the default action, modify using the following parameters:
    /s           Search subdirectories, default off
    /d PATH      Folder to search, defaults to current folder
    /f FILESPEC  Files to search, defaults to "*.pdb;*.dll;*.exe"
    /compression LEVEL  Optimal, fastest, or nocompression, defaults to Optimal
    /threads NUM Threads used during upload, defaults to 20
    /c RETRIES   Maximum retries to attempt for each file upload, defaults to 3.

  To remove symbols from BugSplat use the following single parameter:
    /r           Removes all symbols for specified AppName, AppVersion, Database

  The log level can be modified with:
    /verbose     Use for additional diagnostics
```

## Improving Upload Speeds

Customers located far away from our US-East hosting location, especially those with high-latency and high-bandwidth connections, sometimes report slow upload speeds. We have several reports of significantly faster uploads after following the advice in the Microsoft technical note: <https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/tcpip-performance-known-issues>


# Searching

BugSplat provides powerful searching, filtering, and grouping tools that help users better understand the various intricacies of their crash data. Users can build complex queries via the BugSplat search controls, share the results with co-workers, and export the results for use in other tools.

Need to isolate all crashes that happened before a certain date? Looking for any crash that contains a specific function anywhere in the call stack? Want to group crashes based on their IP Address? BugSplat can do it all! Crafting a search to isolate the crash data you need is straightforward and intuitive.

BugSpat's data can also be searched and filtered directly via our web-services [APIs](/api-reference/paging-filtering-and-grouping).

{% content-ref url="/pages/-MebBB5qGLH01QJXM2uu" %}
[Table Filtering](/guides/searching/search)
{% endcontent-ref %}

{% content-ref url="/pages/-Mg6Z4RN3VvPkNLdR\_yt" %}
[Table Grouping](/guides/searching/grouping)
{% endcontent-ref %}


# Table Filtering

To use the filtering tool first click on the button labeled **Add filter** which can be found on the Crashes, Summary, and Crash Group pages.

Next, select a column to filter in the Search dropdown. After picking a column, select the desired search criteria and enter a value and click **Submit**. Repeat this process until you've found exactly what you're looking for.

In the BugSplat web application, users can filter their crash data based on almost any piece of data attributed to a crash or stack key.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-Mf66sR26I_DrEzhjFdx%2F-Mf6Bdr6qDABxAJUyGjo%2Fcrafting-search-example.gif?alt=media\&token=7b1f4c92-643c-4dcc-8d1a-5fb49ec43a0b)

### Column Types

BugSplat's data is grouped into various columns. Each column can hold 1 of 4 data types. Each data type has slightly different options regarding how it can be searched. The types of data searchable within BugSplat are as follows:

| **Type** | **Options**                                                                                                    |
| -------- | -------------------------------------------------------------------------------------------------------------- |
| Text     | equal to, not equal to, contains, does not contain, is in, is not in, empty, not empty, starts with, ends with |
| Number   | equal to, not equal to, greater than, less than, is in, is not in, empty, not empty                            |
| Date     | on or before, on or after                                                                                      |

### Sharing and Exporting Searches

Once you have the correct set of data selected, you might want to click **Copy Search**, to save the URL to your clipboard to share with a team member.

Searches can be bookmarked by your browser so that they can be accessed more quickly.

You can also export the selected data to CSV or JSON using the **Export** button so that the data can be viewed in tools such as Microsoft Excel.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-Mf66sR26I_DrEzhjFdx%2F-Mf6CJnMSm7tTXpZAjNq%2Fcopy-export-crashes-bs.gif?alt=media\&token=545b5165-26bd-45c4-97d5-feebb22ad411)

###


# Table Grouping

BugSplat's application data grouping and aggregation in search tool provides insight into your application's data and allows you to prioritize fixes based on a wide variety of criteria. The `Group By` tool is available on the [Crashes](https://app.bugsplat.com/v2/crashes) page.

## Basic Use Cases

Group By Email or IP address to determine which customers are crashing most often. Knowing which users are crashing the most allows your team to proactively fix issues instead of waiting for users to complain or give up on your software.

![Example of Grouping Data by IP Address](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-1cd7e90792d68a31954b67f541a0b4d9fe72a95f%2Fgroup-by-ip-address.png?alt=media)

Group By Application and Version to see which versions of your application are crashing the most. Knowing which versions are most problematic allows your team to selectively roll out updates or messaging to get users to upgrade to a stable version of your software.

Group By Error Message or Error Code to see which types of errors are occurring most frequently. If specific errors are more likely to occur in your application, this knowledge can help developers search for potential problems when doing code reviews.

## Advanced Use Cases

BugSplat's Key field can be set to an arbitrary value at runtime. If your team chooses to set the Key value to the user's locale, you can Group By Key to see which geographic locations are crashing most frequently. The Key field can also be set to a value representing the user's video card or graphics driver. Users can use Group By to determine which video cards are most problematic.

Group By Stack Key and User to see how many unique customers see a specific crash. Knowing which crashes are occurring for the most unique users allows your team to fix the issues that will have the most significant impact. You can export the results as a CSV file and count the number of rows for each Stack Key to determine which crash has been seen by the most users.

## Digging Deeper into Data

If you want to dig deeper into a specific group of crashes, simply expand the row you're interested in. There you will find useful data on the group and several sample crashes. To load the full set of crashes that meet the criteria you're interested in exploring, just click the 'Load all results' link.

![Group by Multiple Columns](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-93c3f300f07990c6525e61025df0de81563b8b79%2Fgroup-by-multiple.gif?alt=media)


# Grouping Crashes

## Overview

Deciding which crashes your team should focus on can seem daunting. For many applications, it's impossible to investigate every crash. Fortunately, BugSplat automatically groups similar crashes, allowing you to concentrate your efforts on the bugs causing the most instability.

BugSplat's [Summary](https://app.bugsplat.com/v2/summary) page is a table of crash groups. Usually, crash reports are grouped by the top stack frame when the application crashes. However, sometimes the top of a stack contains common code that causes unrelated crashes to be grouped together. When this happens, auto-group rules can automatically select a lower stack frame that more accurately groups related crashes.

### Auto-Group Rules

BugSplat has a set of customizable rules that skip over functions that are typically not interesting to application developers. Our default rules are designed to get you started quickly and can be modified as required for each crash report database.

The auto-group rules are pattern-based matching rules that skip irrelevant stack frames and create more meaningful crash groups. The three types of rules are **group by**, **ignore**, and **ignore frames up to and including**. Rules are defined per platform and can be specified to match either the **function** or **file** portion of the call stack.

You can view and change Auto-Group rules on the [Rules](https://app.bugsplat.com/v2/rules) page.

Let's look at how BugSplat groups a report with the Windows OS function `KERNELBASE!RaiseException` at the top of the stack. Our default rule is shown below:

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FfzywqOFpGUQlpQEZPkdd%2Fimage.png?alt=media&amp;token=bfb5b014-f250-4af0-aa59-772534d74e3c" alt=""><figcaption><p>Default Ignore Rule</p></figcaption></figure>

By default, BugSplat groups crashes by the function at the top of the call stack. When BugSplat processes reports containing `KERNELBASE!RaiseException` at the top of the stack, the **ignore** rule matches and crashes will automatically be grouped by the following frame of the call stack. To group deeper in the call stack, you can combine multiple **ignore** rules. Alternatively, you can use **ignore frames up to and including** rules to group after a specified pattern that matches anywhere in the call stack. Ignore rules are useful for excluding frames that are known to be common error conditions.

Developers can also add rules that **group by** frames matching certain patterns. **Group by** rules are useful for including items that can be identified as belonging to your application. For example, you might choose **group by** to specify a file matching a path on your build machine, or a function matching your main application's module.

Auto-Group rules are matched via [glob patterns](https://en.wikipedia.org/wiki/Glob_\(programming\)). The following table describes common glob patterns.

<table><thead><tr><th width="122">Pattern</th><th width="495">Description</th><th width="170">Example</th><th width="310">Matches</th><th width="224">Does not match</th></tr></thead><tbody><tr><td><code>*</code></td><td>matches any number of any characters including none</td><td>Law*</td><td>Law, Laws, or Lawyer</td><td></td></tr><tr><td><code>**</code></td><td>matches any number of path/directory segments. When used must be the only contents of a segment.</td><td>/**/some.*</td><td>/foo/bar/bah/some.txt, /some.txt, or /foo/some.txt</td><td></td></tr><tr><td><code>?</code></td><td>matches any single character</td><td>?at</td><td>Cat, cat, Bat or bat</td><td>at</td></tr><tr><td><code>[abc]</code></td><td>matches one character given in the bracket</td><td>[CB]at</td><td>Cat or Bat</td><td>cat or bat</td></tr><tr><td><code>[a-z]</code></td><td>matches one character from the range given in the bracket</td><td>Letter[0-9]</td><td>Letter0, Letter1, Letter2 up to Letter9</td><td>Letters, Letter or Letter10</td></tr><tr><td><code>[!abc]</code></td><td>matches one character that is not given in the bracket</td><td>[!C]at</td><td>Bat, bat, or cat</td><td>Cat</td></tr><tr><td><code>[!a-z]</code></td><td>matches one character that is not from the range given in the bracket</td><td>Letter[!3-5]</td><td>Letter1, Letter2, Letter6 up to Letter9 and Letterx etc.</td><td>Letter3, Letter4, Letter5 or Letterxx</td></tr></tbody></table>

Auto-group rules are processed in a specific, consistent order that cannot be changed. The rules engine follows the logic below:

* If there are any **group-by** rule matches, select the top-most matching frame as the candidate frame. Use the resulting frame for grouping. Don't process any more rules.
* If there are any **ignore frames up to and including** rule matches, select the lower-most matching frame as the candidate frame. Starting with the candidate frame, skip over any frames that match the **ignore** rules until a frame that doesn't match any ignore rules is found. Use the resulting frame for grouping. Don't process any more rules.
* At this point, neither **group-by** nor **group-after** rules matched any stack frames. The rules engine will apply the **ignore** rules starting with the top stack frame, skipping over any frames that match the **ignore** rules until it finds the first frame that isn't to be ignored. The resulting frame is used for grouping.

{% hint style="info" %}
When you specify a new Auto-Group rule, it will be applied to newly processed and reprocessed crashes only. To apply new rules, you can reprocess up to 50 reports at a time via the [Reprocess](/education/how-tos/batch-reprocess-crashes) button on the Crashes page. If you'd like to reprocess more than 50 crashes at a time, please contact [Support](mailto:support@bugsplat.com).
{% endhint %}

### Options

BugSplat can also ignore specific parts of the call stack when creating groups. By default, BugSplat will group items that match based on function name only. At the top of the [Rules](https://app.bugsplat.com/v2/rules) page you'll find the options **include module name**, **include line number**, and **include address offset**. Enabling these settings will include the respective properties in the group calculation.

The module name is the name of the library or executable that added the frame to the stack. The line number is the line of source code where the function crashed, and the address offset is the instruction pointer offset. The hex offset is only considered for grouping stack frames that are not symbolicated.

With all settings enabled, groups would be created by a match on the entire string `MyConsoleCrasher!Crash(42)`, where `MyConsoleCrasher` is the module name, and `42` is the line number. A group would also be created by a full match on the unsymbolicated frame `MyConsoleCrasher!Crash+0xfff`, where `0xfff` is the address offset. With all options disabled groups would be created by a match on just the function name `Crash`.

### Crashes Page

The [**Crashes**](https://app.bugsplat.com/v2/crashes) page displays a list of reports and their associated group under the **Group** column. We've added a rule that effectively skips `KERNELBASE!RaiseException` and the reports are now grouped by the next frame in the stack `MyConsoleCrasher!_CxxThrowException(75)`. To see the report's stack trace, click the value in the **ID** column.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-9482af7abab74edd9329e31b884dc2ca6c1cfab4%2Fimage%20(1).png?alt=media" alt=""><figcaption><p>Crash Page</p></figcaption></figure>

### Crash Page

On the **Crash** page, scroll down to the list of stack frames for the crashing thread. Notice that we didn't quite get our grouping rules correct. Our rules have caused the report to be grouped under the function in bold, `MyConsoleCrasher!_CxxThrowException`**.** The function we actually want to group on is `MyConsoleCrasher!ThrowByUser`. Expand the row containing `MyConsoleCrasher!ThrowByUser` to reveal the **Group Rules** button.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FG533PSbSSUZBXk3xKYdP%2Fcrash-expanded-frame.png?alt=media&amp;token=4daa1ab9-eaf8-4197-8a9f-75b4bc4187ce" alt=""><figcaption><p>Crash Page with Stack Frame Expanded</p></figcaption></figure>

We can click **Group Rules** and add another rule that **ignores frames up to and including** stack frames where the function matches the glob `*_CXXThrowException*`. After creating this rule and reprocessing the crash report, you will see the correct grouping.

### Summary Page

Once new grouping rules have been applied, navigate to the [**Summary**](https://app.bugsplat.com/v2/summary) page to view an overview of groups in the selected database. The **Summary** page provides report counts for all of the various groups. Targeting groups with the highest report **Count** will generally give teams the best return on their efforts. Another interesting metric to target is **Users Affected,** which represents the number of unique users who ran into a specific problem during the selected time frame.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FOanhmHp9D07gi24iYRzC%2Fimage.png?alt=media&amp;token=322e32a2-6659-4aa3-b475-d60c8e29853d" alt=""><figcaption><p>Summary Page</p></figcaption></figure>


# Commenting

BugSplat allows users to leave comments and have discussions about crashes and stack keys.

### Leaving Comments

Using the **Activity** module found at the bottom of the [Crash](/guides/using-the-app#crash) and [Stack Key](/guides/using-the-app#stack-key) pages allows users to comment and discuss issues pertaining to the defect.

This can be a useful tool for making personal notes or for having a larger discussion with team members.

Comments left in the **Activity** module persist and are viewable by anyone with access to the database where the crash or stack key lives.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-MfF5jvArD0LwQmaPeFr%2F-MfF9OwpSgr5_5jrkJRZ%2Fcommenting-crashes-bs.gif?alt=media\&token=78687f92-420c-47a2-9de5-5c3c78697531)

### Adding a Note

Notes differ slightly from comments as they are not designed to foster a conversation around a crash or stack key but are used to manually add details important to understanding the crash.

The “Notes” tools live in the right-hand action column of the [Crashes](/guides/using-the-app#crashes) and [Stack Key](/guides/using-the-app#stack-key) pages.

When text is added to the **Notes**tool that text is searchable and appears in line with other crash and error data on the [Crashes](/guides/using-the-app#crashes) page.

Team's use this tool to add custom, searchable data to crash reports and stack keys.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-MfFCb4v5cd1MwvIBkvw%2F-MfFCxxrKyK22Wk9DMAL%2Fadding-notes-bs.gif?alt=media\&token=cc832b25-cec1-480e-9f8a-418c2fa7b2f3)


# Alerts & Issue Trackers

Integrate BugSplat with your toolset to bring crash and other application performance data to improve your pre-existing workflow.

**Note** that you can see our doc for automatically creating issues in your defect tracker from BugSplat databases [here](/guides/integrating-with-tools/issue-trackers/automatic-issue-creation).

### Configurable Alerts

BugSplat provides tools for teams to get alerted the instant something changes in an application.

{% content-ref url="/pages/-MeRq-OuYsngYmt5COcv" %}
[Slack](/guides/integrating-with-tools/messanger-apps/slack)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRpufNunTz-hV\_77vS" %}
[Microsoft Teams](/guides/integrating-with-tools/messanger-apps/microsoft-teams)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRqBc6ieyj8BY6fa3v" %}
[Discord](/guides/integrating-with-tools/messanger-apps/discord)
{% endcontent-ref %}

{% content-ref url="/pages/-MekPbX8BxgSulMDs3WQ" %}
[Email](/guides/integrating-with-tools/messanger-apps/email)
{% endcontent-ref %}

### Issue Trackers

BugSplat connects with popular defect trackers allowing users to create new issues with a couple of clicks directly from a crash or [stack key](/education/bugsplat-terminology#stack-key).

{% content-ref url="/pages/-MeRmPwjeAY34HTF9ob3" %}
[Jira](/guides/integrating-with-tools/issue-trackers/jira)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRp\_ze4F1HvmoZNY7R" %}
[GitHub Issues](/guides/integrating-with-tools/issue-trackers/github-issues)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRm\_QW\_0YKfGsAKMST" %}
[Azure DevOps](/guides/integrating-with-tools/issue-trackers/azure-devops)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRotKdqt1dHxyC6joj" %}
[Broken mention](broken://pages/-MeRotKdqt1dHxyC6joj)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRpC22m6lBXSetioJF" %}
[Broken mention](broken://pages/-MeRpC22m6lBXSetioJF)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRqI7K25052Hxio3Hi" %}
[YouTrack](/guides/integrating-with-tools/issue-trackers/youtrack)
{% endcontent-ref %}

### Additional Features

{% content-ref url="/pages/AsZctUH6CXVz19ZwXSjH" %}
[Automatic Issue Creation for Defect Tracker Integrations](/guides/integrating-with-tools/issue-trackers/automatic-issue-creation)
{% endcontent-ref %}

### Request an Integration

We take user requests for new tool integrations seriously. Contact us via the methods listed in the link below, and let us know which tool you'd like to see next!

{% content-ref url="/pages/-Mf4bapjtj0Vpj9PznZL" %}
[Contact Us](/administration/contact-us)
{% endcontent-ref %}


# Configurable Alerts

BugSplat provides tools for teams to get alerted the instant something changes in an application.

These tools currently allow you to build alerts that show if your crash rate has increased to a certain number (configurable to any number) of crashes per minute or if a new type of crash is present in a certain database.

{% content-ref url="/pages/-MeRq-OuYsngYmt5COcv" %}
[Slack](/guides/integrating-with-tools/messanger-apps/slack)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRpufNunTz-hV\_77vS" %}
[Microsoft Teams](/guides/integrating-with-tools/messanger-apps/microsoft-teams)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRqBc6ieyj8BY6fa3v" %}
[Discord](/guides/integrating-with-tools/messanger-apps/discord)
{% endcontent-ref %}

{% content-ref url="/pages/-MekPbX8BxgSulMDs3WQ" %}
[Email](/guides/integrating-with-tools/messanger-apps/email)
{% endcontent-ref %}

{% content-ref url="/pages/zcdoJ4LwkVanYduMBtYV" %}
[Webhook](/guides/integrating-with-tools/messanger-apps/webhook)
{% endcontent-ref %}


# Slack

BugSplat’s Slack integration allows your team to receive alerts for new crashes and errors or new groups of crashes or errors. Receiving BugSplat alerts through Slack lets you stay on top of your application's stability and can serve as an early warning that something might be wrong.

{% hint style="warning" %}
**ATTENTION USERS OF BUGSPLAT'S** [**SLACK INTEGRATION**](https://docs.bugsplat.com/introduction/development/integrating-with-tools/messanger-apps/slack#integrating-slack-with-bugsplat-docs)

As part of our ongoing security work at BugSplat, we refreshed our Slack application's OAuth token on the morning of 17-July-2024.

If you use our [Slack notification integration](https://docs.bugsplat.com/introduction/development/integrating-with-tools/messanger-apps/slack#integrating-slack-with-bugsplat-docs), someone on your team may need to reauthorize it to ensure its continuing functionality.

Please feel free to contact <support@bugsplat.com> if you need more help.

Very best,

[![](https://changelog.bugsplat.com/~gitbook/image?url=https%3A%2F%2Fdownloads.intercomcdn.com%2Fi%2Fo%2F1116483060%2F467bce4a9b8b2d564f60aaea%2Fbugsplat-team-signature.png%3Fexpires%3D1721228400%26signature%3D8d98ee6172f27aa416044ad496ef2bd650febb7decee6b550532f5fccaac8656\&width=300\&dpr=4\&quality=100\&sign=b9a63021\&sv=1)](https://downloads.intercomcdn.com/i/o/1116483060/467bce4a9b8b2d564f60aaea/bugsplat-team-signature.png?expires=1721228400\&signature=8d98ee6172f27aa416044ad496ef2bd650febb7decee6b550532f5fccaac8656)
{% endhint %}

#### Integrating Slack with BugSplat <a href="#integrating-slack-with-bugsplat-docs" id="integrating-slack-with-bugsplat-docs"></a>

1. Login to [BugSplat](https://app.bugsplat.com/cognito/login) and navigate to the [Notifications](https://app.bugsplat.com/v2/database/integrations#notifications)[ ](https://app.bugsplat.com/v2/database/notifications)page.
2. Select the Database for which you'd like to configure alerts
3. Under the **Slack** section, click the **Add to Slack** button.
4. You’ll be prompted to confirm your identity and choose which channel you would like the notifications posted to.
5. Select **Authorize**.
6. Use the toggle buttons to set your notification preferences: **New Report Notifications**, **New Group Notifications**, and **Regression Alerts**.
7. Use the **Fields** dropdown to select the fields you'd like to include in your notifications.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FsHF8ZaQjoyOHRMW9KSiA%2Fslack.gif?alt=media&amp;token=35ea231e-c90a-4f96-a1a0-c9aa55ba93ed" alt=""><figcaption><p>Configuring BugSplat's Slack Integration</p></figcaption></figure>


# Microsoft Teams

BugSplat’s Teams integration allows your team to receive alerts for new crashes and errors or groups of crashes or errors. Receiving BugSplat alerts through Teams lets you stay on top of your application's stability and can serve as an early warning that something might be wrong.

#### Integrating BugSplat with Microsoft Teams <a href="#integrating-slack-with-bugsplat-docs" id="integrating-slack-with-bugsplat-docs"></a>

{% embed url="<https://bugsplat.wistia.com/medias/3742ugxbbw>" %}
Teams Webhook Walkthrough
{% endembed %}

1. Create a new Teams webhook workflow following the guide found [here](https://support.microsoft.com/en-us/office/post-a-workflow-when-a-webhook-request-is-received-in-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498).
2. Login to [BugSplat](https://app.bugsplat.com/cognito/login) and navigate to the [Notifications](https://app.bugsplat.com/v2/database/integrations#notifications) page.
3. Select the Database for which you'd like to configure alerts
4. Under the **Teams** section, enter the webhook URL for your channel and click **Update**.
5. Use the toggle buttons to set your notification preferences: **New Report Notifications**, **New Group Notifications**, and **Regression Alerts**.
6. Use the **Fields** dropdown to select the fields you want to include in your notifications.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fb1lFZERDQ6pGC003IlLo%2Fteams.gif?alt=media&amp;token=6d21af17-5c70-4acb-aa6d-1d68927d6277" alt=""><figcaption><p>Configuring BugSplat's Teams Integration</p></figcaption></figure>


# Discord

BugSplat’s Discord integration allows your team to receive alerts for new crashes and errors or new groups of crashes or errors. Receiving BugSplat alerts through Discord lets you stay on top of your application's stability and can serve as an early warning that something might be wrong.

## Integrating Discord with BugSplat <a href="#integrating-slack-with-bugsplat-docs" id="integrating-slack-with-bugsplat-docs"></a>

1. Create a new Discord webhook following the guide found [here](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks).
2. Login to [BugSplat](https://app.bugsplat.com/cognito/login) and navigate to the [Notifications](https://app.bugsplat.com/v2/database/integrations#notifications) page.
3. Select the Database for which you'd like to configure alerts
4. Under the **Discord** section, enter the webhook URL for your channel and click **Update**. More information regarding how to create a webhook URL can be found [here](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks).
5. Use the toggle buttons to set your notification preferences. You can choose to be notified for each new report or each new unique report group.
6. Use the **Fields** dropdown to select the fields you'd like to include in your notifications.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-4ab225437eacfc25e5a38e9ef0bd7f353cdf0c2e%2Fdiscord-integration-settings.png?alt=media" alt="BugSplat Discord notification settings"><figcaption><p>Configuring BugSplat's Discord Integration</p></figcaption></figure>


# Email

BugSplat’s integration with Email Alerts allows your team to receive every new crash from a specific database as an alert or know when a new type of crash has occurred in a database.

These alerts let you stay on top of your crashes and can serve as an early warning that something might be wrong.

#### Integrating Email Alerts with BugSplat <a href="#integrating-email-alerts-with-bugsplat-docs" id="integrating-email-alerts-with-bugsplat-docs"></a>

1. Login to your [account](https://app.bugsplat.com/cognito/login).
2. Go to the [Notifications](https://app.bugsplat.com/v2/database/integrations#notifications) page.
3. To receive emails when your database's crash rate exceeds a certain level, fill in the **Email** and **Reports (per minute)** fields under **Crash Rate Alerts** and click **Update**.
4. To receive hourly summaries of your database's crash activity, fill in the **Email** field under the **Hourly Report Digest Email** section and click **Update**.


# Webhook

BugSplat’s Webhook integration allows your team to configure custom notifications for each new report or group of reports. BugSplat's Webhook integration allows you to build integrations unique and novel integrations that can be tailor-fit to your company's workflow.

## Configuring a BugSplat Webhook <a href="#integrating-slack-with-bugsplat-docs" id="integrating-slack-with-bugsplat-docs"></a>

1. Login to [BugSplat](https://app.bugsplat.com/cognito/login) and navigate to the [Notifications](https://app.bugsplat.com/v2/database/integrations#notifications) page.
2. Select the Database for which you'd like to configure alerts.
3. Under the **Webhook** section, enter the URL of the webhook you would like to invoke and click **Update**.
4. Use the toggle buttons to set your notification preferences. You can be notified for each new report or unique report group.

Once configured, BugSplat will post an object that matches the following interface to your Webhook. Unlike other notifications, Webhook crash notifications have no maximum throughput limitation.

## Webhook Notification

<mark style="color:green;">`POST`</mark> `https://your-domain.com/path/to/your/webhook`

Notification payload for new BugSplat report or new BugSplat group.

#### Request Body

| Name             | Type         | Description                                                                                      |
| ---------------- | ------------ | ------------------------------------------------------------------------------------------------ |
| notificationType | string       | <p>Type of notification: "NewReport", or</p><p>"NewGroup"</p>                                    |
| id               | number       | BugSplat crash ID for new report                                                                 |
| crashTypeId      | number       | Numeric identifier for the platform used to post report                                          |
| stackKeyId       | number       | BugSplat ID for report group                                                                     |
| stackId          | number       | Unique call stack identifier                                                                     |
| stackKeyName     | string       | Function name and line number used to group the report                                           |
| callstack        | object array | Array of stack frame objects. May be empty if BugSplat matches an existing crash using the hash. |
| database         | string       | BugSplat database where report is stored                                                         |
| application      | string       | Application name associated with report                                                          |
| version          | string       | Version associated with report                                                                   |
| key              | string       | Identifier for specific flavor of application associated with report                             |
| user             | string       | End-user associated with generated report                                                        |
| email            | string       | End-user's email associated with generated report                                                |
| ipAddress        | string       | End-user's IP address (can be obfuscated via Options page)                                       |
| hash             | string       | Hash representing unique report call stack. Not available for all crashes.                       |
| exceptionCode    | string       | Code associated with issue that caused the report to be generated                                |
| exceptionMessage | string       | Message associated with issue that caused the report to be generated                             |
| received         | datetime     | Timestamp of generated report                                                                    |
| platform         | string       | Human-readable platform name (e.g., "Windows", "macOS", "Crashpad/Breakpad", "Unity")            |
| crashFileUrl     | string       | Presigned URL to download the crash file. URL expires after a limited time.                      |
| attributes       | object       | Key-value pairs of custom attributes submitted with the crash report                             |
| crashTime        | datetime     | Timestamp of when the crash occurred                                                             |
| userDescription  | string       | End-user's description of the crash, if provided                                                 |


# Issue Trackers

{% hint style="warning" %}
Some organizations restrict access to their issue tracker by IP address. If you need to allow access to BugSplat, add the IP addresses [23.22.79.2](https://www.whatismyip.com/23.22.79.2/?iref=home), [3.93.104.250](https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#ElasticIpDetails:AllocationId=eipalloc-0da0d84b88eed6812), and [34.194.164.107](https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#ElasticIpDetails:AllocationId=eipalloc-0cd966956c064a2e4) to your whitelist.
{% endhint %}

BugSplat connects with popular defect trackers, allowing users to create new issues with a few clicks directly from a crash or stack key.

This allows teams to build issues that contain full crash information, like symbolic call stacks, as well as other crash-specific data that can help your team crush bugs faster. Issues created from BugSplat also include hyperlinks that allow users to quickly navigate between issues and the crash or stack key associated with them.

**Note** you can see our doc for automatically creating issues in your defect tracker from BugSplat databases [here](/guides/integrating-with-tools/issue-trackers/automatic-issue-creation).

{% content-ref url="/pages/-MeRm\_QW\_0YKfGsAKMST" %}
[Azure DevOps](/guides/integrating-with-tools/issue-trackers/azure-devops)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRp\_ze4F1HvmoZNY7R" %}
[GitHub Issues](/guides/integrating-with-tools/issue-trackers/github-issues)
{% endcontent-ref %}

{% content-ref url="/pages/mCciyckqm4gBXS1tS5LS" %}
[GitLab](/guides/integrating-with-tools/issue-trackers/gitlab)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRmPwjeAY34HTF9ob3" %}
[Jira](/guides/integrating-with-tools/issue-trackers/jira)
{% endcontent-ref %}

{% content-ref url="/pages/6nWUxwaYMEvyym07q4sW" %}
[Favro](/guides/integrating-with-tools/issue-trackers/favro)
{% endcontent-ref %}

{% content-ref url="/pages/BHocNLPys1J6XtI42UAl" %}
[Monday.com](/guides/integrating-with-tools/issue-trackers/monday)
{% endcontent-ref %}

{% content-ref url="/pages/-MeRqI7K25052Hxio3Hi" %}
[YouTrack](/guides/integrating-with-tools/issue-trackers/youtrack)
{% endcontent-ref %}

### Additional Features

{% content-ref url="/pages/AsZctUH6CXVz19ZwXSjH" %}
[Automatic Issue Creation for Defect Tracker Integrations](/guides/integrating-with-tools/issue-trackers/automatic-issue-creation)
{% endcontent-ref %}


# Azure DevOps

Visual Studio Team Services (Azure DevOps) integration with BugSplat allows your team to create defects with a few clicks. Hyperlinks allow quick navigation from defects to crash reports and back. Defects created from BugSplat automatically include symbolic call stack information and other crash-specific data.

### Integrating Azure DevOps with BugSplat

1. Login to your BugSplat account.
2. Click the Gear icon (⚙️) in the top right of the page and navigate to the Database Settings page, and under **Database > Integrations >** **Defect Trackers**, select **Azure DevOps** from the options shown.
3. Enter your **Azure DevOps URL** and **Personal Access Token** into the appropriate fields.
4. Click **Update**.
5. If the connection is successful, you can select your desired project from the **Project** dropdown list.
6. Click **Update**.

### Creating an issue in Azure DevOps from a BugSplat crash report

1\. Create a new defect from the crash page or a [stack key](/education/bugsplat-terminology#stack-key) page by using the **Create Defect** button.

2\. Enter relevant details and click the **Submit** button to create the defect. You can also enter an existing **Defect ID** if you'd like to associate a crash or stack key with an existing issue from Azure DevOps.

3\. Click the link to view the new Azure DevOps defect created by BugSplat.

### Automated Defect Creation

Want to create issues in Azure DevOps automatically for each new crash or crash group? Check out the document on auto-creating defects in your third-party defect tracker tool [here](/guides/integrating-with-tools/issue-trackers/automatic-issue-creation).


# Favro

{% hint style="info" %}
BugSplat's Favro integration is in beta. Please message us if you want to request a feature or report a bug.
{% endhint %}

BugSplat allows your team to create cards in [Favro](https://favro.com/) with a few clicks. Our integration adds valuable crash data to your Favro cards and links to the BugSplat dashboard so your team can quickly switch between looking at BugSplat and your Favro workflows.

#### Integrating Favro and BugSplat

1. Create an API token in Favro via **My Profile > API Tokens > Create New Token**
2. Navigate to the **⚙️ > Integrations > Defect Trackers** page in BugSplat
3. Select **Favro** and click the **Connect** button
4. Enter your **Email** and **Token** and click **Update**
5. You should now see a list of organizations. Choose the correct organization and click **Update**
6. You should now see a list of widgets. Choose a widget and click **Update**
7. Optionally enter comma-separated tags in the **Tags** field and click **Update**

#### Push a New Item to Favro

1. To push a new card to Favro, use the **Create Defect** button on the **Crashes** or **Crash Group** pages.
2. Enter relevant details and click the **Submit** button to create the defect.
3. Click the link to view the new Favro card created by BugSplat.
4. View the card in Favro to see that stack trace and other valuable info from BugSplat.

#### Automated Defect Creation <a href="#automated-defect-creation" id="automated-defect-creation"></a>

Want to create cards in Favro automatically for each new crash or crash group? Check out the document on auto-creating defects in your third-party defect tracker tool [here](https://docs.bugsplat.com/introduction/development/integrating-with-tools/issue-trackers/auto-creating-defects-from-bugsplat-databases-in-attached-third-party-trackers).


# Jira

BugSplat's Jira integration allows your team to create defects with a few clicks. Links from BugSplat to Jira allow for quick navigation from defects to crash reports. Defects created from BugSplat automatically include symbolic call stack information and other crash-specific data.

### Integrating Jira and BugSplat

1. Login to your account.
2. Click the Gear icon (⚙️) at the top right of the page and navigate to the [Database Settings](https://app.bugsplat.com/v2/database/integrations) page, and under **Database > Integrations >** **Defect Tracker**, select **Jira** from the options shown.
3. Enter your **Username**, **Token**, and **URL** into the appropriate boxes. For Jira Cloud, use an [API Token](https://id.atlassian.com/manage-profile/security/api-tokens) in the **Token** field. For self-hosted Jira Server use your account's password for the **Token** field.
4. Click **Update**.
5. Once a connection to Jira has been established, you can select one of your projects from the project dropdown list.
6. After selecting your desired project, click **Update** again.
7. Add additional data in any of the other fields, including the optional **Issue Type** field.

{% hint style="info" %}
The optional **Assignee ID** field requires the Atlassian user ID when using Jira Cloud. Jira Server doesn't support user IDs, so use the user name.
{% endhint %}

#### Required scopes for scoped (granular) API tokens

BugSplat supports both **classic (unscoped)** Atlassian API tokens and the newer **scoped (granular)** API tokens. Classic tokens grant all of the issuing user's permissions and don't require scope selection. Scoped tokens follow least-privilege and must be created with the scopes listed below; missing any scope will cause Create Defect or status sync to fail with a 401 or 403.

**Read scopes**

* `read:jira-work`
* `read:issue:jira`
* `read:project:jira`

**Write scopes**

* `write:jira-work`
* `write:issue:jira`
* `write:comment:jira`

### Creating an Issue in Jira

1\. Create a new defect from the crashes page or a [stack key](/education/bugsplat-terminology#stack-key) page by using the **Create Defect** button.

2\. Enter relevant details and click the **Submit** button to create the defect. You can also enter an existing **Defect ID** if you'd like to associate a crash or stack key with an existing defect from Jira.

3\. Click the link to view the new Jira issue created by BugSplat.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FQpCWRBH4KNq00fOXIMaC%2Foutput.gif?alt=media&amp;token=e5d8bc98-3858-4484-bcbe-4ad65b4bd65c" alt=""><figcaption><p>Create a Jira Issue with BugSplat</p></figcaption></figure>

### Bi-Directional Status Syncing

BugSplat can listen to status updates on issues from Jira and update a defect group's status accordingly. Similarly, when a defect group's state is updated in BugSplat, the update can be pushed to Jira, which allows the two systems to stay synchronized.

To configure bi-directional Jira synchronization, perform the following steps:

1. Create a Jira System webhook via **⚙️ > System > WebHooks**
2. Set the WebHook URL value to `https://app.bugsplat.com/api/webhook/jira.php?database=your-bugsplat-database`, being sure to use the name of your BugSplat database
3. Generate a **WebHook Secret** and copy the secret value
4. Configure the webhook to emit events for **Issue Updated**
5. Navigate to BugSplat's [Defect Tracker Integration](https://app.bugsplat.com/v2/database/integrations#defect-trackers) page
6. Enter values for **Webhook Secret**, **Open Status**, and **Closed Status**

You can test the integration by linking a Jira issue to a BugSplat defect. Set the BugSplat status to Open or Closed. When the status changes in BugSplat, the Jira status should be set to the value you entered for **Open Status** and **Closed Status,** respectively.

### Automated Defect Creation

Want to create issues in Jira automatically for each new crash or crash group? Check out the document on auto-creating defects in your third-party defect tracker tool [here](/guides/integrating-with-tools/issue-trackers/automatic-issue-creation).


# GitHub Issues

BugSplat's GitHub Issues integration allows your team to create defects from crash reports with only a few clicks. Pushing crash reports to GitHub Issues creates hyperlinks in BugSplat and allows for quick navigation from crash reports to your defect tracker and back again. Defects created from BugSplat automatically include symbolic call stack information and other crash-specific data.

### Integrating GitHub Issues with BugSplat

1. Generate a [Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) (PAT) in GitHub. You may use a [classic PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#personal-access-tokens-classic) or a [fine-grained PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#fine-grained-personal-access-tokens), ensuring you set the correct **Resource Owner**, select the correct **Repository**, and add **Issues Read/Write** permissions.
2. [Login](https://app.bugsplat.com/cognito/login) to your BugSplat account.
3. Click the Gear icon (⚙️) in the top right of the page and navigate to the [Database Settings](https://app.bugsplat.com/v2/database/integrations) page and under **Database > Integrations >** **Defect Trackers > GitHub** from the options shown.
4. Enter your GitHub **Username**, **API Token,** and **Repo Owner** into the appropriate boxes and click **Update**.
5. Select your desired project.
6. Click **Update** once more to complete the integration.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-e15c3f34757a2d4f39537765e020949bb1d1d24d%2Fgithub-issues-integration-settings.png?alt=media" alt="BugSplat GitHub Issues Defect Tracker settings"><figcaption><p>A completed GitHub Issues Defect Tracker configuration on the Database Settings page</p></figcaption></figure>

### Creating a defect in GitHub Issues from a BugSplat crash report

1\. Create a new defect from the crash page or a [stack key](/education/bugsplat-terminology#stack-key) page by using the **Create Defect** button.

2\. Enter relevant details and click the **Submit** button to create the defect. You can also enter an existing **Defect ID** if you'd like to associate a crash or stack key with an existing issue from GitHub.

3\. Click the link to view the new GitHub issue created by BugSplat.

### Automated Defect Creation

Want to create issues in GitHub automatically for each new crash or crash group? Check out the document on auto-creating defects in your third-party defect tracker tool [here](/guides/integrating-with-tools/issue-trackers/automatic-issue-creation).


# GitLab

{% hint style="info" %}
BugSplat's GitLab integration is in beta. Please message us if you want to request a feature or report a bug.
{% endhint %}

BugSplat allows your team to create issues in [GitLab](https://gitlab.com) with a few clicks. Our integration adds valuable crash data to your GitLab issues and links to the BugSplat dashboard so your team can quickly switch between looking at BugSplat and your GitLab repos.

#### Integrating GitLab and BugSplat

1. Login to your account.
2. Click the Gear icon (⚙️) at the top right of the page and navigate to the [Database Settings](https://app.bugsplat.com/v2/database/integrations) page, and under **Database > Integrations >** **Defect Tracker**, select **GitLab** from the options shown.
3. Enter your GitLab [personal API token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#create-a-personal-access-token) with the API scope into the field labeled **Token.**
4. Click **Update**.
5. Once you have connected to GitLab, you can select one of your projects from the **Projects** dropdown list.
6. After selecting your desired board, click **Update** again.

#### Push a New Item to GitLab

1. Use the **Create Defect** button to create a new item on the crashes page or a crash group page to push a new item to GitLab.
2. Enter relevant details and click the **Submit** button to create the defect.
3. Click the link to view the new GitLab issue created by BugSplat.
4. View the items' updates to see that stack trace and other valuable info from BugSplat.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FsDHHI8WnmgTxgCdiGmRd%2Foutput.gif?alt=media&amp;token=e604ffda-e096-45ad-ae58-cb5a35d80b01" alt=""><figcaption><p>Add BugSplat Item to GitLab</p></figcaption></figure>

#### Automated Defect Creation <a href="#automated-defect-creation" id="automated-defect-creation"></a>

Want to create issues in GitLab automatically for each new crash or crash group? Check out the document on auto-creating defects in your third-party defect tracker tool [here](https://docs.bugsplat.com/introduction/development/integrating-with-tools/issue-trackers/auto-creating-defects-from-bugsplat-databases-in-attached-third-party-trackers).


# Monday.com

{% hint style="info" %}
BugSplat's Monday.com integration is in beta. Please message us if you want to request a feature or report a bug.
{% endhint %}

BugSplat allows your team to create items on [Monday.com](https://monday.com/) with a few clicks. Our integration adds valuable crash data to your Monday.com items and links to the BugSplat dashboard, so your team can quickly switch between looking at BugSplat and your Monday.com boards.

### Integrating Monday.com and BugSplat

1. Login to your account.
2. Click the Gear icon (⚙️) at the top right of the page and navigate to the [Database Settings](https://app.bugsplat.com/v2/database/integrations) page, and under **Database > Integrations >** **Defect Tracker**, select **Monday.com** from the options shown.
3. Enter your Monday.com [personal API token](https://developer.monday.com/api-reference/docs/authentication) into the field labeled **Token.**
4. Click **Update**.
5. Once you have connected to Monday.com, you can select one of your boards from the **Boards** dropdown list.
6. After selecting your desired board, click **Update** again.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-30ab29c909530abffadb8af3f9e1e062bc401bd1%2Fmonday-integration-settings.png?alt=media" alt="BugSplat Monday.com Defect Tracker settings"><figcaption><p>A completed Monday.com Defect Tracker configuration on the Database Settings page</p></figcaption></figure>

### Push a new Item to Monday.com

1. Use the **Create Defect** button to create a new item on the crashes page or a crash group page to push a new item to Monday.com.
2. Enter relevant details and click the **Submit** button to create the defect.
3. Click the link to view the new Monday.com item created by BugSplat.
4. View the items' updates to see that stack trace and other valuable info from BugSplat.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FZ55KD0bI5XQlwiJSdBta%2Foutput.gif?alt=media&amp;token=1b25e2ad-71e6-44d6-92d9-0255dd35d30b" alt=""><figcaption><p>Add BugSplat Item to Monday.com</p></figcaption></figure>

### Automated Defect Creation

Want to create issues in Monday.com automatically for each new crash or crash group? Check out the document on auto-creating defects in your third-party defect tracker tool [here](/guides/integrating-with-tools/issue-trackers/automatic-issue-creation).


# YouTrack

YouTrack integration with BugSplat crash reports allows your team to create defects with a single-button click. Hyperlinks allow quick navigation from defects to crash reports and back. Defects created from BugSplat automatically include symbolic call stack information and other crash-specific data.

### Integrating YouTrack with BugSplat

1. [Login](https://app.bugsplat.com/cognito/login) to your account.
2. Click the Gear icon (⚙️) in the top right of the page and navigate to the Database Settings page, and under **Database > Integrations >** **Defect Tracker**, select **YouTrack** from the options shown.
3. Enter your **Username**, YouTrack **API Token**, YouTrack **URL**, and any additional options.

{% hint style="info" %}
You can find **Username**, **API Token**, and **URL** on the YouTrack Hub Integration page. [Click to learn more](https://www.jetbrains.com/help/youtrack/incloud/Manage-Permanent-Token.html).
{% endhint %}

4. Select your desired **Project**.
5. Click **Update**.

### Creating a defect in YouTrack from a BugSplat crash report

1\. Create a new defect from the crash page or a [stack key](/education/bugsplat-terminology#stack-key) page by using the **Create Defect** button.

2\. Enter relevant details and click the **Submit** button to create the defect. You can also enter an existing **Defect ID** if you'd like to associate a crash or stack key with an existing issue from YouTrack.

3\. Click the link to view the new YouTrack defect created by BugSplat.

### Automated Defect Creation

Want to create issues in Jira automatically for each new crash or crash group? Check out the document on auto-creating defects in your third-party defect tracker tool [here](/guides/integrating-with-tools/issue-trackers/automatic-issue-creation).


# Automatic Issue Creation for Defect Tracker Integrations

### Introduction

BugSplat provides the capability to auto-create issues in third-party issue trackers like [Jira](/guides/integrating-with-tools/issue-trackers/jira), [GitHub Issues](/guides/integrating-with-tools/issue-trackers/github-issues), [Azure DevOps](/guides/integrating-with-tools/issue-trackers/azure-devops), and [more](/guides/integrating-with-tools/issue-trackers) directly from your databases. Issues created from BugSplat contain rich debugging information to help your team prioritize and fix crashes. This document details the process of setting up this feature.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fgit-blob-ec79fa11b42e9a8620d6879d1b39ec37d38f532d%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

#### Configuration

To set up the feature, follow these steps:

1. Navigate to the [Defect Trackers](https://app.bugsplat.com/v2/database/integrations) tab of the Database settings page
2. Follow the instructions to configure your [Defect Tracker](/guides/integrating-with-tools#issue-trackers) if you haven't already
3. Enable the **New Crashes** or **New Groups** setting. Consider setting the **Group Threshold** value to ensure that new groups have multiple crashes before an issue is pushed to your Defect Tracker.
4. Save your settings.

Once these steps are completed, BugSplat will automatically create issues in your defect tracker according to the specified rules.

#### Options

There are two primary options for auto-creating defects:

1. **Creating a new linked issue with every new crash**: This option will generate a new issue in your linked third-party tracker for each new crash recorded in BugSplat.
2. **Creating a new linked issue for every new type of crash group:** This option generates a new issue for each unique type of crash group that is recorded. You can also set a threshold for the number of crashes in a group that are needed before an automatic issue is created. By setting this `Group Threshold` value to `1`, an issue will be created for every new crash group.

#### Feedback and Feature Requests

We are continually expanding our integrations and will release additional features for third-party trackers in the near future. Your feedback helps us improve. Please send us your thoughts and suggestions at <support@bugsplat.com>. We also welcome your requests for new features. In doing so, you can help us shape the future of BugSplat's third-party tracker integrations to better meet your needs.


# Production

The Production section covers documents that help put your application into production with BugSplat.

[**Support Responses**](/guides/production/setting-up-custom-support-responses) - are a custom message set by you that is displayed to an end-user as a new tab in their default browser after they experience a specific type of crash. They are useful for alerting users to known issues or passing along information important to fixing a defect.

[**Managing Versions**](/guides/production/managing-versions) - instructions on adding or removing symbols, retiring old versions you no longer wish to collect crashes from, and adding support for Full Memory Dumps.

[**Security and Compliance**](/guides/production/security-privacy-and-compliance) - Overview of BugSplat's security program, SOC-2 and GDPR compliance, terms, privacy policy, and more.

[Regression Alerts](/guides/production/regression-alerts) - After a defect has been marked as closed, BugSplat can automatically identify when a crash recurs in a newer version and notify your team.


# Versions

BugSplat's Versions Page

The [Versions](https://app.bugsplat.com/v2/versions) page lists each unique application name and version sent to BugSplat. It displays the first and last report dates of each crash report. If symbols have been uploaded with this application name/version, the symbol size will be greater than zero.

### Adding and Removing Symbols

Symbol files can be added and removed via the [Versions](https://app.bugsplat.com/v2/versions) page. Symbol files are required for BugSplat to display call stacks with function names and line numbers. BugSplat will automatically clean up symbol files that are no longer in use, and in most cases, you will not need to remove symbol files manually. If you uploaded incorrect symbol files, uploaded duplicates, or have uploaded extraneous symbol files, we recommend removing unnecessary files so that BugSplat can process your crashes as fast as possible.

Symbols are typically uploaded using command line tools (such as [symbol-upload](/guides/working-with-symbol-files/upload-symbols-with-symbol-upload)) as part of your build process. If you'd like to add Symbol files manually, you can use the **Upload Symbols** button to upload symbols for a new version or expand a row to upload symbols to an existing version. For more information on manually uploading symbols, please visit this [link](/guides/working-with-symbol-files/how-to-manually-upload-symbols). To remove symbol files, expand a row that corresponds to the version you'd like to remove and click the **Delete Symbols** button. Note that the row showing the application name/version will not be deleted, but it will show a size of zero.

![Managing Symbols on the Versions Page](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FtSHOXKrfo5NIWgfBNTKm%2Fimage.png?alt=media\&token=52500889-2f4a-40df-9e17-b4ba97cacc39)

### Retiring Versions

If needed, you can retire old versions of your application using the [Versions](https://app.bugsplat.com/v2/versions) page. BugSplat does not process crash reports from retired versions, nor do they contribute to your crash volume. Since retired crash reports are essentially invisible to you, we suggest retiring versions only if you no longer support that version of the product.

![Retiring a Version](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FDi3HKPMpZ6ugIAAWunmv%2Fretire-version.gif?alt=media\&token=5e5b190c-da34-453d-a941-86eefb1b0375)

### Full Dump Support

BugSplat's [Native](/integrations/desktop/cplusplus) and [.NET](/integrations/desktop/bugsplat-for-dot-net) SDKs support the creation of [Full Memory Dumps](/integrations/desktop/cplusplus/full-memory-dumps). Full Dump support can be added to your subscription for an additional cost. We recommend only enabling Full Dump support on an as-needed basis to ensure end-user crash uploads and processing happens quickly. If you are interested in Full Memory Dumps, please contact our [support](/administration/contact-us) team.\
\
Once Full Dump support has been added to your account, you can enable it on a per-version basis. First, navigate to the [Versions](https://app.bugsplat.com/v2/versions) page, click the **Show/hide columns** button, and ensure the **Full Dumps** column is visible. Next, click the checkbox for the version generating Full Memory Dumps. Finally, you will need to ensure your application has configured BugSplat to generate Full Memory Dumps when this setting is enabled.

For more information on how to configure the BugSplat SDK to generate Full Memory Dumps, please see this [doc](/integrations/desktop/cplusplus/full-memory-dumps).

![Enabling Full Dumps](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2F8jJlFB5IVN1qePnKReSN%2Ffull-dumps.gif?alt=media\&token=d0f601df-6ed3-478f-8ee1-e6c53e974dd5)


# Regression Alerts

BugSplat can be configured to notify developers when a defect marked as Closed recurs in a newer version of their software. Crash groups can have one of four statuses: Open, Closed, Regression, and Ignored. A regression happens when a crash group is marked as closed, but an instance of the crash occurs in a newer version.

In BugSplat, developers can update the status of a group by clicking the Open, Closed, Regression, or Ignored badge and selecting a new status.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2Fp1E8FaYtwjmju12rbAL9%2Fstatus-open-closed.gif?alt=media&amp;token=83913e51-9f5d-4826-8c19-b880d6444c1c" alt=""><figcaption><p>Set the Status of a Group to Closed</p></figcaption></figure>

When a group's status is set to Closed, BugSplat notes the latest version of the application. If the same crash arrives at BugSplat from a newer version, BugSplat considers this a regression and sets the status from Closed to Regression accordingly.

### Alerts

BugSplat can be configured to send a [notification](/guides/integrating-with-tools) via [Discord](/guides/integrating-with-tools/messanger-apps/discord), [Teams](/guides/integrating-with-tools/messanger-apps/microsoft-teams), or [Slack](/guides/integrating-with-tools/messanger-apps/slack) when a regression occurs. Follow the links in the notifications documentation and choose the Regression Alerts option once you've connected to your favorite messaging platform.

### Defect Tracker Sync

If you're using [Jira](/guides/integrating-with-tools/issue-trackers/jira), BugSplat can be configured to update the status of linked issues. On the [Defect Trackers](https://app.bugsplat.com/v2/database/integrations?database=Fred#defect-trackers) page set the status you'd like BugSplat to set on Jira when a crash is identified as a regression.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FRfqLm0TaqVAAeNDT9g6m%2Fregression-status.gif?alt=media&amp;token=eccffd10-8bbd-495a-9fda-1f0417c79dfa" alt=""><figcaption><p>Mapping the Jira Regression Status</p></figcaption></figure>


# Security and Compliance

Welcome to BugSplat’s Security, Privacy, and Compliance Documentation.

We take security and privacy seriously at BugSplat. We also love talking about it with anyone interested. If you have a question, please send us a note at [support@bugsplat.com,](mailto:support@bugsplat.com) or drop by our [Discord](https://discord.gg/K4KjjRV5ve) and talk to us directly.

{% content-ref url="/pages/-MeWC-PL7PFFCJ0GV0Rr" %}
[Security Program](/guides/production/security-privacy-and-compliance/security-program)
{% endcontent-ref %}

{% content-ref url="/pages/-MeWBSH9QlTsdk3iijgm" %}
[GDPR & UK GDPR Compliance](/guides/production/security-privacy-and-compliance/gdpr)
{% endcontent-ref %}

{% content-ref url="/pages/-MeWC4vwUj1UII3I\_c9K" %}
[SOC 2](/guides/production/security-privacy-and-compliance/soc-2)
{% endcontent-ref %}

{% content-ref url="/pages/-MeWFosyCxsyQFqCwAnl" %}
[Avoid Collecting Personally Identifiable Information (PII)](/guides/production/security-privacy-and-compliance/avoid-collecting-personally-identifiable-information-pii)
{% endcontent-ref %}

{% content-ref url="/pages/-MlRjOuWuTd\_1pqneW31" %}
[Crash Expiry](/guides/production/security-privacy-and-compliance/crash-expiry)
{% endcontent-ref %}

{% content-ref url="/pages/-MhQbU2cvZxT\_Mo-nGD0" %}
[Privacy Policy](/guides/production/security-privacy-and-compliance/privacy-policy)
{% endcontent-ref %}

{% content-ref url="/pages/-MhQaSjPFZmuGsv5h6fo" %}
[Terms](/guides/production/security-privacy-and-compliance/terms)
{% endcontent-ref %}


# Security Program

Updated 25-Oct-2023

## Security Program

BugSplat, LLC (“BugSplat”) maintains an Information Security Program (“ISP”) in conformance with the requirements set forth below, which may be incorporated by reference into a Customer License Agreement (the “Agreement”). In the event of a conflict between the terms of this document and the terms of the Agreement, the terms of the Agreement will apply.

#### Security Standards.

The ISP is designed to: (a) protect the confidentiality, integrity, and availability of information and data, including personal data, that is provided or made available to BugSplat under the Agreement (“Customer Data”) against any anticipated or actual threats or hazards; unauthorized or unlawful access, use, disclosure, alteration, or destruction; accidental loss or destruction or damage; and (b) safeguard the Customer Data as required by any local, state or federal regulations applicable to any Service provided by BugSplat under the Agreement. The ISP contains administrative, technical, and physical safeguards appropriate to: (a) the size, scope and type of BugSplat’s business and the Service it provides; (b) the type of information that BugSplat stores; and (c) the need for security and confidentiality of such information.

#### Elements of the ISP

**Security Policies and Procedures**

* BugSplat will maintain and implement security policies and procedures that are reasonably designed to cause all employees, Infrastructure Operator, and any subcontractors to process Customer Data in accordance with the Information Security Program. “Infrastructure Operator” means the vendor who hosts BugSplat’s physical servers. Amazon Web Services (AWS) is the current Infrastructure Operator.
* BugSplat will implement disciplinary measures against employees and contractors who fail to abide by its security policies and procedures

**Intrusion Prevention**

* BugSplat will use commercially reasonable efforts ensure that its security infrastructure is consistent with industry standards for firewalls, intrusion prevention, and intrusion detection.
* BugSplat development workstations will include endpoint protection software which is consistent with industry standards.

**Security Awareness Training**

* BugSplat will maintain up-to-date security awareness training for employees and contractors with access to Customer Data consistent with applicable law.
* Security awareness training includes:
  * The handling and securing of Customer Data
  * Response plans for potential security events
  * Details about the company’s enforcement of security policies and procedures

**Physical Environment, Access Control and Monitoring**

* Infrastructure Operator establishes physical controls for access to network and servers that access Customer Data.
* Infrastructure Operator establishes camera monitoring at hosting environment entrance and exit points.
* Infrastructure Operator has implemented and maintains appropriate temperature and humidity controls and monitoring for the server environment.

**Logical Access Controls**

* BugSplat has established controls designed to prevent network access to Customer Data without proper authentication
* BugSplat ensures that authentication includes account passwords that are unique to each employee or contractor, and two-factor or multi-factor authentication or other mechanism appropriate to protect against brute force account attacks.
* BugSplat will ensure that its employee and contractor accounts provide access to Customer Data to only those employees who require access to provide services to Customer.
* BugSplat will ensure that all access to Customer Data is logged by BugSplat and that a process is in place for monitoring these logs and notifying BugSplat of unusual activity.
* At a minimum, BugSplat will review account access and activity on a quarterly basis.
* BugSplat has an internal review mechanism for any change which may affect authentication, authorization, or auditing mechanisms.
* BugSplat will immediately terminate an employee’s access to Customer Data when such employee is terminated or contractor service is suspended or discontinued.

**Disaster Recovery**

* BugSplat maintains remote backups of production servers on an appropriate schedule.
* BugSplat tests data recovery from backups at least quarterly.
* BugSplat maintains a formal disaster recovery plan that supports any documented service level agreement.
* BugSplat provides backup and recovery services for all Customer Data.

**Business Continuity**

* BugSplat and Infrastructure Operator maintain business continuity and incident response plans to minimize the impact of unplanned events, including cyber security, physical, or natural disaster.
* BugSplat incident response plans support the goal of resuming service within 48 hours of an incident that disables any service.
* BugSplat’s incident response plans include providing Customer with notification and details about the cause and remediation of any incident.

**Storage and Transmission Security**

* Customer Data is logically segregated from any third-party data.
* Transport Layer Security with a key strength of at least 256 bits and industry standard ciphers are used for movement of Customer Data.
* Customer Data is encrypted at rest with a key strength of at least 256 bits using industry standard ciphers.
* BugSplat uses industry standard measures to protect Customer Data by strong access controls.

**Internal Audits**

* BugSplat will conduct regular internal security audits.
* BugSplat will contract with a third party to do external security assessment and penetration tests, tests are performed on at least an annual basis.

**Secure Disposal**

* BugSplat will securely destroy, or at Customer’s request, return through a secure method, any Customer Data that is no longer needed to fulfill obligations to Customer, or on termination or expiration of the Agreement with Customer

**Risk Identification**

* BugSplat will periodically review internal and external threats to the service and use industry standard methods to confirm that existing controls, policies, and procedures provide sufficient mitigation.

**Third-Party Suppliers**

* BugSplat will conduct a risk assessment on the security practices of any of its third-party contractors or vendors prior to providing access to Customer Data. Any BugSplat third-party supplier with access to Customer Data must adhere to terms substantially similar to those in the BugSplat ISP.
* BugSplat will verify that its risk assessment is sufficient to satisfy compliance with this ISP.
* The data sub-processors used by BugSplat are:
  * Amazon Web Services (<https://aws.amazon.com/>)
  * Loggly, a service of SolarWinds Worldwide (<https://www.loggly.com/>)
  * Intercom (<https://www.intercom.com/>)

**Change and Configuration Management**

* BugSplat policies and procedures ensure at least one additional engineer reviews and signs off on any changes to production systems, applications, or databases that may have an impact on security or service availability.
* BugSplat has processes that support identifying and applying necessary security patches from all software, libraries, or hardware firmware in use.

**Change of Compliance**

* BugSplat will notify Customer within thirty days if it is no longer possible to satisfy the security policies and procedures outlined in this document. At its option, Customer may terminate services upon such notification and receive a pro-rata refund of any fees already paid for the period following such termination.


# BugSplat Security Program Inquirys

BugSplat is committed to maintaining the highest standards of security for our products and services. To achieve this, we partner with SecureFrame, a leader in security compliance, to implement a robust security framework that aligns with industry best practices.

**Interested in Our Security Details?**

For those keen to delve deeper into the specifics of our security measures, including the BugSplat SOC 2 program, findings from our SOC-2 audit, or to request additional supporting documents, we've streamlined the process for your convenience.

**How to Request Information:**

* **Email Contact:** Simply reach out to us at **<sales@bugsplat.com>**. Whether you're a current customer or just exploring, we welcome your interest and are here to provide the information you need.

**Confidentiality Assurance:**

We understand the importance of confidentiality in security matters. Therefore, access to detailed information about BugSplat's security program, including audit results and certifications, is provided under a Non-Disclosure Agreement (NDA). This ensures that sensitive information remains protected while allowing us to share our commitment to security with you.

**We're Here to Help:**

At BugSplat, your security concerns are our top priority. We're dedicated to providing transparent and detailed information to support your decision-making process. Should you have any questions or require further assistance, please don't hesitate to get in touch.

Thank you for your interest in BugSplat's security initiatives. We look forward to partnering with you to meet your security needs.


# SOC 2

BugSplat has implemented processes to support SOC 2 based on the Trust Services Criteria relevant to Security (applicable Trust Services Criteria) outlined in TSP section 100, 2017 Trust Services Criteria for Security, Availability, Processing Integrity, Confidentiality, and Privacy (AICPA, Trust Services Criteria).

BugSplat has created a Systems Description (or Section 3), conducted an annual risk assessment, identified applicable risk mitigation strategies, completed and reviewed information security policies and procedures, and prepared an internal controls matrix.

BugSplat has partnered with [SecureFrame](https://secureframe.com/) to implement our security framework. Additional supporting documents regarding the BugSplat SOC 2 program, results of BugSplat's SOC-2 audit, and other information are [available to customers and curious parties under NDA](/guides/production/security-privacy-and-compliance/bugsplat-security-program-inquirys).

Please contact <support@bugsplat.com> for follow-up questions.


# GDPR & UK GDPR Compliance

On May 25, 2018, the EU’s General Data Protection Regulation (GDPR) went into effect, establishing new global privacy rights for individuals in the European Union. Since then, the United Kingdom has adopted a parallel privacy framework known as **UK GDPR** following its departure from the EU.

At BugSplat, we take your data privacy seriously. We’ve worked hard to meet and exceed the obligations set out in both the **EU GDPR** and the **UK GDPR**.

***

### BugSplat as a Data Processor

BugSplat operates as a **processor** on behalf of our customers, who act as controllers of their end-user data. We only process data as instructed by our customers and in accordance with applicable data protection laws.

***

### What We’ve Done to Comply with the GDPR & UK GDPR

**Company-Level Actions**

* Consulted with external counsel to understand how both EU and UK GDPR affect BugSplat and our users
* Reviewed and updated our **Data Processing Agreement (DPA)** to reflect:
  * The latest **EU Standard Contractual Clauses (SCCs)**
  * The **UK Addendum** for data transfers from the United Kingdom
* Audited all vendors and subprocessors and signed DPAs where required

**Product-Level Changes**

* Give customers the option to **automatically obfuscate** personally identifiable information (PII) such as usernames, email addresses, and IP addresses
* Added a **consent checkbox** to crash dialog forms for end-users to voluntarily provide crash data
* Provide tooling to allow customers to **permanently delete** specific users, email addresses, or IPs from all crash reports

***

#### Our Data Processing Agreement (DPA)

Our DPA reflects the requirements under both the **EU GDPR** and **UK GDPR**, including SCCs and the UK Addendum for international data transfers.

If you'd like to review or sign our DPA, please contact us at <support@bugsplat.com>.

**Additional Information**

For more info about BugSplat and GDPR please see our [Security](/guides/production/security-privacy-and-compliance/security-program) page and our [Privacy Policy](/guides/production/security-privacy-and-compliance/privacy-policy).


# Avoid Collecting Personally Identifiable Information (PII)

For all plans except Free (Team plan or higher is required to upgrade), BugSplat account holders have the option to prevent the collection of personally identifiable information from your users.

**Steps to mask and obfuscate personally identifiable information:**

1. Sign in to your account
2. Navigate to the '[Settings-Database-Privacy](https://app.bugsplat.com/v2/database/privacy)' page.
3. Enable all the checkboxes under ‘Obfuscate Personally Identifiable Information’

Once these option boxes are checked, new crash reports will not contain any personally identifiable information.


# Crash Expiry

BugSplat stores crash data for different time frames for different [plans](https://www.bugsplat.com/pricing/). See the [plans](https://www.bugsplat.com/pricing/) page to learn more.

To use this feature, users should navigate to the [Settings](https://app.bugsplat.com/v2/database/privacy) page and set the limit for crash retention data using the Crash Expiry tool.

![](https://976110677-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LBMgmIcgkIXSUfnXDSv%2F-MlRjMJYDonKlzNWBv8H%2F-MlRknuvgywS8BjZjV4g%2FScreen%20Shot%202021-10-07%20at%203.57.46%20PM.png?alt=media\&token=07fd91db-1939-4fe9-b88e-570c6ea19075)


# Terms

Last Updated: 10th August, 2022

The following BugSplat Terms of Use (“Terms” or “Agreement”) constitutes a legal agreement between you (“you,” “your,” or “Developer(s)”, all used interchangeably except that when “Developer(s)” is used herein, it applies only to “Developer(s)” (as “Developer(s)” is defined in Section 1 below)) and, if applicable the Entity (as defined below) on whose behalf you are accessing and/or using the Services (as defined below) and BugSplat LLC (“BugSplat”). Your use of the BugSplat websites and the BugSplat crash reporting solution (collectively, the “Services,” as more fully described below) is subject to these Terms, so you should take the time to fully understand how these Terms govern your relationship with BugSplat and your use of the Services. If you have questions regarding the Terms, please contact BugSplat at <support@bugsplat.com>.

YOUR RIGHT TO ACCESS AND USE THE SERVICES IS EXPRESSLY CONDITIONED ON ACCEPTANCE OF THESE TERMS. BY ACCESSING OR USING THE SERVICES, YOU AGREE TO BE BOUND BY THESE TERMS. IF YOU ARE ACCESSING OR USING THE SERVICES ON BEHALF OF YOUR EMPLOYER OR ANOTHER ENTITY (“ENTITY”), YOU AGREE TO PROVIDE BUGSPLAT WITH THE NAME OF THE ENTITY AND OBTAIN BUGSPLAT’S APPROVAL TO USE THE SOFTWARE ON YOUR BEHALF AND BEHALF OF THE ENTITY AND YOU AGREE TO REMAIN RESPONSIBLE AND LIABLE FOR YOUR AND SUCH ENTITY’S COMPLIANCE WITH THIS AGREEMENT. FURTHER, YOU REPRESENT AND WARRANT TO BUGSPLAT THAT (I) YOU ARE THE AUTHORIZED AGENT OF THE APPLICABLE ENTITY AND HAVE THE LEGAL AUTHORITY TO ENTER INTO THE AGREEMENT ON BEHALF OF YOURSELF AND THE ENTITY, AND (II) YOU HAVE OBTAINED, ON BEHALF OF YOURSELF AND THE ENTITY (IF APPLICABLE), ALL NECESSARY RIGHTS, WAIVERS, CONSENTS AND PERMISSIONS NECESSARY TO COLLECT, USE, STORE, AND SHARE USER INFORMATION IN CONNECTION WITH THE SOFTWARE.

**SECTION 1. OVERVIEW OF THE SERVICES**

The Services provide a crash reporting solution for developers of computer applications (“Developer(s)”). The Services provide information to Developers about the functioning of applications they own or manage, including, but not limited to, information about how and under what circumstances an application crashed.

**SECTION 2. SPECIFIC TERMS FOR DEVELOPERS**

**Service and Access Credentials.** Developer will provide reasonable cooperation, assistance, information and access to BugSplat as may be necessary to initiate Developer’s use of the Services. During the Term, and subject to Developer’s compliance with all terms and conditions of these Terms, BugSplat will provide Developer with access to the Services. As part of the implementation process, Developer will identify user names and passwords that will be used to set up Developer’s account. Developer will be responsible and liable for the acts or omissions of any person who accesses the Services using passwords or access procedures provided to Developer. BugSplat reserves the right to refuse registration of, or to suspend or cancel, login IDs used by Developer to access the Services if Developer violates the terms and conditions set forth in these Terms.

**License to Developer.** During the Term, and subject to all terms and conditions of these Terms, BugSplat grants Developer a nonexclusive, nontransferable right and license (without right to sublicense) to (a) access and use the Services (including the Background Materials (as defined below) necessary to use the Services), solely for Developer’s internal business purposes and (b) download, install and use a reasonable number of copies of the BugSplat software development kit (the “SDK”) and any tools provided as part of the SDK solely in connection with Developer’s authorized use of the Services. Developer may use the Services and the Software for the sole purposes of (i) enabling users of their applications, (ii) obtaining information regarding the installation, use of and engagement with, and the functionality of Developer’s applications, including reporting on errors or bugs (collectively, “Performance Data”), (iii) improving the functionality of Developer’s applications and related products and services, and (iv) communicating with users about Developer’s applications. Developer’s access and use of the Services shall also comply with all other conditions set forth in all documentation, instructions, end user guides and other documents regarding the Services and Software that is provided or made available by BugSplat to Developer in electronic or other form (collectively, “Documentation”). Additionally, during the Term and thereafter in perpetuity, and subject to all terms and conditions of these Terms, BugSplat grants Developer a nonexclusive, nontransferable right and license (without right to sublicense) to distribute to Developer’s authorized end-users BugSplat’s binary files included as part of the SDK for the sole purpose of use of the Services.

**Restrictions.** Except as expressly authorized under immediately preceding section (License to Developer), Developer shall not directly or indirectly (a) use the Services or any of BugSplat’s Confidential Information (as defined below) to create any service, software or documentation that is substantially the same or has similar functionality as the Services, (b) disassemble, decompile, reverse engineer or use any other means to attempt to discover any source code, algorithms or trade secrets underlying the Services or Background Materials (defined below), except and only to the extent these restrictions are expressly prohibited by applicable statutory law, (c) encumber, sublicense, transfer, distribute, rent, lease, time­share or use any BugSplat Properties (as defined below) in any service bureau arrangement or otherwise for the benefit of any third party, (d) adapt, combine, create derivative works of or otherwise modify any BugSplat Properties, or (e) use or allow the transmission, transfer, export, re-­export or other transfer of any product, technology or information it obtains or learns in connection with Developer’s use of the Services in violation of any export control or other laws and regulations of the United States or any other relevant jurisdiction.

**Excluded Developers.** The Service may not be used by any party engaged in the design, development, programming or distribution of any Malware. “Malware” shall mean software designed to infiltrate or damage a computer system without the owner's informed consent. Software is considered Malware based on the perceived intent of the creator rather than any particular features. Malware includes computer viruses, worms, Trojan horses, most rootkits, spyware, dishonest adware, crime ware and other malicious and unwanted software. Developer represents and warrants to BugSplat that Developer is not engaged in design, development, programming or distribution of any Malware. In the event BugSplat determines Developer has violated this provision, BugSplat, without notice or right to cure, may terminate Developer’s use of the Service, without limitation of BugSplat’s other rights or remedies with respect to such violation.

**Developer Data.** Developer hereby grants BugSplat a nonexclusive, license­ fee free and royalty­ free right and license to access, copy, distribute, process and use all information, data and other content provided by Developer (“Developer Data”) solely for the purpose of providing the Services and as otherwise expressly permitted in these Terms. Developer agrees that (a) the Services depends on the availability of the Developer Data, and (b) BugSplat will not assume any responsibility or liability for, or undertake to verify, the legality, accuracy or completeness of the Developer Data. BugSplat shall have no obligation to store any Developer Data or Results (as defined below).

**User Data.** The Services allow the Developer to collect information relating to performance of Developer’s applications. Developer may turn on features of the Services to allow collection of other information via the Services, including some personally identifiable information (e.g., a user’s e­mail address), which allows Developers to communicate with users about the functionality of their applications. Developer represents and warrants that Developer is collecting information via the Services solely to obtain information about the user engagement with and functionality of Developer’s applications, and to communicate with users about such engagement and functionality. Subject to and without limiting the foregoing, Developer agrees it will not enable collection or use of credit card information, Social Security numbers, driver’s license numbers, dates of birth or physical addresses via the Services. Developer further agrees it will not enable the collection or use of personally identifiable information by way of applications directed at children under 13 via the Services or provide any personally identifiable information collected via such applications to BugSplat. At all times during the term of this Agreement, developer shall at all times comply with all applicable laws, rules and regulations relating to data collection, privacy and security, including, without limitation, the Children’s Online Privacy Protection Act (“COPPA”) and shall indemnify and hold BugSplat harmless with respect to any violations thereof.

**Developer Systems.** Developer is responsible for providing (a) all equipment, subscriptions and credentials necessary for BugSplat to receive the Developer Data, and (b) all modems, servers, devices, storage, software (other than Software), databases, network and communications equipment and ancillary services needed to connect to, access or otherwise use the Services at its facility (collectively, “Developer Systems”). Developer shall ensure that Developer Systems are compatible with the Services and comply with all configurations and specifications described in the Documentation.

**Limitations.** BugSplat will not be responsible or liable for any failures in the Services or any other problems which are related to (a) the Developer Data or Developer Systems, or (b) any satellite, telecommunications, network or other equipment or service outside of BugSplat’s facilities or control.

**Confidentiality.** “Confidential Information” means, with respect to BugSplat, all financial, business or technical information disclosed by or for BugSplat in relation to these Terms and/or the Services that is of a nature that should reasonably be considered to be confidential or proprietary. Except for the specific rights granted by these Terms, neither party receiving Confidential Information hereunder (“Recipient”) may use, copy or disclose any Confidential Information of the party disclosing Confidential Information hereunder (“Discloser”) without Discloser’s prior written consent, and shall use no less than reasonable care to safeguard Discloser’s Confidential Information, including ensuring that Recipient’s employees, contractors and agents (“Representatives”) with access to Discloser’s Confidential Information have a need to know such Confidential Information for the purposes of these Terms and are bound by confidentiality obligations no less protective of the parties as those set forth herein. The foregoing obligations shall not apply to any Confidential Information that Recipient can demonstrate is (a) already known by it without restriction, (b) rightfully furnished to it without restriction by a third party not in breach of any obligation to Discloser, (c) generally available to the public without breach of these Terms or (d) independently developed by it without reference to or use of any of Discloser’s Confidential Information and without any violation of any obligation of these Terms. Each party shall be responsible for any breach of confidentiality by its Representatives, as applicable. Promptly upon Discloser’s request at any time, Recipient shall return all of Discloser’s tangible Confidential Information, permanently erase all Confidential Information from any storage media and destroy all information, records, copies, summaries, analyses and materials developed therefrom. Nothing herein shall prevent a party from disclosing any of the other’s Confidential Information as necessary pursuant to any court order or any legal, regulatory, law enforcement or similar requirement or investigation; provided, however, prior to any such disclosure, Recipient shall use reasonable efforts to (a) promptly notify Discloser in writing of such requirement to disclose, and (b) cooperate with Discloser in protecting against or minimizing any such disclosure and/or obtaining a protective order.

**Proprietary Rights.** As used in these Terms: “Background Materials” means all ideas, concepts, inventions, systems, platforms, software (including all Software), interfaces, tools, utilities, templates, forms, Report Formats, techniques, methods, processes, algorithms, know ­how, trade secrets and other technologies and information that are used by BugSplat in providing the Services and Results (including any correction, improvement, derivative work, extension or other modification to the Services made, created, conceived or developed by or for BugSplat, including at Developer’s request or as a result of feedback provided by Developer to BugSplat); “Reports” means the reports, charts, graphs and other presentation in which the Results are presented to Developer; “Report Formats” means the formatting, look and feel of the Reports; and “Results” means the work products resulting from the Services that are delivered to Developer by BugSplat through the Services, and which are based on the Developer Data. For the sake of clarity, Results shall expressly exclude all Background Materials. Developer shall own all right, title and interest (including all intellectual property and other proprietary rights) in and to feedback, suggestions, ideas or other materials and information provided (“User Feedback”), the Results and Developer Data. Developer acknowledges and agrees that the Results will be presented to it in a Report, the Report Format of which is Confidential Information and proprietary to BugSplat. Developer may make a reasonable number of copies of the Reports only for its internal purposes in using the Results. Developer hereby grants to BugSplat a license ­fee free, royalty ­free, fully paid up, non­exclusive, perpetual and irrevocable, worldwide right and license to (a) use the Developer Data, Performance Data and User Feedback, solely for purposes of providing the Services to Developer, (b) use the Developer Data, Performance Data and User Feedback to create aggregate measures of Services usage, engagement, and performance, and (c) use the Results and aggregated Developer Data, Performance Data and User Feedback to improve the Services generally and for its other business purposes.

**General Learning; Aggregate Data.** BugSplat reserves the right to disclose aggregate information of Services usage, engagement, and performance, and to reuse all general knowledge, experience, know ­how, works and technologies (including ideas, concepts, processes and techniques) related to the Results or acquired during provision of the Services (including without limitation, that which it could have acquired performing the same or similar services for another customer).

**Reservation of Rights.** Except for the limited rights and licenses expressly granted hereunder, no other license is granted, no other use is permitted and BugSplat (and its licensors) shall retain all right, title and interest (including all intellectual property and proprietary rights embodied therein) in and to the Services, Documentation, Background Materials, aggregate data, and analyses (collectively, “BugSplat Properties”).

**Warranties.** Developer represents and warrants that it owns all right, title and interest, or possesses sufficient license rights, in and to the Developer Data as may be necessary to grant the rights and licenses, and provide the representations, and for BugSplat to provide the Services set forth herein. Developer bears all responsibility and liability for the legality, accuracy and completeness of the Developer Data and BugSplat’s access, possession, distribution and use thereof, as permitted herein.

**SECTION 3. GENERAL TERMS**

**Disclaimers.** THE BUGSPLAT SERVICES, BUGSPLAT PROPERTIES AND RESULTS ARE PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND. WITHOUT LIMITING THE FOREGOING, BUGSPLAT AND ITS AFFILIATES, RELATED COMPANIES, OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, REPRESENTATIVES, PARTNERS AND LICENSORS (COLLECTIVELY, THE “BUGSPLAT ENTITIES”) MAKES NO WARRANTY (I) THAT THE SERVICES OR RESULTS WILL MEET YOUR REQUIREMENTS OR BE UNINTERRUPTED, ERROR­FREE OR BUG­FREE, (II) REGARDING THE RELIABILITY, TIMELINESS, OR PERFORMANCE OF THE SERVICES, OR (III) THAT ANY ERRORS IN THE SERVICES CAN OR WILL BE CORRECTED. THE BUGSPLAT ENTITIES HEREBY DISCLAIM (FOR ITSELF AND ITS SUPPLIERS) ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, ORAL OR WRITTEN, INCLUDING WITHOUT LIMITATION, ALL IMPLIED WARRANTIES OF NON­INFRINGEMENT, MERCHANTABILITY, TITLE OR FITNESS FOR ANY PARTICULAR PURPOSE AND ALL WARRANTIES ARISING FROM ANY COURSE OF DEALING, COURSE OF PERFORMANCE OR USAGE OF TRADE.

**Indemnification.** You will indemnify, defend, and hold harmless the BugSplat Entities from all claims, whether actual or alleged (collectively, “Claims”), that arise out of or in connection with (a) your use of the Services, (b) your actual or alleged infringement or misappropriation of the rights of any third party, including, without limitation, any intellectual property rights, privacy rights or publicity rights; and (c) your breach of any representations and warranties set forth in the Agreement. You are solely responsible for defending any Claim against the BugSplat Entities, subject to such BugSplat Entities’ right to participate with counsel of its own choosing, and for payment of all judgments, settlements, damages, losses, liabilities, costs, and expenses, including reasonable attorneys’ fees, resulting from all Claims against the BugSplat Entities, provided that you will not agree to any settlement related to any Claims without the BugSplat Entities’ prior express written consent regardless of whether or not such settlement releases the BugSplat Entities from any obligation or liability.

**Limitation of Liability.** IN NO EVENT SHALL THE BUGSPLAT ENTITIES BE LIABLE CONCERNING THE SUBJECT MATTER OF THESE TERMS, REGARDLESS OF THE FORM OF ANY CLAIM OR ACTION (WHETHER IN CONTRACT, NEGLIGENCE, STRICT LIABILITY OR OTHERWISE), FOR ANY (A) LOSS OR INACCURACY OF DATA, LOSS OR INTERRUPTION OF USE, OR COST OF PROCURING SUBSTITUTE TECHNOLOGY, GOODS OR SERVICES, (B) INDIRECT, PUNITIVE, INCIDENTAL, RELIANCE, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES INCLUDING, BUT NOT LIMITED TO, LOSS OF BUSINESS, REVENUES, PROFITS AND GOODWILL, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR (C) DAMAGES, IN THE AGGREGATE, IN EXCESS OF THE AMOUNT OF FEES ACTUALLY PAID BY YOU TO BUGSPLAT IN THE IMMEDIATELY PRECEDING 12-MONTH PERIOD. THESE LIMITATIONS ARE INDEPENDENT FROM ALL OTHER PROVISIONS OF THESE TERMS AND SHALL APPLY NOTWITHSTANDING THE FAILURE OF ANY REMEDY PROVIDED HEREIN.

Some states do not allow the exclusion or limitation of incidental or consequential damages, so the above limitation or exclusion may not apply to you.

**Term and Termination**

**Term; Termination** The term of this Agreement (the “Term”) shall initially be the free trial period described below under “Pricing”. Following the initial free trial period, the Term shall be such period of time as specified by your BugSplat invoice (if any) or the period covered by your most recent credit card payment. BugSplat may terminate your use of the Services for any reason or no reason during the initial free trial period which termination shall be effective immediately upon BugSplat’s written notice to you of such termination; thereafter, BugSplat may terminate your use of the Services without cause by providing written notice of such termination not later than thirty (30) days prior to the end of the then current Term, which termination shall be effective upon expiration of the then current Term. This Agreement and your right to use the Services may be terminated by either party due to a material breach of this Agreement by the other party which has not been cured within ten (10) days after express written notice thereof from the non-defaulting party, including non-payment. BugSplat’s right to terminate for non-payment is in addition and without prejudice to BugSplat’s right to the outstanding amounts owed to BugSplat.

**Effects of Termination.** Upon any expiration or termination of the Terms, all rights, obligations and licenses of the parties shall cease, except that (a) all obligations that accrued prior to the effective date of termination and all remedies for breach of these Terms shall survive, (b) you must discontinue accessing and using the Services and delete all Software, BugSplat Properties, and BugSplat Material, and (c) the provisions in Section 2 titled Restrictions, Developer Feedback, Confidentiality, Proprietary Rights, General Learning; Aggregate Data, Warranties and the provisions in this Section 3 shall survive. BugSplat has no obligation to store, delete or return any User Feedback, Performance Data, Developer Data or Results.

**Pricing**

**Free Trial.** All new accounts are free for the first 14 days of use. This is BugSplat’s free trial period. BugSplat has a free tier for low volume accounts, which are not charged a subscription fee. However, crash reports may be rejected when the crash count exceeds the low volume subscription limit. After the free trial period, you will be asked to pay for the BugSplat services or your account will be terminated. Monthly subscriptions are available through our website. For additional information on pricing for your application, or for annual invoice subscriptions, please contact us at <sales@bugsplat.com>.

**Miscellaneous**

**Entire Agreement.** These Terms constitute the entire agreement, and supersede all prior negotiations, understandings or agreements (oral or written), between the parties about the subject matter of these Terms.

**Waivers, Consents and Amendments.** No waiver, consent or modification of these Terms shall bind the BugSplat Entities unless in writing and signed by BugSplat. We may amend these Terms from time to time. If we make a change to these Terms that, in our sole discretion, is material, we will notify you by posting notice of the change on BugSplat.com and in these Terms. Any such amended Terms shall become effective with respect to you and your use of the Services upon the next renewal of your Term. If you do not agree to the modified terms, you shall notify BugSplat in writing not later than thirty (30) days prior to the end of the then current Term, and upon the expiration of the then current Term your right to access and use the Services shall immediately terminate and the BugSplat Entities shall have no further responsibility or liability to you. The failure of either party to enforce its rights under these Terms at any time for any period will not be construed as a waiver of such rights.

**Severability.** If any provision of these Terms is determined to be illegal or unenforceable, that provision will be limited or eliminated to the minimum extent necessary so that these Terms will otherwise remain in full force and effect and enforceable.

**Governing Law.** These Terms shall be governed by and construed in accordance with the laws of the State of New Hampshire. Neither the United Nations Convention on Contracts for the International Sale of Goods nor any implementation of the Uniform Computer Information Transactions Act in any jurisdiction shall apply to these Terms. Except that the BugSplat Entities may seek equitable or similar relief from any court of competent jurisdiction to prevent or restrain any breach or threatened breach of this Agreement by you, exclusive jurisdiction and venue for actions related to these Terms or your use of the Services will be the state and federal courts located in Merrimack County New Hampshire, United States, and both parties consent to the jurisdiction of such courts with respect to any such actions. In any action or proceeding to enforce or interpret these Terms, the prevailing party will be entitled to recover from the other party its costs and expenses (including reasonable attorneys’ fees) incurred in connection with such action or proceeding and enforcing any judgment or order obtained.

**Force Majeure.** In the event that either party is prevented from performing, or is unable to perform, any of its obligations under these Terms (except payment obligations) due to any cause beyond its reasonable control, the affected party shall give written notice thereof to the other party and its performance shall be extended for the period of delay or inability to perform due to such occurrence.

**Notices.** Any notice or communication hereunder shall be in writing and either personally delivered or sent via confirmed facsimile, confirmed electronic transmission, recognized express delivery courier or certified or registered mail, prepaid and return receipt requested, addressed to the other party, which, in the case of Developer, shall be the address provided to BugSplat upon signing up for the Services, and, in the case of BugSplat, shall be BugSplat 1023 Walnut St, Boulder, CO 80302 or at such other address for either party as is designated in a subsequent notice. All notices shall be in English, and deemed to have been received when they are hand delivered, or five business days of their mailing, or upon confirmed electronic transmission.

**Assignment.** These Terms and the rights and obligations hereunder may not be assigned, transferred or delegated, in whole or in part, by you without BugSplat’s prior written consent. Any assignment or transfer in violation of the foregoing shall automatically be null and void. These Terms shall be binding upon, and inure to the benefit of, the successors, representatives and permitted assigns of the parties hereto.

**Independent Contractors.** The parties shall be independent contractors under these Terms, and nothing herein will constitute either party as the employer, employee, agent or representative of the other party, or both parties as joint venturers or partners for any purpose.


# Privacy Policy

**Updated October 10th, 2022**

BugSplat, LLC (“BugSplat”) offers a crash reporting service that provides developers with information about the stability of their applications (the “Services”). This Privacy Policy describes how BugSplat collects, uses and shares information about application developers that are customers of BugSplat (“Developers”) and the end-users of their applications (“End Users”) that use our Services. The policy also explains how BugSplat collects and uses information when individuals visit our websites. We encourage you to read this Privacy Policy in order to learn more about how we safeguard your privacy. Below are our Terms of Service, which outline a lot of legal goodies, but the bottom line is it’s our aim to always take care of both you, as a customer, or as a seller on our platform.

Customers using BugSplat technology in an application created by Microsoft or one of their affiliates are also covered by the [Microsoft Security and Privacy](https://privacy.microsoft.com/en-us/privacystatement) policy.

### ***SCOPE OF THIS PRIVACY POLICY***

Section 1 of this Privacy Policy covers BugSplat’s treatment of information that may be collected from End Users. Section 2 of this Privacy Policy covers BugSplat’s treatment of information collected from Developers using the Services. Section 3 contains information about our privacy practices that applies to both Developers and End Users, including information collected when an individual uses the BugSplat websites.

The policy specifically addresses the following areas:

* What information is collected by the BugSplat websites and Services;
* How BugSplat uses this information;
* With whom BugSplat may share this information;
* What choices are available to you with respect to the collection and use of information collected by BugSplat;
* What types of security procedures are in place to protect against the loss, misuse or alteration of information under our control; and
* How you can correct any inaccuracies in the information we hold about you.

This policy does not apply to the practices of companies not owned or controlled by BugSplat (including Developers) or to people whom BugSplat does not employ or manage.

#### **SECTION 1: END USER INFORMATION**

This Section provides information on the collection and use of information from End Users.

**What information does BugSplat collect from End Users?**

The Services collect certain information that does not personally identify End Users who access or use applications that use the Services. This information includes, but is not limited to, computer state information, information relating to how an application functions, and the type of computer hardware and operating system being used.

Developers may also use certain features of the Services that will allow BugSplat to collect some End Users’ personally identifiable information and feedback that End Users voluntarily provide. For example, end-users may provide BugSplat with their email addresses so that the Developers can contact them. BugSplat captures all of this information on Developers’ behalf so that they can understand and improve their applications and communicate with users about their experience with the applications. BugSplat requires Developers to use BugSplat to collect information solely for these purposes, and to observe all applicable laws and regulations.

**How does BugSplat use the information that it collects?**

The information BugSplat collects about End Users and their activities is the property of the Developer, not of BugSplat. The information collected by the Services from End Users is used to provide Developers with insight into the functionality of and engagement with their applications, including any problems that occur. Our algorithms process and analyze the data separately for each Developer, so if you are an End User of multiple Developers that are BugSplat’s customers your information is not shared across Developers. However, BugSplat does aggregate information across Developers in a non-personally identifiable way. Such aggregate and anonymous information is used by BugSplat to (i) improve the Services, (ii) create analysis of trends or behaviors and (iii) other similar uses, but always in an aggregate and anonymous way.

**Will BugSplat share information about me with anyone else?**

Except as provided below in Section 3, we never divulge End User data to anyone other than the Developer on whose behalf we are collecting and analyzing its End User data.

**Is there a way that End Users can opt out of collection of information by BugSplat?**

Collection of information is at the discretion of each Developer, so please consult with the Developer whose application you are using as to how to opt out of collection of information by BugSplat.

#### **SECTION 2: DEVELOPER INFORMATION**

This Section provides information on the collection and use of information from Developers.

**What information does BugSplat collect from Developers?**

BugSplat collects the following information from Developers:

Usage Data:

BugSplat collects information relating to the usage of the Services from Developers in order to better provide the service to Developers, to improve the performance of the Services generally, and to bill them appropriately for use of the Service.

Account Information:

When you create an account with BugSplat, you will provide us with certain personally identifiable information, such as but not limited to your name, contact information, company name and account user name and password. We recognize that this information is very important to you and we will never divulge any of your personally identifiable information to anyone without your permission except as needed to provide Services to you and as described in Section 3 below.

**How does BugSplat use the information collected from Developers?**

Our primary goal in collecting information from you is to provide you with a great experience while using our websites and to allow us to provide the Services to you. We use personal information solely for the purpose of contacting you with respect to your use of the Services, providing the Services to you and generally facilitating your use of the Services, or informing you about features of our Services that may be of interest to you.

In order to customize the online user experience, improve the Services generally, and provide Developers with useful statistics and analysis regarding use of the Services, we may use certain aggregate, anonymous information, including, without limitation, Services usage information, for such purpose, but never in a manner in which the Developer or any End User identity is reasonably ascertainable.

**How can Developers change or delete information?**

You may review, update, correct or delete the personally identifiable information in your BugSplat account where it is inaccurate by contacting us. If you would like us to delete your BugSplat account in our system, please contact us at <support@bugsplat.com> with a request that we delete your personally identifiable information from our database. We will use commercially reasonable efforts to honor your request. If you request that your personally identifiable information be deleted from our records, there may be a brief delay in our processing that request, while we verify that the request is valid and originates from you as opposed to an unauthorized third party. If you request that your information be deleted, we reserve the right to terminate and/or limit your access to the Services, as we may need such information to provide the Services to you. We may retain an archived copy of your records as required by law or for legitimate business purposes. If your personally identifiable information changes, you may contact us to correct, update or delete and deactivate our record of your personally identifiable information.

#### **SECTION 3: GENERAL INFORMATION**

This Section applies to information collected from End Users and Developers, as well as visitors to the BugSplat website.

What precautions does BugSplat take to ensure the security of information collected?

BugSplat has implemented reasonable security measures in order to protect both personal and nonpersonal information from loss, misuse and unauthorized access, disclosure, alteration or destruction.

Under what circumstances will BugSplat share my information with third parties?

Except for the provision of End User information relating to a specific Developer’s application to that Developer as described above, BugSplat will never give your information to, or share your information with, any third party except as provided below (which disclosure shall always be in accordance with applicable law). BugSplat will share information about you only as follows:

* We may share information with service providers we engage to perform functions and provide services to us in the United States and abroad, subject to confidentiality obligations consistent with this Privacy Policy, and on the condition that the third parties use your information only on our behalf and pursuant to our instructions.
* We have your consent to share the information.
* Notwithstanding anything to the contrary in this Privacy Policy, we may disclose information if we believe that it is reasonably necessary to comply with a law, regulation or legal request; to protect the safety of any person; to address fraud, security or technical issues; or to protect BugSplat’s rights or property.
* In the event that BugSplat is involved in a bankruptcy, merger, acquisition, reorganization or sale of assets, your information may be sold or transferred as part of that transaction. The promises in this Privacy Policy will apply to your information as transferred to the new entity.

**Does BugSplat collect any information from children?**

Our websites and the Services are not directed to children and BugSplat does not knowingly collect any personally identifiable information from children under 13 years of age. If you learn that BugSplat has collected any personally identifiable information from children under 13 years of age, please contact us at <support@bugsplat.com>.

**Does BugSplat collect information when I visit the BugSplat websites?**

When you visit our websites, our servers automatically record certain information in our log files. This web log information includes your IP address, browser type, operating system, the referring web page, pages visited, and cookie information (discussed further below). Like many websites, we use web log information, along with cookies and similar technologies, to operate our websites, better understand how they are used, resolve technical problems, and enhance your experience on our websites.

**Does BugSplat use cookies?**

Yes. Like many companies, BugSplat uses cookies. A cookie is a small text file stored on the customer’s hard drive for an extended period of time, which may include a unique identifier that is sent to a user’s browser from a website’s computer and stored on the user’s computer’s hard drive. The website placing the cookie on the user’s computer can then recognize the computer when the user navigates the website at a later time. We use this information to improve your experience.

Although most web browsers automatically accept cookies, your browser setting can usually be modified to decline cookies or alert you when a website is attempting to place a cookie on your computer. Consult the help manual for your browser for detailed information. If you choose to decline cookies, you may lose some of the functionality associated with the Services or the BugSplat websites.

**Does BugSplat control Developers or other third parties?**

No. Please be advised that we do not control and are not responsible for the privacy practices of any third party, including, but not limited to, Developers and any website or service that links to or from the BugSplat websites or the Services. While, as discussed above, we require that Developers maintain a privacy policy that fully and accurately discloses their data collection practices, we cannot control the actions of Developers, so please be sure to review the privacy policies of any online services that you may use.

**BugSplat and GDPR**

If you've entered into a data processing agreement (DPA) with BugSplat you have additional rights

**Can this Privacy Policy change?**

We may amend this Privacy Policy from time to time. If we make a change to this policy that, in our sole discretion, is material, we will notify you by posting notice of the change on [www.BugSplat.com](http://www.BugSplat.com) and in this Privacy Policy.

**Who can I contact if I have questions about this Privacy Policy?**

If you have any questions about our Privacy Policy or any other questions about the BugSplat websites or the Services, please contact us at <support@bugsplat.com>. We will make every effort to resolve your concerns.


# Support Responses

A custom support response is a message displayed to an end-user as a new tab in their default browser. BugSplat can be configured to display these messages automatically and their content can be based upon the type of crash submitted. The message can also be branded with your company or application logo by [following these instructions](/education/faq/add-custom-branding-to-support-response).

A custom support response allows you to send targeted information to users in the moments immediately after they experience a known crash type.

For example, do you know a particular crash is associated with a bug fixed in a newer version?

The support response can target users who are experiencing this crash and encourage them to upgrade.

The support response can also provide a default message used in the absence of a crash-type specific message.

## Creating a Crash-specific Support Response

Navigate to the desired **Key Crash** page by clicking a [stack key](/education/bugsplat-terminology#stack-key) link from any crash report or from the **Summary** page.

Once on the desired **Key Crash** page, click the **Support Response** button. This will bring you to the **Support Response** page. Here you can craft your crash-specific support response.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FOsOGih3OzjHAjsANPN49%2Fsupport-response-2023.png?alt=media&amp;token=c735b1c5-9111-4ac1-ae95-bae4981b5c5c" alt=""><figcaption></figcaption></figure>

To define the message, enter a subject in addition to the message that your users will see after they submit a crash of this type.

To style the message, use Markdown. If you don't remember Markdown off the top of your head, check out this [cheat sheet](https://www.markdownguide.org/cheat-sheet/).

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FZHjEhnVXZbmnoIRcvv52%2Fsupport-response-editor.png?alt=media&amp;token=d3afdfb9-1d3e-45eb-9325-f1f452603167" alt=""><figcaption><p>Support Response Editor</p></figcaption></figure>

Once you've defined your message, a live preview is shown in the **Preview** panel on the right side of the page. Click **Open in New Tab** at the bottom left to view the support response at its live URL.

If the message or subject is left empty, the default tech support response (if one is defined) will be shown to users submitting crash reports.

Note: The application key is set at runtime by your application and can be used to provide different messages for the same crash type. For example, the application key could be used to identify localized versions of a product and return localized versions of the support response.

For more information about how to localize your support response, please see this [doc](/education/faq/localized-support-responses-for-windows-c++-.net-and-macos).

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FeGe4irPtJscUDsDVobnN%2FEnd%20User%20Support%20Response%20Page.png?alt=media&amp;token=6893e0bd-b9f2-459c-9d13-7ebe3cabb531" alt=""><figcaption><p>End User Support Response Page</p></figcaption></figure>

## Setting the default response

The default support response is displayed if there is no [stack key](/education/bugsplat-terminology#stack-key)-specific message for a given crash report.‌

To configure the default response, click the **Edit Default Response** button found on the **Support Response** page.‌

Just like other support responses, the default response also attempts to match the application key. In cases where the application key support response isn't defined, the default application key message is displayed.

<figure><img src="https://976110677-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LBMgmIcgkIXSUfnXDSv%2Fuploads%2FaT8bGkEFDjALsKHUXUsf%2Fsupport-response-editor-small.png?alt=media&amp;token=eaf9efcd-1efe-4049-90a4-3468c11d27a9" alt=""><figcaption><p>Edit Default Response</p></figcaption></figure>




---

[Next Page](https://docs.bugsplat.com/llms-full.txt/1)

