LogoLogo
HomePlatform IntegrationsDownloadsLogin
  • Welcome
  • 📌Introduction
    • Getting Started
      • Signing Up
      • Creating a Database
      • Platform Integrations
        • 💻Desktop
          • BugSplat Crash Reporting Library for Windows (Native C++)
            • Full Memory Dumps
            • Windows (Native C++) Dependencies
          • Windows (.NET Framework)
          • macOS
          • Linux
        • 🔀Cross-Platform
          • .NET Standard
          • Breakpad (Deprecated)
          • Crashpad
            • How to Build Google Crashpad
          • Deno
          • Electron
          • Java
          • Node.js
          • Python
          • Qt
        • 🎮Game Development
          • CRYENGINE
          • Nintendo Switch
          • PlayStation
          • Unreal Engine
            • Unreal Engine Plugin
          • Unity
          • Xbox
        • 📱Mobile
          • Android
          • Ionic
          • iOS
          • React Native
        • 🕸️Web
          • Angular
          • JavaScript
          • React
          • Vue
        • ⌛Downloads
      • Platform Samples
        • BugSplatTester (iOS)
        • BugSplatTester (macOS)
        • myConsoleCrasher (C++)
          • Address Sanitizer Reports
        • my-android-crasher
        • my-angular-crasher
        • my-electron-crasher
        • my-java-crasher
        • my-node-crasher
        • my-qt-crasher
        • my-react-crasher
        • my-unity-crasher
        • my-unreal-crasher
      • Inviting Team Members
      • Importing Crashes
      • Troubleshooting
      • Quickly Submitting Your First Crash in Under 5 Minutes
    • Development
      • Using the App
      • Symbol Files
        • Common Symbols
        • How to Manually Upload Symbols
        • Source Maps
        • Symbol Servers
        • Working with Symbol Files in Windows Environments
      • Searching
        • Table Filtering
        • Table Grouping
      • Grouping Crashes
      • Commenting
      • Integrations and Third Party Tools
        • Configurable Alerts
          • Slack
          • Microsoft Teams
          • Discord
          • Email
          • Webhook
        • Issue Trackers
          • Azure DevOps
          • Favro
          • Jira
          • GitHub Issues
          • GitLab
          • Monday.com
          • YouTrack
          • Auto-Creating Defects from BugSplat Databases in Attached Third-Party Issue Trackers
      • API
        • Web Application Endpoints
          • Charting
          • Company
          • Crash
          • Crashes
          • Crash Groups
          • Databases
          • Defect
          • Events
          • Import/Migrate
          • Support Response
          • User (GDPR)
          • Users
          • Versions
        • Crash Post Endpoints
        • OAuth2
        • Defect Tracker Options
        • Paging, Filtering, and Grouping
        • Platform Specific API's
          • C++ Native API
          • .NET API
    • Production
      • Versions
      • 🆕Regression Alerts
      • Security and Compliance
        • Security Program
        • BugSplat Security Program Inquirys
        • SOC 2
        • GDPR & UK GDPR Compliance
        • Avoid Collecting Personally Identifiable Information (PII)
        • Crash Expiry
        • Terms
        • Privacy Policy
      • Support Responses
      • BugSplat Status
  • 🍎Education
    • BugSplat Terminology
    • How-Tos
      • Creating Defects
      • Contacting End-Users
      • Crash Dialog Branding
      • Reprocess Crashes
      • Batch Reprocess Crashes
      • Using the Crash Attribute Feature
      • Send Feedback
      • Remove Crashes
    • Videos
      • BugSplat Product Walkthrough
    • FAQs
      • How Do I Upload Crashes with Python?
      • How Do I Remove Symbol Files?
      • Crash details 'Active Thread'
      • How long does it take to process a crash?
      • How BugSplat handles large crash volumes
      • How Does Crash Rate Limiting Work?
      • Add Custom Branding to Support Response
      • Finding Missing Reports
      • Using Dark Mode
      • What If My App or Game Grows Quickly?
      • Does BugSplat have an effect on application performance?
      • Manually Upload Crash Reports to BugSplat
      • How to configure proxy settings in BugSplat
      • Using BugSplat's public database
      • How to Upload Symbol Files with Symbol-Upload
      • Using SendPdbs to Automatically Upload Symbol Files
      • Managing Symbol Space
      • Why Group Crashes?
      • Uploading third-party DLLs without PDB files
      • Localized Support Responses for Windows C++, .NET, and macOS
      • BugSplat application uptime data
        • What are the upload size considerations with BugSplat accounts.
      • Is an application's source code safe when using BugSplat?
      • How to get correct callstacks with BugSplat in Steam
      • What is a crash reporter?
      • Common End-User Questions
        • Missing BugSplat.dll
        • What should I do if I get a BugSplat?
        • What is BsSndRpt.exe?
        • My software just crashed. Should I contact BugSplat for help?
  • 🏢Administration
    • Billing
      • Free Trial Overview
      • Plans and Billing Overview
      • How to Sign Up for a BugSplat Plan
      • Viewing Account Usage
      • Upgrading, Changing, or Canceling Your Plan
        • Upgrading or Downgrading Your Plan
        • Adding Additional Crashes and Storage Space
        • Updating Credit Card and Billing Information and Viewing Billing History
        • Updating Tax and VAT Information
        • Canceling Your Plan
      • Free and Discounted Plans
        • Free Plan Overview
        • Free Crash Reporting for Indie Game Development
        • Education
        • Open-Source
        • Good Causes
      • Plans, Upgrades, and Payments FAQ
        • Fair-Refund Policy
        • Update to Our Legacy Plans Guide
        • Updates to BugSplat Pricing Plans - March 2024
        • Using Coupons and Promotions at BugSplat
        • What is 'High Volume Fractional Crash Processing'?
    • Account
      • Migrating Databases
      • Deleting Databases
      • Deleting a Company Account
      • Changing Company Name
    • User Management
      • User Permissions
      • Deleting a User
      • Requesting Access
      • Login Page and Options
      • Password Settings and Reset Options
        • Required Password Reset - August 4th, 2023
      • Single Sign-On (SSO)
      • Multi-Factor Authentication (MFA)
      • Enforce MFA
      • Adding New Users in Companies with Multiple Databases
    • Contact us
  • 🐛About
    • What is BugSplat?
    • Why BugSplat?
    • Who is BugSplat?
      • Our Values
      • Charitable Giving
      • Brand Guidelines
    • Partnerships
    • Misc
      • Promotions
        • March 2024 - Game Developer Free Months of Service
      • Giveaways
        • April 8 - April 22, 2025
        • Feb 18 - March 17, 2025
        • Jan 15 - Feb 13, 2025
        • December 19-29, 2024
        • November 21–28, 2024
        • October 17-24th, 2024
        • September 19-26th, 2024
        • July 18 - July 23, 2024
        • April 18 - May 12, 2024
        • March 18 - April 03, 2024
        • November 15-30, 2023
        • October 9-23, 2023
  • 🔀Changelog
    • Changelog
