Depurar ANRs

Resolver ANRs no seu jogo do Unity é um processo sistemático:

Figura 1. Etapas para resolver ANRs em jogos do Unity.

Integrar serviços de relatórios

Serviços de relatórios, como o Android vitals, o Firebase Crashlytics e o Backtrace (um parceiro certificado do Unity ), fornecem registro e análise de erros para seu jogo em grande escala. Integre os SDKs de serviços de relatórios ao seu jogo no início do ciclo de desenvolvimento. Analise qual serviço de relatórios melhor se adapta às necessidades e ao orçamento do seu jogo.

Diferentes serviços de relatórios têm maneiras diferentes de capturar ANRs. Inclua um segundo serviço de relatórios para aumentar a chance de obter dados válidos para apoiar sua decisão na correção de ANRs.

A integração de SDKs de relatórios não afeta o desempenho do jogo nem o tamanho do APK.

Analisar símbolos

Analise os relatórios do serviço de relatórios e verifique se os stack traces estão em formato legível. Consulte Simbolizar falhas do Android e o erro ANR para jogos Unity para mais informações.

Figura 2. O Crashlytics mostra o ID do build e os símbolos libil2cpp.so ausentes.

Como verificar o ID do build do símbolo

Se o sistema de relatórios mostrar o ID do build ausente, mas os símbolos do build ainda existirem no armazenamento da máquina de build, será possível verificar o ID do build dos símbolos e fazer o upload deles para o serviço de relatórios. Caso contrário, um novo build será necessário para fazer o upload dos arquivos de símbolos.

No Windows ou macOS:

  1. Navegue até a pasta de símbolos com base no seu scripting backend (consulte Resolução:)
    1. Use o comando a seguir (no Windows, use Cygwin para executar o readelf utilitário)
    2. O uso de grep é opcional para filtrar a saída de texto
    3. Procure o ID do build
readelf -n libil2cpp.so | grep 'Build ID'
Build ID: b42473fb7449e44e0182dd1f580c99bab0cd8a95

Inspecionar o código do jogo

Quando o stack trace mostra uma função na biblioteca libil2cpp.so, o erro aconteceu no código C#, que é convertido para C++. A biblioteca libil2cpp.so tem não apenas o código do jogo, mas também plug-ins e pacotes.

O nome do arquivo C++ segue o nome do assembly definido no projeto do Unity. Caso contrário, o nome do arquivo tem o nome padrão Assembly-C#. Por exemplo, a Figura 3 mostra o erro no arquivo Game.cpp (destacado em azul), que é o nome definido no arquivo de definição do assembly. Logger é o nome da classe (destacado em vermelho) no script C#, seguido pelo nome da função (destacado em verde). Por fim, está o nome completo que o conversor IL2CPP gerou (destacado em laranja).

Figura 3. Pilha de chamadas do projeto de teste do Backtrace.

