Native

The Sentry Native SDK is intended for C and C++. However, since it builds as a dynamic library and exposes C-bindings, it can be used by any language that supports interoperability with C, such as the Foreign Function Interface (FFI).

Sentry also offers higher-level SDKs for platforms with built-in support for native crashes:

In case you would like to integrate Sentry into a third-party framework directly without using the Native SDK, see the following resources:

Integrating the SDK

The Native SDK currently supports Windows, macOS and Linux. There are three distribution to choose from:

Standalone With Breakpad With Crashpad
Custom Messages Custom Messages Custom Messages
Custom Errors Custom Errors Custom Errors
Breadcrumbs Breadcrumbs Breadcrumbs
Stack Traces* Stack Traces Stack Traces
Capture Crashes* Capture Crashes Capture Crashes
Minidumps Minidumps
Attachments Attachments

* Adding stack traces and capturing application crashes requires you to add an unwind library and hook into signal handlers of your process. The Standalone distribution currently does not contain integrations that perform this automatically.

Building the SDK

To build the SDK, download the latest release of the SDK from the Releases page. For each supported platform, there is a gen_* subfolder that contains build files:

Windows

gen_windows contains a Microsoft Visual Studio 2017 solution. Open the solution and add your projects or copy the projects to an existing solution. Each project supports a debug and release configuration and includes all sources required for building.

Linux and macOS

gen_linux and gen_macos contain Makefiles that can be used to produce dynamic libraries. Run make help to see an overview of the available configurations and target. There are debug and release configurations, that can be toggled when building:

make config=release sentry

There are multiple available targets to build:

  • sentry: Builds the Native SDK built as a dynamic library.
  • sentry_breakpad: Builds the Native SDK with Google Breakpad as a dynamic library.
  • sentry_crashpad: Builds the Native SDK with Google Crashpad as a dynamic library.
  • crashpad_*: Builds crashpad utilities. To run the Crashpad distribution of the SDK, you must build crashpad_handler and ship it with your application.

Connecting the SDK to Sentry

After completing the project setup in Sentry, it shows the Data Source Name (DSN). It looks similar to a standard URL, and contains all configuration for the SDK.

Import and initialize the Sentry SDK early in your application setup:

#include <sentry.h>

int main(void) {
  sentry_options_t *options = sentry_options_new();
  sentry_options_set_dsn(options, "___PUBLIC_DSN___");
  sentry_init(options);

  /* ... */

  // make sure everything flushes
  sentry_shutdown();
}

Alternatively, the DSN can be passed as SENTRY_DSN environment variable during runtime. This can be especially useful for server applications.

Verifying Your Setup

Now that SDK setup is complete, verify that all configuration is correct. Start by capturing a manual event:

sentry_capture_event(sentry_value_new_message_event(
  /*   level */ SENTRY_LEVEL_INFO,
  /*  logger */ "custom",
  /* message */ "It works!"
));

Once the event is captured, it will show up on the Sentry dashboard.

Capturing Events

The Native SDK exposes a Value API to construct values like Exceptions, User objects, Tags, and even entire Events. There are several ways to create an event.

Manual Events

To create and capture a manual event, follow these steps:

  1. Create an event value using sentry_value_new_event. This internally creates an object value and initializes it with common event attributes, like a timestamp and event_id.
  2. Add custom attributes to the event, like a message or an exception.
  3. Send the event to Sentry by invoking sentry_capture_event.

In a more complex example, it looks like this:

sentry_value_t event = sentry_value_new_event();
sentry_value_set_by_key(event, "message", sentry_value_new_string("Hello!"));

sentry_value_t screen = sentry_value_new_object();
sentry_value_set_by_key(screen, "width", sentry_value_new_int32(1920));
sentry_value_set_by_key(screen, "height", sentry_value_new_int32(1080));

sentry_value_t extra = sentry_value_new_object();
sentry_value_set_by_key(extra, "screen_size", screen);

sentry_value_set_by_key(event, "extra", extra);
sentry_capture_event(event);

For the full list of supported values, see Event Payloads and linked documents.

Exceptions

To capture an error or exception condition, create events containing an exception object. It needs to contain at least a value and type:

#include <sentry.h>

sentry_value_t exc = sentry_value_new_object();
sentry_value_set_by_key(exc, "type", sentry_value_new_string("Exception"));
sentry_value_set_by_key(exc, "value", sentry_value_new_string("Error message."));

sentry_value_t event = sentry_value_new_event();
sentry_value_set_by_key(event, "exception", exc);
sentry_capture_event(event);

This exception does not contain a stack trace, which must be added separately.

Message Events

To simplify creating events, there are shorthand functions that construct prepopulated event objects. The most important one is sentry_value_new_message_event. The logger and message parameters are each optional.

