Obtenha relatórios de falhas do Android NDK

Se seu aplicativo Android contiver bibliotecas nativas , você poderá ativar rastreamentos completos de pilha e relatórios de falhas detalhados para seu código nativo no Firebase Crashlytics com algumas pequenas atualizações na configuração de compilação do seu aplicativo.

Este guia descreve como configurar relatórios de falhas com o SDK do Firebase Crashlytics para NDK.

Se você está procurando como começar a usar o Crashlytics em seus projetos do Unity, confira o guia de primeiros passos do Unity .

Antes de você começar

  1. Adicione o Firebase ao seu projeto Android, caso ainda não o tenha feito. Se você não tiver um aplicativo Android, poderá fazer download de um aplicativo de exemplo .

  2. Recomendado : para obter automaticamente registros de localização atual para entender as ações do usuário que levam a um evento de falha, não fatal ou ANR, você precisa ativar o Google Analytics em seu projeto do Firebase.

    • Se o seu projeto existente do Firebase não tiver o Google Analytics ativado, você poderá ativar o Google Analytics na guia Integrações do seu > Configurações do projeto no console do Firebase.

    • Se você estiver criando um novo projeto do Firebase, ative o Google Analytics durante o fluxo de trabalho de criação do projeto.

Etapa 1 : adicione o SDK do Crashlytics para NDK ao seu aplicativo

No arquivo Gradle do módulo (nível do aplicativo) (geralmente <project>/<app-module>/build.gradle.kts ou <project>/<app-module>/build.gradle ), adicione a dependência para o Crashlytics NDK biblioteca para Android. Recomendamos usar o Firebase Android BoM para controlar o controle de versão da biblioteca.

Para uma experiência ideal com o Crashlytics, recomendamos ativar o Google Analytics no seu projeto do Firebase e adicionar o SDK do Firebase para Google Analytics ao seu aplicativo.

dependencies {
   
// Import the BoM for the Firebase platform
    implementation
(platform("com.google.firebase:firebase-bom:32.8.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")

}

Ao usar o Firebase Android BoM , seu aplicativo sempre usará versões compatíveis das bibliotecas do Firebase Android.

Se você optar por não usar o Firebase BoM, deverá especificar cada versão da biblioteca do Firebase em sua linha de dependência.

Observe que se você usa várias bibliotecas do Firebase no seu aplicativo, é altamente recomendável usar a BoM para gerenciar as versões da biblioteca, o que garante que todas as versões sejam compatíveis.

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:18.6.3")
    implementation
("com.google.firebase:firebase-analytics:21.6.1")

}
Procurando um módulo de biblioteca específico para Kotlin? A partir de outubro de 2023 (Firebase BoM 32.5.0) , tanto os desenvolvedores Kotlin quanto os Java podem depender do módulo da biblioteca principal (para obter detalhes, consulte o FAQ sobre esta iniciativa ).

Etapa 2 : adicione o plug-in Crashlytics Gradle ao seu aplicativo

  1. Em seu arquivo Gradle de nível raiz (nível de projeto) ( <project>/build.gradle.kts ou <project>/build.gradle ), adicione o plug-in Crashlytics Gradle ao bloco plugins :

    plugins {
        id
    ("com.android.application") version "7.3.0" apply false
       
    // ...

       
    // Make sure that you have the Google services Gradle plugin dependency
        id
    ("com.google.gms.google-services") version "4.4.1" apply false

       
    // Add the dependency for the Crashlytics Gradle plugin
        id
    ("com.google.firebase.crashlytics") version "2.9.9" apply false

    }
    plugins {
        id
    'com.android.application' version '7.3.0' apply false
       
    // ...

       
    // Make sure that you have the Google services Gradle plugin dependency
        id
    'com.google.gms.google-services' version '4.4.1' apply false

       
    // Add the dependency for the Crashlytics Gradle plugin
        id
    'com.google.firebase.crashlytics' version '2.9.9' apply false

    }
  2. No arquivo Gradle do módulo (nível do aplicativo) (geralmente <project>/<app-module>/build.gradle.kts ou <project>/<app-module>/build.gradle ), adicione o plug-in Crashlytics Gradle:

    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'

    }

