Google は、黒人コミュニティのための人種的公平の促進に取り組んでいます。詳細をご覧ください。

Android NDK クラッシュ レポートを取得する

Android アプリにネイティブ ライブラリが含まれている場合は、アプリのビルド構成を少し更新するだけで、Firebase Crashlytics でネイティブ コードの完全なスタック トレースを行い、詳細なクラッシュ レポートを作成できます。このガイドでは、新しい Firebase Crashlytics SDK を使用してクラッシュ レポートを構成する方法について説明します。

始める前に

まず、Crashlytics を設定します。

  1. ステップ 2(アプリに Firebase Crashlytics プラグインを追加する)では、アプリが Crashlytics Gradle プラグイン v2.4.0 以降を使用していることを確認します。これにより、ストリップされていないバイナリのみを使用してシンボルをアップロードし、シンボリケートされたクラッシュを生成できます。

ステップ 1: Gradle の構成を更新する

アプリレベルの build.gradle で、Crashlytics NDK のランタイム依存関係を宣言します。

Java

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

dependencies {
  // ...

  // Import the BoM for the Firebase platform
  implementation platform('com.google.firebase:firebase-bom:28.2.0')

  // Declare the dependency for the Firebase Crashlytics NDK library.
  // If you previously declared the Firebase Crashlytics dependency, replace it.
  // When using the BoM, you don't specify versions in Firebase library dependencies
  implementation 'com.google.firebase:firebase-crashlytics'
  implementation 'com.google.firebase:firebase-crashlytics-ndk'
  implementation 'com.google.firebase:firebase-analytics'
}

// …
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
          }
      }
  }
}

Firebase Android BoM を使用すると、アプリは常に互換性のあるバージョンの Firebase Android ライブラリを使用します。

(別の方法)BoM を使用せずに Firebase ライブラリの依存関係を宣言する

Firebase BoM を使用しない場合は、依存関係の行でそれぞれの Firebase ライブラリのバージョンを指定する必要があります。

アプリで複数の Firebase ライブラリを使用する場合は、すべてのバージョンの互換性を確保するため、BoM を使用してライブラリのバージョンを管理することを強くおすすめします。

  dependencies {
      // Declare the dependency for the Firebase Crashlytics NDK library.
      // If you previously declared the Firebase Crashlytics dependency, replace it.
      // When NOT using the BoM, you must specify versions in Firebase library dependencies
      implementation 'com.google.firebase:firebase-crashlytics:18.1.0'
      implementation 'com.google.firebase:firebase-crashlytics-ndk:18.1.0'
      implementation 'com.google.firebase:firebase-analytics:19.0.0'
  }
  

Kotlin+KTX

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

dependencies {
  // ...

  // Import the BoM for the Firebase platform
  implementation platform('com.google.firebase:firebase-bom:28.2.0')

  // Declare the dependency for the Firebase Crashlytics NDK library.
  // If you previously declared the Firebase Crashlytics dependency, replace it.
  // When using the BoM, you don't specify versions in Firebase library dependencies
  implementation 'com.google.firebase:firebase-crashlytics-ktx'
  implementation 'com.google.firebase:firebase-crashlytics-ndk'
  implementation 'com.google.firebase:firebase-analytics-ktx'
}

// …
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
          }
      }
  }
}

Firebase Android BoM を使用すると、アプリは常に互換性のあるバージョンの Firebase Android ライブラリを使用します。

(別の方法)BoM を使用せずに Firebase ライブラリの依存関係を宣言する

Firebase BoM を使用しない場合は、依存関係の行でそれぞれの Firebase ライブラリのバージョンを指定する必要があります。

アプリで複数の Firebase ライブラリを使用する場合は、すべてのバージョンの互換性を確保するため、BoM を使用してライブラリのバージョンを管理することを強くおすすめします。

  dependencies {
      // Declare the dependency for the Firebase Crashlytics NDK library.
      // If you previously declared the Firebase Crashlytics dependency, replace it.
      // When NOT using the BoM, you must specify versions in Firebase library dependencies
      implementation 'com.google.firebase:firebase-crashlytics-ktx:18.1.0'
      implementation 'com.google.firebase:firebase-crashlytics-ndk:18.1.0'
      implementation 'com.google.firebase:firebase-analytics-ktx:19.0.0'
  }
  

Crashlytics NDK バージョン 17.3.0 では必須: アプリで targetSdkLevel 30 以上を使用している場合は、AndroidManifest.xml に次の行を追加して、アプリのポインタのタグ付け機能を無効にする必要があります。

<application android:allowNativeHeapPointerTagging="false">
...
</application>

詳しくは、タグ付きポインタに関するデベロッパー サポートをご覧ください。

ステップ 2: ネイティブ シンボルのアップロードを有効にする

NDK のクラッシュから読み取り可能なスタック トレースを生成するには、ネイティブ バイナリ内のシンボルを Crashlytics に知らせる必要があります。Gradle プラグインには、このプロセスを自動化する uploadCrashlyticsSymbolFileBUILD_VARIANT タスクが含まれています(このタスクにアクセスするには、必ず nativeSymbolUploadEnabled を true に設定してください)。

スタック トレースにメソッド名を含めるには、NDK ライブラリをビルドするたびに uploadCrashlyticsSymbolFileBUILD_VARIANT タスクを明示的に呼び出す必要があります。例:

>./gradlew app:assembleBUILD_VARIANT\
           app:uploadCrashlyticsSymbolFileBUILD_VARIANT

