Mendapatkan laporan error Android NDK

Jika aplikasi Android berisi library native, Anda dapat mengaktifkan pelacakan tumpukan penuh dan laporan error yang mendetail untuk kode native dari Firebase Crashlytics dengan sejumlah perubahan kecil pada konfigurasi build aplikasi Anda.

Panduan ini menjelaskan cara mengonfigurasi pelaporan error dengan Firebase Crashlytics SDK untuk NDK.

Jika Anda mencari cara memulai penggunaan Crashlytics di project Unity, lihat panduan Memulai Unity.

Sebelum memulai

  1. Tambahkan Firebase ke project Android jika belum melakukannya. Jika tidak memiliki aplikasi Android, Anda dapat mendownload aplikasi contoh.

  2. Direkomendasikan: Untuk mendapatkan log breadcrumb secara otomatis guna memahami tindakan pengguna yang menyebabkan peristiwa error, non-fatal, atau ANR, Anda harus mengaktifkan Google Analytics di project Firebase Anda.

    • Jika project Firebase yang ada belum mengaktifkan Google Analytics, Anda dapat mengaktifkan Google Analytics dari tab Integrations di > Project settings di Firebase console.

    • Jika Anda membuat project Firebase baru, aktifkan Google Analytics selama alur kerja pembuatan project.

  3. Pastikan bahwa aplikasi Anda memiliki versi minimum yang diperlukan berikut:

    • Gradle 8.0
    • Plugin Android Gradle 8.1.0
    • Plugin Gradle layanan Google 4.4.1

Langkah 1: Tambahkan Crashlytics SDK untuk NDK ke aplikasi Anda

Dalam file Gradle modul (level aplikasi) (biasanya <project>/<app-module>/build.gradle.kts atau <project>/<app-module>/build.gradle), tambahkan dependensi untuk library Crashlytics untuk Android. Sebaiknya gunakan Firebase Android BoM untuk mengontrol pembuatan versi library.

Untuk mengoptimalkan penggunaan Crashlytics, sebaiknya aktifkan Google Analytics di project Firebase dan tambahkan Firebase SDK untuk Google Analytics ke aplikasi Anda.

dependencies {
    // Import the BoM for the Firebase platform
    implementation(platform("com.google.firebase:firebase-bom:33.9.0"))

    // Add the dependencies for the Crashlytics NDK and Analytics libraries
    // When using the BoM, you don't specify versions in Firebase library dependencies
    implementation("com.google.firebase:firebase-crashlytics-ndk")
    implementation("com.google.firebase:firebase-analytics")
}

Dengan menggunakan Firebase Android BoM, aplikasi Anda akan selalu menggunakan versi library Android Firebase yang kompatibel.

Jika memilih untuk tidak menggunakan Firebase BoM, Anda harus menentukan setiap versi library Firebase di baris dependensinya.

Perlu diperhatikan bahwa jika Anda menggunakan beberapa library Firebase di aplikasi, sebaiknya gunakan BoM untuk mengelola versi library, yang memastikan bahwa semua versi kompatibel.

dependencies {
    // Add the dependencies for the Crashlytics NDK and Analytics libraries
    // When NOT using the BoM, you must specify versions in Firebase library dependencies
    implementation("com.google.firebase:firebase-crashlytics-ndk:19.4.0")
    implementation("com.google.firebase:firebase-analytics:22.2.0")
}
Mencari modul library khusus Kotlin? Mulai Oktober 2023 (Firebase BoM 32.5.0), developer Kotlin dan Java dapat bergantung pada modul library utama (untuk mengetahui detailnya, lihat FAQ tentang inisiatif ini).