Etapa 3 : adicione a extensão Crashlytics à sua compilação

No arquivo Gradle do módulo (nível do aplicativo) (geralmente <project>/<app-module>/build.gradle.kts ou <project>/<app-module>/build.gradle ), configure a extensão Crashlytics.

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
         
}

     
}
 
}
}

Etapa 4 : configurar o upload automático de símbolos nativos

Para produzir rastreamentos de pilha legíveis de falhas do NDK, o Crashlytics precisa conhecer os símbolos em seus binários nativos. O plug-in Crashlytics Gradle inclui a tarefa uploadCrashlyticsSymbolFile BUILD_VARIANT para automatizar esse processo.

  1. Para que você possa acessar a tarefa de upload automatizado de símbolos, certifique-se de que nativeSymbolUploadEnabled esteja definido como true no arquivo Gradle do módulo (nível do aplicativo).

  2. Para que os nomes dos métodos apareçam nos rastreamentos de pilha, você deve invocar explicitamente a tarefa uploadCrashlyticsSymbolFile BUILD_VARIANT após cada compilação da sua biblioteca NDK. Por exemplo:

    >./gradlew app:assembleBUILD_VARIANT\
               app
    :uploadCrashlyticsSymbolFileBUILD_VARIANT
  3. Tanto o SDK do Crashlytics para NDK quanto o plug-in Crashlytics Gradle dependem da presença do ID de compilação GNU nos objetos nativos compartilhados.

    Você pode verificar a presença deste ID executando readelf -n em cada binário. Se o ID da compilação estiver ausente, adicione -Wl,--build-id aos sinalizadores do seu sistema de compilação para corrigir o problema.

Etapa 5 : forçar uma falha de teste para concluir a configuração

Para concluir a configuração do Crashlytics e ver os dados iniciais no painel do Crashlytics do console do Firebase, você precisa forçar uma falha de teste.

  1. Adicione código ao seu aplicativo que você pode usar para forçar uma falha de teste.

    Você pode usar o código a seguir na MainActivity do seu aplicativo para adicionar um botão ao seu aplicativo que, quando pressionado, causa uma falha. O botão é denominado "Test Crash".

    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. Crie e execute seu aplicativo.

  3. Force a falha do teste para enviar o primeiro relatório de falha do seu aplicativo:

    1. Abra seu aplicativo no dispositivo de teste ou emulador.

    2. No seu aplicativo, pressione o botão "Test Crash" que você adicionou usando o código acima.

    3. Depois que o aplicativo travar, reinicie-o para que ele possa enviar o relatório de falha ao Firebase.

  4. Acesse o painel do Crashlytics do console do Firebase para ver a falha do teste.

    Se você atualizou o console e ainda não vê a falha do teste após cinco minutos, habilite o registro de depuração para ver se seu aplicativo está enviando relatórios de falha.


E é isso! O Crashlytics agora está monitorando falhas no seu aplicativo, e você pode visualizar e investigar relatórios e estatísticas de falhas no painel do Crashlytics.

Próximos passos

  • (Recomendado) Obtenha ajuda para depurar falhas causadas por erros de memória nativa coletando relatórios GWP-ASan . Esses erros relacionados à memória podem estar associados à corrupção de memória do seu aplicativo, que é a principal causa de vulnerabilidades de segurança do aplicativo. Para aproveitar esse recurso de depuração, certifique-se de que seu aplicativo tenha o GWP-ASan explicitamente ativado e use o SDK Crashlytics para NDK mais recente (v18.3.6+ ou Firebase BoM v31.3.0+).

  • Personalize a configuração do seu relatório de falhas adicionando relatórios opcionais, registros, chaves e rastreamento de erros não fatais.

  • Integre-se ao Google Play para que você possa filtrar os relatórios de erros do seu aplicativo Android por faixa do Google Play diretamente no painel do Crashlytics. Isso permite que você concentre melhor seu painel em compilações específicas.