sentry_value_t event = sentry_value_new_message_event(
  /*   level */ SENTRY_LEVEL_INFO,
  /*  logger */ "custom",
  /* message */ "It works!"
);

Uploading Debug Information

To allow Sentry to fully process native crashes and provide you with symbolicated stack traces, you need to upload Debug Information Files (sometimes also referred to as Debug Symbols or just Symbols). We recommend uploading debug information during your build or release process.

Note that for all libraries where you’d like to receive symbolication, you need to provide debug information. This includes dependencies and operating system libraries. If you are not sure which files are required, go to Project Settings > Processing Issues, which shows a list of all the necessary files and instructions to retrieve them.

In addition to Debug Information Files, Sentry needs Call Frame Information (CFI) to extract accurate stack traces from minidumps of optimized release builds. CFI is usually part of the executables and not copied to debug symbols. Unless you are uploading Breakpad symbols, be sure to also include the binaries when uploading files to Sentry.

For more information on uploading debug information and their supported formats, see Debug Information Files.

Releases

A release is a version of your code that you deploy to an environment. When you give Sentry information about your releases, you unlock many new features:

  • Determine the issue and regressions introduced in a new release
  • Predict which commit caused an issue and who is likely responsible
  • Resolve issues by including the issue number in your commit message
  • Receive email notifications when your code gets deployed

After configuring your SDK, setting up releases is a 2-step process:

  1. Create Release and Associate Commits
  2. Tell Sentry When You Deploy a Release

For more information, see Releases Are Better With Commits.

To configure the SDK to send release information, set the release during initialization:

  sentry_options_t *options = sentry_options_new();
  sentry_options_set_release(options, "my-unique-release-1.0.0");

Context

Sentry supports additional context with events. Often this context is shared among any issue captured in its lifecycle, and includes the following components:

Structured Contexts

Structured contexts are typically set automatically.

User

Information about the current actor.

Tags

Key/value pairs which generate breakdown charts and search filters.

Level

An event’s severity.

Fingerprint

A value used for grouping events into issues.

Unstructured Extra Data

Arbitrary unstructured data which the Sentry SDK stores with an event sample.

Context information is attached to every event until explicitly removed or overwritten.

Extra Context

In addition to the structured contexts that Sentry understands, you can send arbitrary key/value pairs of data which the Sentry SDK will store alongside the event. These are not indexed, and the Sentry SDK uses them to add additional information about what might be happening.

sentry_set_extra takes the name of the extra value as first parameter, and the value as sentry_value_t as second parameter:

sentry_value_t screen = sentry_value_new_object();
sentry_value_set_by_key(screen, "width", sentry_value_new_int32(1920));
sentry_value_set_by_key(screen, "height", sentry_value_new_int32(1080));
sentry_set_extra("screen_size", screen);

Capturing the User

Sending users to Sentry will unlock many features, primarily the ability to drill down into the number of users affecting an issue, as well as to get a broader sense about the quality of the application.

sentry_value_t user = sentry_value_new_object();
sentry_value_set_by_key(user, "id", sentry_value_new_int32(42));
sentry_value_set_by_key(user, "username", sentry_value_new_string("John Doe"));
sentry_set_user(user);

Users consist of a few critical pieces of information which are used to construct a unique identity in Sentry. Each of these is optional, but one must be present for the Sentry SDK to capture the user:

id

Your internal identifier for the user.

username

The user’s username. Generally used as a better label than the internal ID.

email

An alternative, or addition, to a username. Sentry is aware of email addresses and can show things like Gravatars, unlock messaging capabilities, and more.

ip_address

The IP address of the user. If the user is unauthenticated, providing the IP address will suggest that this is unique to that IP. If available, we will attempt to pull this from the HTTP request data.

Additionally, you can provide arbitrary key/value pairs beyond the reserved names, and the Sentry SDK will store those with the user.

Tagging Events

Tags are key/value pairs assigned to events that can be used for breaking down issues or quick access to finding related events.

sentry_set_tag("server_name", "caroline");

For more information, see the Tagging Events section in Context.

Setting the Level

You can set the severity of an event to one of five values (sorted from most severe to least severe): fatal, error, warning, info, and debug. The default level is error.

sentry_set_level(SENTRY_LEVEL_WARNING);

Setting the Fingerprint

Sentry uses a fingerprint to decide how to group errors into issues.

For some very advanced use cases, you can override the Sentry default grouping using the fingerprint attribute. In supported SDKs, this attribute can be passed with the event information and should be an array of strings.

If you wish to append information, thus making the grouping slightly less aggressive, you can do that as well by adding the special string {{default}} as one of the items.

For code samples, see Grouping & Fingerprints.

For more information, see Aggregate Errors with Custom Fingerprints.