Langkah 2: Tambahkan plugin Gradle Crashlytics ke aplikasi Anda

  1. Dalam file Gradle level root (level project) (<project>/build.gradle.kts atau <project>/build.gradle), tambahkan plugin Gradle Crashlytics ke blok plugins:

    KotlinGroovy
    plugins {
        // Make sure that you have the AGP plugin 8.1+ dependency
        id("com.android.application") version "8.1.4" apply false
        // ...
    
        // Make sure that you have the Google services Gradle plugin 4.4.1+ dependency
        id("com.google.gms.google-services") version "4.4.2" apply false
    
        // Add the dependency for the Crashlytics Gradle plugin
        id("com.google.firebase.crashlytics") version "3.0.3" apply false
    }
    plugins {
        // Make sure that you have the AGP plugin 8.1+ dependency
        id 'com.android.application' version '8.1.4' apply false
        // ...
    
        // Make sure that you have the Google services Gradle plugin 4.4.1+ dependency
        id 'com.google.gms.google-services' version '4.4.2' apply false
    
        // Add the dependency for the Crashlytics Gradle plugin
        id 'com.google.firebase.crashlytics' version '3.0.3' apply false
    }
  2. Dalam file Gradle modul (level aplikasi) (biasanya <project>/<app-module>/build.gradle.kts atau <project>/<app-module>/build.gradle), tambahkan plugin Gradle Crashlytics:

    KotlinGroovy
    plugins {
      id("com.android.application")
      // ...
    
      // Make sure that you have the Google services Gradle plugin
      id("com.google.gms.google-services")
    
      // Add the Crashlytics Gradle plugin
      id("com.google.firebase.crashlytics")
    }
    plugins {
      id 'com.android.application'
      // ...
    
      // Make sure that you have the Google services Gradle plugin
      id 'com.google.gms.google-services'
    
      // Add the Crashlytics Gradle plugin
      id 'com.google.firebase.crashlytics'
    }

Langkah 3: Tambahkan ekstensi Crashlytics ke build Anda

Dalam file Gradle modul (level aplikasi) (biasanya <project>/<app-module>/build.gradle.kts atau <project>/<app-module>/build.gradle), konfigurasikan ekstensi rashlytics extension.

KotlinGroovy
import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension

// ...

android {
  // ...
  buildTypes {
      getByName("release") {
          // Add this extension
          configure<CrashlyticsExtension> {
              // Enable processing and uploading of native symbols to Firebase 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
          }
      }
  }
}
// ...

android {
  // ...
  buildTypes {
      release {
          // Add this extension
          firebaseCrashlytics {
              // Enable processing and uploading of native symbols to Firebase 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
          }
      }
  }
}

Langkah 4: Siapkan upload otomatis simbol native

Untuk menghasilkan stack trace yang dapat dibaca dari error NDK, Crashlytics perlu mengetahui simbol dalam biner native Anda. Plugin Gradle Crashlytics menyertakan tugas uploadCrashlyticsSymbolFileBUILD_VARIANT untuk mengotomatiskan proses ini.

  1. Agar Anda dapat mengakses tugas untuk upload simbol otomatis, pastikan nativeSymbolUploadEnabled ditetapkan ke true dalam file Gradle modul (level aplikasi).

  2. Agar nama metode muncul dalam stack trace, Anda harus secara eksplisit memanggil tugas uploadCrashlyticsSymbolFileBUILD_VARIANT setelah setiap build library NDK. Contoh:

    >./gradlew app:assembleBUILD_VARIANT\
               app:uploadCrashlyticsSymbolFileBUILD_VARIANT
  3. Baik Crashlytics SDK untuk NDK maupun plugin Gradle Crashlytics bergantung pada keberadaan ID build GNU dalam objek native bersama.

    Anda dapat memverifikasi keberadaan ID ini dengan menjalankan readelf -n pada setiap biner. Jika ID build tidak ada, tambahkan -Wl,--build-id ke flag sistem build untuk memperbaiki masalah ini.

Langkah 5: Sengaja pancing error pengujian untuk menyelesaikan penyiapan