Solução de problemas

Se você estiver vendo rastreamentos de pilha diferentes no console do Firebase e no logcat, consulte o guia de solução de problemas .



Opções alternativas para upload de símbolos

O fluxo de trabalho principal nesta página acima é aplicável para compilações padrão do Gradle. No entanto, alguns aplicativos usam uma configuração ou ferramentas diferentes (por exemplo, um processo de compilação diferente do Gradle). Nessas situações, as opções a seguir podem ser úteis para carregar símbolos com êxito.

Opção : Carregar símbolos para módulos de biblioteca e dependências externas

Esta opção pode ser útil nas seguintes situações:

  • Se você usar um processo de compilação NDK personalizado no Gradle
  • Se suas bibliotecas nativas forem criadas em um módulo de biblioteca/recurso ou fornecidas por terceiros
  • Se a tarefa de upload automático de símbolos estiver falhando ou você estiver vendo falhas não simbolizadas no painel

A tarefa padrão de upload de símbolos do Crashlytics pressupõe que você esteja criando suas bibliotecas nativas como parte da compilação Gradle do módulo do seu aplicativo, usando ferramentas de compilação padrão do NDK, como o CMake.

No entanto, se você estiver usando um processo de compilação NDK personalizado no Gradle ou se suas bibliotecas nativas forem criadas em um módulo de biblioteca/recurso ou fornecidas por terceiros, talvez seja necessário especificar explicitamente o caminho para suas bibliotecas não removidas. Para fazer isso, você pode adicionar a propriedade unstrippedNativeLibsDir na extensão Crashlytics em seu arquivo de compilação do Gradle.

  1. Certifique-se de ter concluído as seguintes tarefas iniciais do fluxo de trabalho principal anteriormente nesta página:

    1. Ativado o Crashlytics no console do Firebase.

    2. Adicionados o Crashlytics SDK para NDK e o plug-in Crashlytics Gradle .

    3. Adicionada a extensão Crashlytics ao seu build.

    4. Configure o upload automático de símbolos nativos.

  2. Para que a tarefa de upload automático de símbolos possa encontrar as informações do seu símbolo, adicione o seguinte ao arquivo Gradle do módulo (nível do aplicativo) (geralmente <project>/<app-module>/build.gradle.kts ou <project>/<app-module>/build.gradle ):

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

    O plug-in Crashlytics pesquisará recursivamente no diretório especificado em busca de bibliotecas nativas com uma extensão .so . O Crashlytics então extrai símbolos de depuração de todas essas bibliotecas e os carrega nos servidores Firebase.

    Aqui está o que você pode especificar na propriedade unstrippedNativeLibsDir :

    • Qualquer argumento permitido para org.gradle.api.Project#files(Object...) , incluindo: java.lang.String , java.io.File ou org.gradle.api.file.FileCollection

    • Vários diretórios para um único tipo de compilação, fornecendo uma lista ou instância FileCollection

  3. Por fim, force uma falha de teste para concluir a configuração do Crashlytics e ver os dados iniciais no painel do Crashlytics do console do Firebase.

Opção : fazer upload de símbolos para compilações não Gradle ou bibliotecas nativas não despojadas inacessíveis

Esta opção pode ser útil nas seguintes situações:

  • Se você usar um processo de compilação diferente do Gradle

  • Se suas bibliotecas nativas não removidas forem fornecidas a você de alguma forma que não sejam acessíveis durante as compilações do Gradle

