Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Obtén informes de fallas del NDK de Android

Si tu app para Android contiene bibliotecas nativas, puedes habilitar los seguimientos de pila completa y los informes de fallas detallados para tu código nativo desde Firebase Crashlytics con solo hacer unas pequeñas actualizaciones en la configuración de compilación de tu app. En esta guía se describe cómo configurar los informes de fallas con el nuevo SDK de Firebase Crashlytics.

Antes de comenzar

Para comenzar, configura Crashlytics.

  1. Como parte del paso 2 (Agrega el complemento de Firebase Crashlytics a tu app), asegúrate de que tu app use la versión 2.4.0 o posterior del complemento de Crashlytics para Gradle, que te permite subir símbolos usando solo tus objetos binarios sin eliminar a fin de generar fallas simbolizadas.

Paso 1: Actualiza la configuración de Gradle

En el archivo build.gradle de nivel de la app, declara la dependencia del entorno de ejecución del NDK de Crashlytics:

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.4.1')

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

Si usas la BoM de Firebase para Android, tu app siempre utilizará versiones compatibles de las bibliotecas de Firebase para Android.

Como alternativa, puedes declarar las dependencias de la biblioteca de Firebase sin usar la BoM.

Si eliges no usar la BoM de Firebase, debes especificar cada versión de la biblioteca de Firebase en su línea de dependencia.

Ten en cuenta que, si usas varias bibliotecas de Firebase en tu app, te recomendamos que utilices la BoM para administrar las versiones de las bibliotecas, lo que garantiza que todas las versiones sean compatibles.

  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.2.1'
      implementation 'com.google.firebase:firebase-crashlytics-ndk:18.2.1'
      implementation 'com.google.firebase:firebase-analytics:19.0.1'
  }
  

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.4.1')

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

Si usas la BoM de Firebase para Android, tu app siempre utilizará versiones compatibles de las bibliotecas de Firebase para Android.

Como alternativa, puedes declarar las dependencias de la biblioteca de Firebase sin usar la BoM.

Si eliges no usar la BoM de Firebase, debes especificar cada versión de la biblioteca de Firebase en su línea de dependencia.

Ten en cuenta que, si usas varias bibliotecas de Firebase en tu app, te recomendamos que utilices la BoM para administrar las versiones de las bibliotecas, lo que garantiza que todas las versiones sean compatibles.

  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.2.1'
      implementation 'com.google.firebase:firebase-crashlytics-ndk:18.2.1'
      implementation 'com.google.firebase:firebase-analytics-ktx:19.0.1'
  }
  

Obligatorio para la versión 17.3.0 del NDK de Crashlytics: Si tu aplicación usa targetSdkLevel 30 o posterior, también debes inhabilitar la función de etiquetado de punteros en la app agregando lo siguiente a tu AndroidManifest.xml:

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

Si necesitas más información, consulta la asistencia para desarrolladores sobre punteros etiquetados.

Paso 2: Habilita la carga de símbolos nativos

Para producir seguimientos de pila legibles de las fallas del NDK, Crashlytics debe conocer los símbolos de tus objetos binarios nativos. Nuestro complemento de Gradle incluye la tarea uploadCrashlyticsSymbolFileBUILD_VARIANT a fin de automatizar este proceso (para acceder a esta tarea, asegúrate de que nativeSymbolUploadEnabled esté configurado como verdadero).

Para que los nombres de los métodos aparezcan en los seguimientos de pila, debes invocar de manera explícita la tarea uploadCrashlyticsSymbolFileBUILD_VARIANT después de cada compilación de la biblioteca del NDK. Por ejemplo:

>./gradlew app:assembleBUILD_VARIANT\
           app:uploadCrashlyticsSymbolFileBUILD_VARIANT

El NDK de Crashlytics v17.3.0 o versiones posteriores y el complemento de Gradle v2.4.1 o versiones posteriores dependen de la presencia del ID de compilación de GNU dentro de los objetos compartidos nativos. Puedes verificar la presencia de este ID ejecutando readelf -n en cada objeto binario. Si no aparece el ID de compilación, agrega -Wl,--build-id a las marcas del sistema de compilación para solucionar el problema.

Paso 3 (opcional): Sube símbolos para módulos de biblioteca y dependencias externas