Untuk menyelesaikan penyiapan Crashlytics dan melihat data awal di dasbor Crashlytics pada Firebase console, Anda harus memaksa error pengujian.

  1. Tambahkan kode ke aplikasi yang dapat Anda gunakan untuk memaksa error pengujian.

    Anda dapat menggunakan kode berikut di MainActivity aplikasi untuk menambahkan tombol ke aplikasi Anda yang, jika ditekan, akan menyebabkan error. Tombol tersebut diberi label "Test Crash".

    KotlinJava
    val crashButton = Button(this)
    crashButton.text = "Test Crash"
    crashButton.setOnClickListener {
       throw RuntimeException("Test Crash") // Force a crash
    }
    
    addContentView(crashButton, ViewGroup.LayoutParams(
           ViewGroup.LayoutParams.MATCH_PARENT,
           ViewGroup.LayoutParams.WRAP_CONTENT))
    Button crashButton = new Button(this);
    crashButton.setText("Test Crash");
    crashButton.setOnClickListener(new View.OnClickListener() {
       public void onClick(View view) {
           throw new RuntimeException("Test Crash"); // Force a crash
       }
    });
    
    addContentView(crashButton, new ViewGroup.LayoutParams(
           ViewGroup.LayoutParams.MATCH_PARENT,
           ViewGroup.LayoutParams.WRAP_CONTENT));
  2. Bangun dan jalankan aplikasi Anda.

  3. Paksa error pengujian untuk mengirimkan laporan error pertama aplikasi:

    1. Buka aplikasi dari emulator atau perangkat pengujian.

    2. Di aplikasi Anda, tekan tombol "Test Crash" yang telah ditambahkan menggunakan kode di atas.

    3. Setelah aplikasi Anda mengalami error, mulai ulang aplikasi agar dapat mengirimkan laporan error ke Firebase.

  4. Buka dasbor Crashlytics di Firebase console untuk melihat error pengujian Anda.

    Jika Anda sudah me-refresh konsol dan masih tidak melihat error pengujian setelah lima menit, aktifkan logging debug untuk melihat apakah aplikasi Anda mengirim laporan error atau tidak.


Dan selesai! Crashlytics kini akan memantau aplikasi Anda untuk menemukan error, dan Anda dapat melihat serta menyelidiki laporan error dan statistik error di dasbor Crashlytics.

Langkah berikutnya

  • (Direkomendasikan) Dapatkan bantuan terkait proses debug error yang disebabkan oleh error memori native dengan mengumpulkan laporan GWP-ASan. Error terkait memori ini dapat dikaitkan dengan kerusakan memori dalam aplikasi Anda, yang merupakan penyebab utama kerentanan keamanan aplikasi. Untuk memanfaatkan fitur proses debug ini, pastikan aplikasi Anda telah mengaktifkan GWP-ASan secara eksplisit dan menggunakan Crashlytics SDK terbaru untuk NDK (v18.3.6 dan yang lebih baru atau Firebase BoM v31.3.0 dan yang lebih baru).

  • Sesuaikan penyiapan laporan kesalahan dengan menambahkan pelaporan keikutsertaan, log, kunci, dan pelacakan error non-fatal.

  • Integrasikan dengan Google Play sehingga Anda dapat memfilter laporan error aplikasi Android berdasarkan jalur Google Play secara langsung di dasbor Crashlytics. Dengan demikian, Anda dapat lebih memfokuskan dasbor pada build tertentu.

Pemecahan masalah

Jika stack trace di Firebase console dan di logcat berbeda, lihat panduan Pemecahan Masalah.



Opsi alternatif untuk mengupload simbol

Alur kerja utama yang dijelaskan di atas pada halaman ini berlaku untuk build Gradle standar. Namun, beberapa aplikasi menggunakan konfigurasi atau alat yang berbeda (misalnya proses build selain Gradle). Dalam situasi ini, opsi berikut mungkin berguna agar berhasil mengupload simbol.

Opsi: Upload simbol untuk modul library dan dependensi eksternal

Opsi ini dapat berguna dalam situasi berikut:

  • Jika Anda menggunakan proses build NDK yang disesuaikan dalam Gradle
  • Jika library native Anda dibangun dalam modul library/fitur atau disediakan oleh pihak ketiga
  • Jika tugas upload simbol otomatis gagal atau Anda melihat error yang tidak disimbolisasi di dasbor

Tugas upload simbol Crashlytics standar mengasumsikan bahwa Anda membangun library native sebagai bagian dari build Gradle modul aplikasi, menggunakan alat build NDK standar seperti CMake.