Powered by GitBook
On this page
  • Introduction
  • Building Crashpad
  • Integrating Crashpad
  • Configuring Crashpad
  • Symbols
  • Generating a Crash Report

Was this helpful?

  1. Introduction
  2. Getting Started
  3. Platform Integrations
  4. Mobile

Android

PreviousMobileNextIonic

Last updated 1 year ago

Was this helpful?

Introduction

The is a set of tools for building native C++ applications for Android. BugSplat recommends using to handle native crashes in Android NDK applications. Before integrating your application with BugSplat, make sure to review the resources and complete the simple startup tasks listed below.

BugSplat also provides a reference Android Studio project that includes , shows how to , demonstrates how to link with the Crashpad libraries and and copy the necessary files to your APK via .

Building Crashpad

For an in depth guide that discusses how to build Crashpad, please see this .

To build Crashpad you'll first need to download a copy of the Chromium . Once you have downloaded depot_tools, you'll need to add the parent folder to your system's PATH environment variable. After adding depot_tools to your systems PATH, run the following commands to download the Crashpad repository:

mkdir ~/crashpad
cd ~/crashpad
fetch crashpad
cd crashpad

Next you'll need to generate Crashpad build configurations for each your application supports. Generate build configurations for the target_cpu values arm, arm64, x86, and x64:

gn gen out/arm64-v8a --args='target_os="android" target_cpu="arm64" android_ndk_root="[Path to Android SDK]/ndk/21.4.7075529" android_api_level=21'

Build each of build configurations:

ninja -C out/arm64-v8a

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 app/src/main/cpp/crashpad/include. Next, add the include directories your project's CMakeLists.txt file:

# Crashpad Headers
include_directories(${PROJECT_SOURCE_DIR}/crashpad/include/ ${PROJECT_SOURCE_DIR}/crashpad/include/third_party/mini_chromium/mini_chromium/)

After adding the include directories, you'll need to add the Crashpad static libraries to your project. You'll need to add a set of Crashpad libraries for each ABI your application supports. From the /crashpad/out/Debug/{{ABI}} directory you'll want to copy the client, util and third_party/mini_chromium/mini_chromium/base folders to app/src/main/cpp/crashpad/lib/{{ABI}}.

Once all of the Crashpad libraries have been copied to your project directory, add the following to your project's CMakeLists.txt file to link the Crashpad libraries:

# Crashpad Libraries
add_library(crashpad_client STATIC IMPORTED)
set_property(TARGET crashpad_client PROPERTY IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/crashpad/lib/${ANDROID_ABI}/client/libcrashpad_client.a)

add_library(crashpad_util STATIC IMPORTED)
set_property(TARGET crashpad_util PROPERTY IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/crashpad/lib/${ANDROID_ABI}/util/libcrashpad_util.a)

add_library(base STATIC IMPORTED)
set_property(TARGET base PROPERTY IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/crashpad/lib/${ANDROID_ABI}/base/libbase.a)

# Specifies the target library
target_link_libraries(  
    native-lib
    crashpad_client
    crashpad_util
    base
)

Additionally, you'll need ship a copy of the crashpad_handler executable with your application. To do this, you'll need to rename crashpad_handler to libcrashpad_handler.so otherwise it will be ignored by the APK bundler. Copy libcrashpad_handler.so to app/src/main/cpp/crashpad/lib/{{ABI}} for each Crashpad ABI architecture. Add the following snippet to CMakeLists.txt so that libcrashpad_handler.so is copied to your device and made available at runtime:

# Crashpad Handler
add_library(crashpad_handler SHARED IMPORTED)
set_property(TARGET crashpad_handler PROPERTY IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/crashpad/lib/${ANDROID_ABI}/libcrashpad_handler.so)

Configuring Crashpad

To enable Crashpad in your application you'll need to configure the Crashpad handler with your BugSplat database, application name and application version. The following snippet will configure the Crashpad handler:

#include <jni.h>
#include <string>
#include <unistd.h>
#include "client/crashpad_client.h"
#include "client/crash_report_database.h"
#include "client/settings.h"

using namespace base;
using namespace crashpad;
using namespace std;

extern "C" JNIEXPORT jboolean JNICALL
Java_com_example_androidcrasher_MainActivity_initializeCrashpad(
    JNIEnv* env,
    jobject /* this */
) {

    string dataDir = "/data/data/com.example.androidcrasher";

    // Crashpad file paths
    FilePath handler(dataDir + "/lib/libcrashpad_handler.so");
    FilePath reportsDir(dataDir + "/crashpad");
    FilePath metricsDir(dataDir + "/crashpad");

    // Crashpad upload URL for BugSplat database
    string url = "http://{{database}}.bugsplat.com/post/bp/crash/crashpad.php";

    // Crashpad annotations
    map<string, string> annotations;
    annotations["format"] = "minidump";           // Required: Crashpad setting to save crash as a minidump
    annotations["database"] = "{{database}}";     // Required: BugSplat database
    annotations["product"] = "{{appName}}";       // Required: BugSplat appName
    annotations["version"] = "{{appVersion}}";    // Required: BugSplat appVersion
    annotations["key"] = "Key";                   // Optional: BugSplat key field
    annotations["user"] = "fred@bugsplat.com";    // Optional: BugSplat user email
    annotations["list_annotations"] = "Sample comment"; // Optional: BugSplat crash description

    // Crashpad arguments
    vector<string> arguments;
    arguments.push_back("--no-rate-limit");

    // Crashpad local database
    unique_ptr<CrashReportDatabase> crashReportDatabase = CrashReportDatabase::Initialize(reportsDir);
    if (crashReportDatabase == NULL) return false;

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

    // File paths of attachments to be uploaded with the minidump file at crash time - default bundle limit is 20MB
    vector<FilePath> attachments;
    FilePath attachment(dataDir + "/files/attachment.txt");
    attachments.push_back(attachment);

    // Start Crashpad crash handler
    static CrashpadClient *client = new CrashpadClient();
    bool status = client->StartHandlerAtCrash(handler, reportsDir, metricsDir, url, annotations, arguments, attachments);
    return status;
}