Crashlytics NDK v17.3.0 以降と Gradle プラグイン v2.4.1 以降は、ネイティブ共有オブジェクト内の GNU ビルド ID の存在に依存しています。この ID の存在を確認するには、各バイナリに対して readelf -n を実行します。このビルド ID が存在しない場合は、ビルドシステムのフラグに -Wl,--build-id を追加することで問題を解決できます。

ステップ 3(省略可): 外部依存関係のシンボルをアップロードする

シンボルのアップロード タスクでは、CMake などの標準の NDK ビルドツールを使用して、Gradle ビルドの一環としてネイティブ ライブラリをビルドすることを前提としています。ネイティブ ライブラリを外部でビルドしている場合や、カスタマイズした NDK のビルドプロセスを Gradle 内で使用している場合、ストリップされていないライブラリへのパスを明示的に指定しなければならない場合があります。firebaseCrashlytics 拡張機能には、これを指定するためのプロパティ unstrippedNativeLibsDir があります。

アプリレベルの build.gradle ファイルに以下のコマンドを追加します。

// …
android {
    // ...
    buildTypes {
        release {
            firebaseCrashlytics {
                nativeSymbolUploadEnabled true
                unstrippedNativeLibsDir file("path/to/unstripped/dir")
            }
        }
    }
}

Crashlytics プラグインは、指定されたディレクトリおよびそのすべてのサブディレクトリを対象に、.so 拡張子を持つネイティブ ライブラリを検索します。Crashlytics はそのようなすべてのライブラリからデバッグ シンボルを抽出し、Firebase サーバーにアップロードします。

unstrippedNativeLibsDir プロパティでは、org.gradle.api.Project#files(Object...) で使用できる引数(java.lang.Stringjava.io.Fileorg.gradle.api.file.FileCollection など)を指定できます。リストまたは FileCollection インスタンスを指定することで、1 つのビルド フレーバーに複数のディレクトリを指定できます。

ステップ 4(省略可): NDK クラッシュ レポートをカスタマイズする

必要に応じて、C++ コードに crashlytics.h ヘッダーを組み込んで、NDK クラッシュ レポートにメタデータ(ログ、カスタムキー、ユーザー ID など)を追加できます。crashlytics.h は、ヘッダーのみの C++ ライブラリとして Firebase Android SDK GitHub リポジトリに用意されています。NDK C++ API の使用方法については、ヘッダー ファイル内のコメントをご覧ください。

ステップ 5(省略可): シンボリケーション用に Breakpad シンボル ファイルを有効にする

Crashlytics Gradle プラグインは、次の機能を提供します。

  • ストリップされていないネイティブのバイナリを処理し、シンボル ファイルを生成する。
  • 生成されたシンボル ファイルをサーバーにアップロードし、後でネイティブ コードでのクラッシュをシンボリケーションする際に使用する。

Crashlytics Gradle プラグインは、Crashlytics シンボル ファイル(cSYM)と Breakpad シンボル ファイルの 2 種類のシンボル ファイル形式をサポートしています。

Breakpad が生成したシンボル ファイルには、Crashlytics が生成したシンボル ファイルよりも多くの情報が含まれています。これには、スタック フレームの計算のための巻き戻しプロセスで使用される、Call Frame Info(CFI)などがあります。CFI を使用すると、特にゲームやメディアアプリなどの高度に最適化されたアプリケーションで、より正確なスタック トレースを実現できます。

Breakpad ベースのシンボル ファイル生成ツールは、次のいずれかの方法で有効にできます。

  • オプション 1: build.gradle ファイルの firebaseCrashlytics 拡張機能を使用して有効にする

    アプリレベルの build.gradle ファイルに以下のコマンドを追加します。

    android {
      // ...
      buildTypes {
        // ...
        release {
          // ...
          firebaseCrashlytics {
            // existing; required for either symbol file generator
            nativeSymbolUploadEnabled true
            // Add this optional new block to specify breakpad() or csym()
            symbolGenerator {
               breakpad()
            }
          }
        }
      }
    }
    

    デフォルトの Crashlytics シンボル ファイル生成ツールに戻すには、次のいずれかを行います。

    • プラグインはデフォルトで Crashlytics シンボル ファイル生成ツールを使用するため、symbolGenerator ブロックはすべて省略します。

    • ブロックはそのままにして、breakpad()csym() に変更します。

  • オプション 2: Gradle プロパティ ファイルでプロパティ行を使用して有効にする

    com.google.firebase.crashlytics.symbolGenerator プロパティを使用すると、使用するシンボル ファイル生成ツールを制御できます。このプロパティの有効な値は、breakpadcsym です。指定しない場合、現在のデフォルトは csym と同じですが、これは将来のバージョンで変更される可能性があります。

    手動で Gradle プロパティ ファイルを更新することも、コマンドラインからファイルを更新することもできます。たとえば、Breakpad シンボル ファイル生成ツールを有効にするには、次のコマンドのように breakpad の値を指定します。

    ./gradlew -Pcom.google.firebase.crashlytics.symbolGenerator=breakpad \
    app:assembleRelease app:uploadCrashlyticsSymbolFileRelease
    

ステップ 6: クラッシュ レポートを表示する

Crashlytics が NDK のクラッシュを正しく報告していることを確認するには、アプリをビルドし、シンボルをアップロードして、ネイティブ コードでのクラッシュを強制的に発生させます。アプリがクラッシュしたら、Crashlytics がレポートを送信できるようにそのアプリを再起動する必要があります。数分以内に Firebase コンソールにクラッシュが表示されます。

トラブルシューティング

Firebase コンソールのスタック トレースと logcat のスタック トレースが一致しない場合は、トラブルシューティング ガイドをご覧ください。