Namun, jika menggunakan proses build NDK kustom dalam Gradle, atau jika library native Anda dibangun di modul library/fitur atau disediakan oleh pihak ketiga, Anda mungkin perlu secara eksplisit menentukan jalur ke library unstripped. Caranya, Anda dapat menambahkan properti unstrippedNativeLibsDir dalam ekstensi Crashlytics dalam file build Gradle Anda.

  1. Pastikan Anda telah menyelesaikan tugas awal berikut dari alur kerja utama yang dijelaskan sebelumnya di halaman ini:

    1. Mengaktifkan Crashlytics di Firebase console.

    2. Menambahkan Crashlytics SDK untuk NDK dan plugin Gradle Crashlytics.

    3. Menambahkan ekstensi Crashlytics ke build Anda.

    4. Menyiapkan upload otomatis simbol native.

  2. Agar tugas upload simbol otomatis dapat menemukan informasi simbol, tambahkan baris berikut ke file Gradle modul (level aplikasi) (biasanya <project>/<app-module>/build.gradle.kts atau <project>/<app-module>/build.gradle):

    KotlinGroovy
    import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension
    
    // ...
    
    android {
        // ...
        buildTypes {
            release {
                configure<CrashlyticsExtension> {
                    nativeSymbolUploadEnabled = true
                    unstrippedNativeLibsDir = file("PATH/TO/UNSTRIPPED/DIRECTORY")
                }
            }
        }
    }
    // ...
    
    android {
        // ...
        buildTypes {
            release {
                firebaseCrashlytics {
                    nativeSymbolUploadEnabled true
                    unstrippedNativeLibsDir file("PATH/TO/UNSTRIPPED/DIRECTORY")
                }
            }
        }
    }

    Plugin Crashlytics akan menelusuri direktori yang ditentukan secara berulang untuk mencari library native yang memiliki ekstensi .so. Crashlytics kemudian mengekstrak simbol proses debug dari semua library tersebut dan menguploadnya ke server Firebase.

    Berikut yang dapat Anda tentukan di properti unstrippedNativeLibsDir:

    • Argumen apa pun yang diizinkan untuk org.gradle.api.Project#files(Object...), termasuk: java.lang.String, java.io.File, atau org.gradle.api.file.FileCollection

    • Beberapa direktori untuk satu ragam build dengan memberikan daftar atau instance FileCollection

    • (Mulai dengan plugin Gradle Crashlytics v3.0.0) Mengakumulasi beberapa direktori di setiap produk dan ragam build.

      buildTypes {
        release {
          configure<CrashlyticsExtension> {
            nativeSymbolUploadEnabled = true
            unstrippedNativeLibsDir = file("MY/NATIVE/LIBS")
          }
        }
        productFlavors {
          flavorDimensions += "feature"
          create("basic") {
            dimension = "feature"
            // ...
          }
          create("featureX") {
            dimension = "feature"
            configure<CrashlyticsExtension> {
              unstrippedNativeLibsDir = file("MY/FEATURE_X/LIBS")
            }
          }
        }
      }
      

    Tugas uploadCrashlyticsSymbolFilesBasicRelease hanya akan mengupload simbol di MY/NATIVE/LIBS, tetapi uploadCrashlyticsSymbolFilesFeatureXRelease akan mengupload simbol di MY/NATIVE/LIBS dan MY/FEATURE_X/LIBS.

  3. Terakhir, paksa error pengujian untuk menyelesaikan penyiapan Crashlytics dan melihat data awal di dasbor Crashlytics pada Firebase console.

Opsi: Upload simbol untuk build non-Gradle atau library native unstripped yang tidak dapat diakses

Opsi ini dapat berguna dalam situasi berikut:

  • Jika Anda menggunakan proses build selain Gradle

  • Jika library native unstripped yang disediakan untuk Anda tidak dapat diakses selama build Gradle