Nuestra tarea de carga de símbolos supone que compilas tus bibliotecas nativas como parte de la compilación de Gradle del módulo de tu app con herramientas de compilación estándares del NDK, como CMake. Si usas un proceso de compilación personalizado del NDK en Gradle, o si tus bibliotecas nativas se compilan en un módulo de biblioteca o funciones, o si las proporciona un tercero, es posible que debas especificar de manera explícita la ruta de acceso a tus bibliotecas no eliminadas. Para ello, la extensión firebaseCrashlytics proporciona la propiedad unstrippedNativeLibsDir.

Agrega lo siguiente al archivo build.gradle a nivel de la app:

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

El complemento de Crashlytics buscará bibliotecas nativas con una extensión .so en el directorio especificado y en todos sus subdirectorios. Crashlytics extraerá símbolos de depuración de todas esas bibliotecas y los subirá a los servidores de Firebase.

La propiedad unstrippedNativeLibsDir acepta todos los argumentos que se admiten para org.gradle.api.Project#files(Object...), incluidos java.lang.String, java.io.File y org.gradle.api.file.FileCollection. Puedes especificar varios directorios para una sola variante de compilación proporcionando una lista o una instancia de FileCollection.

Paso 4 (opcional): Personaliza los informes de fallas del NDK

De manera opcional, puedes incluir el encabezado crashlytics.h en tu código de C++ para agregar metadatos a los informes de fallas del NDK, como registros, ID de usuarios y claves personalizadas. crashlytics.h está disponible como una biblioteca C++ de solo encabezado en el repositorio de GitHub del SDK de Firebase Android. Lee los comentarios del archivo de encabezado para obtener instrucciones sobre el uso de las API de C++ del NDK.

Paso 5 (opcional): Habilita el archivo de símbolos de Breakpad para la simbolización

El complemento de Gradle para Crashlytics proporciona las siguientes funcionalidades:

  • Procesa tus objetos binarios nativos no eliminados para generar archivos de símbolos.
  • Sube los archivos de símbolos generados a nuestros servidores para usarlos más adelante cuando se realice la simbolización de las fallas por errores en el código nativo.

El complemento de Gradle de Crashlytics admite dos tipos de formatos de archivo de símbolos:
el archivo de símbolos de Crashlytics (cSYM) y el archivo de símbolos de Breakpad.

Un archivo de símbolos generado por Breakpad contiene más datos que uno creado por Crashlytics, incluida la información de marco de llamada (CFI) que se usa en el proceso de liberación para calcular los marcos de pila. Usar la CFI generará seguimientos de pila de mayor calidad, sobre todo para aplicaciones altamente optimizadas, como juegos y apps multimedia.

Puedes habilitar el generador de archivos de símbolos basado en Breakpad de dos maneras:

  • Opción 1: Habilítalo con la extensión firebaseCrashlytics en tu archivo build.gradle.

    Agrega lo siguiente al archivo build.gradle a nivel de la app:

    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()
            }
          }
        }
      }
    }
    

    Si deseas volver al generador de archivos de símbolos predeterminado de Crashlytics, puedes realizar una de las siguientes acciones:

    • Omite el bloque symbolGenerator por completo, ya que el complemento usa el generador de archivos de símbolos de Crashlytics de forma predeterminada.

    • Conserva el bloque, pero cambia breakpad() a csym().

  • Opción 2: Habilítalo con una línea de propiedad en tu archivo de propiedades de Gradle.

    Puedes usar la propiedad com.google.firebase.crashlytics.symbolGenerator para controlar qué generador de archivos de símbolos usar. Los valores válidos para la propiedad son breakpad o csym. Si no se especifica, el valor predeterminado actual será equivalente a csym, aunque eso podría cambiar en versiones futuras.

    Puedes actualizar manualmente el archivo de propiedades de Gradle o hacerlo con la línea de comandos. Por ejemplo, para habilitar el generador de archivos de símbolos de Breakpad, especifica el valor de breakpad, como se muestra en el siguiente comando:

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

Paso 6: Consulta tus informes de fallas

Verifica que Crashlytics informe adecuadamente las fallas del NDK. Para ello, compila tu app, sube los símbolos y fuerza una falla por error en código nativo. Deberás reiniciar la app después de la falla a fin de que Crashlytics envíe el informe. En pocos minutos, la falla debería aparecer en Firebase console.

Soluciona problemas

Si ves diferentes seguimientos de pila en Firebase console y en logcat, consulta la guía para solucionar problemas.