Be sure to update the values for database, appName, appVersion and packageNameto values specific to your application. Next add a call to initializeCrashpad at the entry point of your application. The following example defines initializeCrashpad as a native C++ function and calls it using Kotlin from MainActivity:

// MainActivity entry point
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Example of a call to a native method
    sample_text.text = if (initializeCrashpad()) "initialized" else "fail"
}

// Declare native C++ method
external fun initializeCrashpad(): Boolean

To test the attachments feature, use Java or Kotlin to write a text file. The following is a Kotlin snippet that creates a file attachment.txt:

// MainActivity entry point
override fun onCreate(savedInstanceState: Bundle?) {
    writeLogFile()
    ...
}

private fun writeLogFile() {
    try {
        val outputStreamWriter = OutputStreamWriter(
        applicationContext.openFileOutput(
                "attachment.txt",
                Context.MODE_PRIVATE
            )
        )
        outputStreamWriter.write("BugSplat rocks!")
        outputStreamWriter.close()
    } catch (e: IOException) {
        Log.e("Exception", "File write failed: " + e.toString())
    }
}

Symbols

To ensure that your crash reports contain function names and line numbers you'll need to add an option to your build configuration that prevents symbolic information from being stripped. To prevent symbols from being stripped, add the following to your build.gradle file:

android {
  ...
  // Add this directly under the android section in app/src/build.gradle
  packagingOptions{
    doNotStrip "*/armeabi/*.so"
    doNotStrip "*/armeabi-v7a/*.so"
    doNotStrip "*/x86/*.so"
    doNotStrip "*/x86_64/*.so"
  }
}

Once you've built dump_syms on a Linux system, run dump_syms on a Linux machine passing it the path to your Android library:

./dump_syms path/to/app/build/intermediates/merged_native_libs/debug/out/lib/x86/my-lib.so > /my-lib.so.sym

If you're developing on an macOS or Linux system, build the Breakpad tool symupload on your local system. Upload the generated .sym file by running symupload. Be sure to replace the {{database}}, {{application}} and {{version}} with the values you used in the Configuring Crashpad section:

symupload "/path/to/my-lib.so.sym" "https://{{database}}.bugsplat.com/post/bp/symbol/breakpadsymbols.php?appName={{application}}&appVer={{version}}"

After each release build you'll need to generate and upload .sym files making sure to increment the version number each time. The version number from the Configuring Crashpad section must match the version number in your upload URL.

Generating a Crash Report

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

*(volatile int *)0 = 0;

Next, you will need to generate and upload .sym files to BugSplat. To generate symbols for your Android NDK library you will need to build the Breakpad tool dump_syms on a Linux machine. For more information about building Breakpad tools on Linux please see this .

You can also run the Linux version of dump_syms using compatible Linux emulator on or . Examples of how to run a Linux build of dump_syms on macOS and Windows can be found in the section of the AndroidCrasher repository.

If you're developing on Windows, symupload will not upload your Android .sym files. As an alternative, the AndroidCrasher folder provides and example PowerShell that will upload .sym files to BugSplat.

After you've submitted a crash report, navigate to the page. Click the link in the ID column to see the details of your crash report. The following image is from our sample AndroidCrasher application:

📌
📱
Android NDK
Crashpad
Getting Started
my-android-crasher
pre-built Crashpad libraries
initialize Crashpad
CMakeLists.txt
article
depot_tools
Android ABI
macOS
Windows
tools
tools
script
Crashes
document
BugSplat Android Libs Crashpad Folders
BugSplat Android NDK Crash