Get Android NDK crash reports with the Firebase Crashlytics SDK

If your Android app contains native libraries, you can enable full stack traces and detailed crash reports for your native code from Firebase Crashlytics with a few small updates to your app's build configuration. This guide describes how to configure crash reporting with the new Firebase Crashlytics SDK.

Before you begin

To get started, set up Crashlytics with the Firebase Crashlytics SDK.

Step 1: Update your Gradle configuration

In your app-level build.gradle, add the Crashlytics NDK runtime dependency:

apply plugin: 'com.android.application'
apply plugin: 'com.google.firebase.crashlytics'

dependencies {
    // ...

    // Add the Crashlytics NDK dependency.
    implementation 'com.google.firebase:firebase-crashlytics-ndk:17.0.0-beta01'
}

// …
android {
    // ...
    buildTypes {
        release {
            // Add this extension
            firebaseCrashlytics {
                // Enable processing and uploading of native symbols to Crashlytics
                // servers. By default, this is disabled to improve build speeds.
                // This flag must be enabled to see properly-symbolicated native
                // stack traces in the Crashlytics dashboard.
                nativeSymbolUploadEnabled true
            }
        }
    }
}

Step 2: Enable native symbol uploading

To produce readable stack traces from NDK crashes, Crashlytics needs to know about the symbols in your native binaries. Our Gradle plugin includes the uploadCrashlyticsSymbolFileBUILD_VARIANT task to automate this process (to access this task, make sure nativeSymbolUploadEnabled is set to true).

For method names to appear in your stack traces, you must explicitly invoke the uploadCrashlyticsSymbolFileBUILD_VARIANT task after each build of your NDK library. For example:

>./gradlew app:assembleBUILD_VARIANT\
           app:uploadCrashlyticsSymbolFileBUILD_VARIANT

Step 3 (optional): Upload symbols for external dependencies

Our symbol upload task assumes you are building your native libraries as part of your Gradle build, using standard NDK build tools such as CMake. If you have externally-built native libraries, or are using a customized NDK build process within Gradle, you may need to explicitly specify the path to your stripped and unstripped libraries. The firebaseCrashlytics extension provides properties to do this: strippedNativeLibsDir and unstrippedNativeLibsDir.

// …
android {
    // ...
    buildTypes {
        release {
            firebaseCrashlytics {
                nativeSymbolUploadEnabled true
                strippedNativeLibsDir ‘path/to/stripped/parent/dir’
                unstrippedNativeLibsDir ‘path/to/unstripped/parent/dir’
            }
        }
    }
}

Our plugin assumes libraries are located in architecture-specific subdirectories under the specified directories, and that corresponding stripped/unstripped library pairs have identical paths under that directory. For example:

strippedNativeLibsDir/
 +- x86/
      |
      +- libfoo.so
      +- libbar.so
 +- arm64/
      |
      +- libfoo.so
      +- libbar.so

unstrippedNativeLibsDir/
 +- x86/
      |
      +- libfoo.so
      +- libbar.so
 +- arm64/
      |
      +- libfoo.so
      +- libbar.so

If your build system does not adhere to the above structure/naming scheme, manually create this structure on your local disk prior to invoking the uploadCrashlyticsSymbolFileBUILD_VARIANT task.

Step 4: See your crash reports

Verify that Crashlytics is properly reporting NDK crashes by building your app, uploading symbols, and forcing a native crash. You’ll need to restart the app after it crashes for Crashlytics to send the report. You should see the crash in your Firebase console within a few minutes.