Advanced Usage

Advanced Configuration

The Native SDK sets the options when you first initialize the SDK:

sentry_options_t *options = sentry_options_new();

sentry_options_set_environment(options, "Production");
sentry_options_set_release(options, "5fd7a6cd");
sentry_options_set_debug(options, 1);

sentry_init(options);

For more information, see:

To receive more information on actions leading up to an exception or crash, the SDK can record breadcrumbs that are automatically added to every event. The most recent breadcrumbs are kept in a buffer.

You can manually add breadcrumbs using sentry_add_breadcrumb:

#include <sentry.h>

sentry_value_t crumb = sentry_value_new_breadcrumb("default", "Authenticated user");
sentry_value_set_by_key(crumb, "category", sentry_value_new_string("auth"));
sentry_value_set_by_key(crumb, "level", sentry_value_new_string("info"));
sentry_add_breadcrumb(crumb);

For more information, see:

Filter Events & Custom Logic

Sentry exposes a before_send callback which can be used to filter out information or add additional context to the event object. The callback must conform to the sentry_event_function_t signature.

#include <sentry.h>

sentry_value_t strip_sensitive_data(sentry_value_t event, void *hint) {
  /* modify event here or return NULL to discard the event */
  return event;
}

int main(void) {
  sentry_options_t *options = sentry_options_new();
  sentry_options_set_before_send(options, strip_sensitive_data);
  sentry_init(options);

  /* ... */
}

The callback is executed in the same thread as the call to sentry_capture_event. Work performed by the function may thus block the executing thread. For this reason, consider avoiding heavy work in before_send.

For more information, see:

Transports

The Native SDK uses Transports to send event payloads to Sentry. The default transport depends on the target platform:

  • Linux: Curl
  • macOS: Curl
  • Windows: WinHTTP

To specify a custom transport, use the sentry_options_set_transport function and supply a transport that conforms to the sentry_transport_function_t signature:

#include <sentry.h>

void custom_transport(sentry_value_t event, void *data) {
  /*
   * Send the event here. If the transport requires state, such as an HTTP
   * client object or request queue, it can be specified in the `data`
   * parameter when configuring the transport. It will be passed as second
   * argument to this function.
   */
}

int main(void) {
  void *transport_data = 0;

  sentry_options_t *options = sentry_options_new();
  sentry_options_set_transport(options, custom_transport, transport_data);
  sentry_init(options);

  /* ... */
}

The transport is invoked in the same thread as the call to sentry_capture_event. Consider to offload network communication to a background thread or thread pool to avoid blocking execution.

Integrations

Integrations extend the functionality of the SDK for some common frameworks and libraries. Similar to plugins, they extend the functionality of the Sentry SDK. The Native SDK comes in two additional distributions that include integrations into the Breakpad and Crashpad libraries, respectively.

Google Breakpad

Breakpad is an open-source multiplatform crash reporting system written in C++ by Google and the predecessor of Crashpad. It supports macOS, Windows, and Linux, and features an uploader to submit minidumps to a configured URL right when the process crashes.

To use the Breakpad integration with the Native SDK, build and link the sentry_breakpad dynamic library. Then, configure a path at which Breakpad can store its database. This location temporarily hosts Minidumps before they are uploaded to Sentry.

sentry_options_t *options = sentry_options_new();
sentry_options_set_database_path(options, "sentry-db");
sentry_init(options);

Google Crashpad

Crashpad is an open-source multiplatform crash reporting system written in C++ by Google. It supports macOS, Windows, and Linux (limited), and features an uploader to submit minidumps to a configured URL right when the process crashes.

To use the Crashpad integration with the Native SDK, build and link the sentry_crashpad dynamic library. Additonally, build the standalone crashpad_handler application. Then, configure a path at which Crashpad can store its database. This location temporarily hosts Minidumps before they are uploaded to Sentry.

sentry_options_t *options = sentry_options_new();
sentry_options_set_handler_path(options, "path/to/crashpad_handler");
sentry_options_set_database_path(options, "sentry-db");
sentry_init(options);

The crashpad handler executable must be shipped alongside your application so that it can be launched when initializing the SDK. The path is evaluated relative to the current working directory at runtime.

Event Attachments (Preview)

Besides the Minidump file, Sentry can optionally store additional files uploaded in the same request, such as log files.

The organization and project setting Store Native Crash Reports also enables storage of the original minidump files. For data privacy reasons, this setting is by default disabled. Raw minidumps are deleted permanently with their issues or after 30 days.

Attachments require the Crashpad distribution of the SDK. To add an attachment, the path to the file has to be configured when initializing the SDK. It will monitor the file and add it to any Minidump that is sent to Sentry:

sentry_options_add_attachment(options, "log", "/var/server.log");