Para inspecionar o código do jogo, faça o seguinte:

  • Examine o projeto C# em busca de códigos suspeitos. Normalmente, exceções não processadas em C# não causam um ANR ou falha do aplicativo. Mesmo assim, verifique se o código é executado corretamente em diferentes situações. Verifique se o código usa um módulo de mecanismo de terceiros e analise se uma versão recente introduziu o erro. Além disso, verifique se você atualizou o Unity recentemente ou se o erro só acontece em dispositivos específicos.
  • Exporte o jogo como um projeto do Android Studio. Com acesso completo ao código-fonte C# convertido do jogo, você pode encontrar a função que está causando o ANR. O código C++ é muito diferente do código C#, e a conversão de código raramente tem um problema. Se você encontrar algo, registre um tíquete de suporte para o Unity.
  • Revise o código-fonte do jogo e verifique se toda a lógica em execução nos OnApplicationFocus() e OnApplicationPause() callbacks foi limpa adequadamente.
    • O mecanismo do Unity tem um tempo limite para pausar a execução. Uma carga de trabalho excessiva nesses callbacks pode causar um ANR.
    • Adicione registros ou breadcrumbs a partes do código para melhorar a análise de dados.
  • Use o Unity Profiler para investigar o desempenho do jogo. A criação de perfil do app também pode ser uma ótima maneira de ajudar a identificar gargalos que podem estar causando o ANR.
  • Uma ótima maneira de identificar operações de E/S longas na linha de execução principal é usar o modo restrito.
  • Analise o histórico do Android vitals ou de outro serviço de relatórios e verifique as versões de lançamento do jogo em que o erro ocorre com mais frequência. Revise o código-fonte no histórico de controle de versões e compare as mudanças de código entre as versões. Se você encontrar algo suspeito, experimente cada mudança ou possível correção individualmente.
  • Examine o histórico de relatórios de ANR do Google Play para os dispositivos e versões do Android que recebem mais ANRs. Se os dispositivos ou versões estiverem desatualizados, é provável que você possa ignorá-los com segurança se isso não afetar a lucratividade do jogo. Estude os dados com cuidado, já que um grupo específico de usuários não poderá mais jogar. Para mais informações, consulte Painel de distribuição.
  • Revise o código-fonte do jogo para garantir que você não esteja chamando nenhum código que possa causar um problema. Por exemplo, o finish pode ser destrutivo se não for usado corretamente. Consulte os guias para desenvolvedores Android para saber mais sobre o desenvolvimento do Android.
  • Depois de revisar os dados e exportar o build do jogo para o Android Studio, você estará lidando com código C e C++. Assim, poderá aproveitar ao máximo as ferramentas além das soluções padrão do Unity, como Android Memory Profiler, Android CPU Profiler e perfetto.

Código do mecanismo do Unity

Para saber se um ANR está acontecendo no lado do mecanismo do Unity, verifique se há libUnity.so ou libMain.so nos stack traces. Se você os encontrar, siga estas etapas:

  • Primeiro, pesquise nos canais da comunidade (fóruns do Unity, discussões do Unity, Stackoverflow).
  • Se você não encontrar nada, registre um bug para resolver o problema. Forneça um stack trace simbolizado para que os engenheiros do mecanismo possam entender e resolver melhor o erro.
  • Verifique se a versão mais recente do Unity LTS fez melhorias relacionadas aos seus problemas. Se sim, faça o upgrade do jogo para usar essa versão. Essa solução só é possível para alguns desenvolvedores.
  • Se o código usar uma Activity personalizada em vez da padrão, revise o código Java para garantir que a atividade não esteja causando problemas.

SDK de terceiros

  • Verifique se todas as bibliotecas de terceiros estão atualizadas e não têm relatórios de falhas ou ANRs para a versão mais recente do Android.
  • Acesse os fóruns do Unity para conferir se algum erro já foi resolvido em uma versão mais recente ou se uma solução alternativa foi fornecida pelo Unity ou por um membro da comunidade.
  • Revise o relatório de ANR do Google Play e verifique se o erro já foi identificado pelo Google. O Google está ciente de alguns ANRs e está trabalhando ativamente para corrigi-los.

Biblioteca do sistema

As bibliotecas do sistema geralmente estão longe do controle do desenvolvedor, mas não representam uma porcentagem significativa de ANRs. Além de entrar em contato com o desenvolvedor da biblioteca ou adicionar registros para restringir o problema, os ANRs da biblioteca do sistema são difíceis de resolver.

Motivos de saída

ApplicationExitInfo é uma API Android para entender as causas de ANR. Se o jogo estiver usando Unity 6 ou mais recente, você poderá chamar ApplicationExitInfo diretamente. Para versões mais antigas do Unity, é necessário implementar seu próprio plug-in para ativar chamadas ApplicationExitInfo do Unity.

O Crashlytics também usa ApplicationExitInfo. No entanto, sua própria implementação oferece um controle mais refinado e permite incluir informações mais relevantes.