Opsi ini mengharuskan Anda menjalankan perintah Firebase CLI saat membuat build rilis atau build apa pun yang ingin Anda lihat stack trace tersimbolisasinya di Firebase console.

  1. Pastikan Anda telah menyelesaikan tugas awal berikut dari alur kerja utama yang dijelaskan sebelumnya di halaman ini:

    1. Mengaktifkan Crashlytics di Firebase console.

    2. Menambahkan Crashlytics SDK untuk NDK dan plugin Gradle Crashlytics.

    Perhatikan bahwa dengan opsi ini, Anda tidak perlu menambahkan ekstensi firebaseCrashlytics atau menyiapkan upload simbol otomatis karena Anda akan menggunakan Firebase CLI (langkah berikutnya di bawah) untuk membuat dan mengupload file simbol.

  2. Siapkan lingkungan dan project Anda untuk upload simbol:

    1. Ikuti petunjuk untuk menginstal Firebase CLI.

      Jika Anda sudah menginstal CLI, pastikan untuk mengupdate ke versi terbarunya.

    2. (hanya untuk aplikasi yang menggunakan Android API level 30+) Update template AndroidManifest.xml aplikasi Anda untuk menonaktifkan Pemberian Tag Pointer:

      1. Centang kotak untuk Android Player Settings > Publishing Settings > Build > Custom Main Manifest.

      2. Buka template manifes yang berada di Assets/Plugins/Android/AndroidManifest.xml.

      3. Tambahkan atribut berikut ke tag aplikasi: <application android:allowNativeHeapPointerTagging="false" ... />

  3. Bangun project Anda.

  4. Upload informasi simbol.

    Setelah build selesai, buat file simbol yang kompatibel dengan Crashlytics dan upload ke server Firebase dengan menjalankan perintah Firebase CLI berikut:

    firebase crashlytics:symbols:upload --app=FIREBASE_APP_ID PATH/TO/SYMBOLS
    • FIREBASE_APP_ID: ID Aplikasi Android Firebase Anda (bukan nama paket)
      Contoh ID Aplikasi Android Firebase: 1:567383003300:android:17104a2ced0c9b9b

      Berikut dua cara untuk menemukan ID Aplikasi Firebase:

      • Di file google-services.json, ID Aplikasi Anda adalah nilai mobilesdk_app_id; atau

      • Di Firebase console, buka Project settings. Scroll ke bawah ke kartu Your apps, lalu klik Aplikasi Firebase yang diinginkan untuk menemukan ID Aplikasi-nya.

    • PATH/TO/SYMBOLS: Jalur ke file simbol yang dihasilkan oleh CLI

      • Mengekspor ke project Android Studio — PATH/TO/SYMBOLS dapat berupa direktori apa pun. Firebase CLI akan menelusuri direktori yang ditentukan secara berulang untuk mencari library native yang memiliki ekstensi .so.

      • Membangun APK langsung dari dalam Unity — PATH/TO/SYMBOLS adalah jalur file simbol terkompresi yang dihasilkan di direktori root project saat build Anda selesai (misalnya: myproject/myapp-1.0-v100.symbols.zip).

    Flag Deskripsi
    --generator=csym

    Menggunakan generator file simbol cSYM lama, bukan generator Breakpad default

    Tidak direkomendasikan untuk digunakan. Sebaiknya gunakan generator file simbol Breakpad default.

    --generator=breakpad

    Menggunakan generator file simbol Breakpad

    Perhatikan bahwa default untuk pembuatan file simbol adalah Breakpad. Hanya gunakan flag ini jika Anda telah menambahkan symbolGenerator { csym() } dalam konfigurasi build dan ingin menggantinya untuk menggunakan Breakpad.

    --dry-run

    Membuat file simbol tetapi tidak menguploadnya

    Flag ini berguna jika Anda ingin memeriksa konten file yang dikirim.

    --debug Menyediakan informasi proses debug tambahan
  5. Terakhir, paksa error pengujian untuk menyelesaikan penyiapan Crashlytics dan melihat data awal di dasbor Crashlytics pada Firebase console.

    Setelah membangun aplikasi sebagai bagian dari pemaksaan error, pastikan untuk menjalankan perintah crashlytics:symbols:upload Firebase CLI guna mengupload file simbol Anda.