Esta opção requer que você execute um comando Firebase CLI ao criar uma versão ou qualquer compilação para a qual deseja ver rastreamentos de pilha simbolizados no console do Firebase.

  1. Certifique-se de ter concluído as seguintes tarefas iniciais do fluxo de trabalho principal anteriormente nesta página:

    1. Ativado o Crashlytics no console do Firebase.

    2. Adicionados o Crashlytics SDK para NDK e o plug-in Crashlytics Gradle .

    Observe que, com esta opção, você não precisa adicionar a extensão firebaseCrashlytics ou configurar o upload automático de símbolos porque, em vez disso, usará a CLI do Firebase (próximas etapas abaixo) para gerar e fazer upload de seus arquivos de símbolos.

  2. Configure seu ambiente e projeto para upload de símbolos:

    1. Siga as instruções para instalar a CLI do Firebase .

      Se você já instalou a CLI, atualize para a versão mais recente .

    2. (apenas para aplicativos que usam Android API nível 30+) Atualize o modelo AndroidManifest.xml do seu aplicativo para desativar a marcação de ponteiro:

      1. Marque a caixa Android Player Settings > Publishing Settings > Build > Custom Main Manifest .

      2. Abra o modelo de manifesto localizado em Assets/Plugins/Android/AndroidManifest.xml .

      3. Adicione o seguinte atributo à tag do aplicativo: <application android:allowNativeHeapPointerTagging="false" ... />

  3. Construa seu projeto.

  4. Carregue as informações dos seus símbolos.

    Assim que a compilação for concluída, gere um arquivo de símbolo compatível com Crashlytics e faça upload dele nos servidores do Firebase executando o seguinte comando Firebase CLI:

    firebase crashlytics:symbols:upload --app=FIREBASE_APP_ID PATH/TO/SYMBOLS
    • FIREBASE_APP_ID : seu ID do aplicativo Android do Firebase (não o nome do seu pacote)
      Exemplo de ID do aplicativo Android do Firebase: 1:567383003300:android:17104a2ced0c9b9b

      Aqui estão duas maneiras de encontrar seu ID do aplicativo Firebase:

      • No arquivo google-services.json , o ID do aplicativo é o valor mobilesdk_app_id ; ou

      • No console do Firebase, acesse as configurações do projeto . Role para baixo até o cartão Seus aplicativos e clique no aplicativo Firebase desejado para encontrar seu ID do aplicativo.

    • PATH/TO/SYMBOLS : O caminho para o arquivo de símbolos gerado pela CLI

      • Exportado para um projeto Android Studio — PATH/TO/SYMBOLS pode ser qualquer diretório. A CLI do Firebase pesquisará recursivamente no diretório especificado em busca de bibliotecas nativas com uma extensão .so .

      • Construído o APK diretamente do Unity — PATH/TO/SYMBOLS é o caminho do arquivo de símbolo compactado gerado no diretório raiz do projeto quando sua compilação foi concluída (por exemplo: myproject/myapp-1.0-v100.symbols.zip ).

    Bandeira Descrição
    --generator=csym

    Usa o gerador de arquivo de símbolo cSYM legado em vez do gerador Breakpad padrão

    Não recomendado para uso. Recomendamos usar o gerador de arquivo de símbolos Breakpad padrão.

    --generator=breakpad

    Usa o gerador de arquivo de símbolos Breakpad

    Observe que o padrão para geração de arquivos de símbolos é Breakpad. Use este sinalizador apenas se você adicionou symbolGenerator { csym() } em sua configuração de compilação e você deseja substituí-lo para usar o Breakpad.

    --dry-run

    Gera os arquivos de símbolos, mas não os carrega

    Este sinalizador é útil se você deseja inspecionar o conteúdo dos arquivos enviados.

    --debug Fornece informações adicionais de depuração
  5. Por fim, force uma falha de teste para concluir a configuração do Crashlytics e ver os dados iniciais no painel do Crashlytics do console do Firebase.

    Depois de criar seu aplicativo como parte do processo de forçar uma falha, execute o comando crashlytics:symbols:upload da CLI do Firebase para fazer upload do arquivo de símbolo.