Déboguer les erreurs ANR

La résolution des erreurs ANR dans votre jeu Unity est un processus systématique:

Figure 1. Procédure à suivre pour résoudre les erreurs ANR dans les jeux Unity.

Intégrer des services de création de rapports

Les services de création de rapports tels que Android Vitals, Firebase Crashlytics et Backtrace (partenaire Unity certifié) fournissent la journalisation et l'analyse des erreurs pour votre jeu à grande échelle. Intégrez les SDK de services de création de rapports à votre jeu dès le début du cycle de développement. Analysez le service de création de rapports qui répond le mieux aux besoins et au budget de votre jeu.

Les différents services de création de rapports ont des méthodes différentes pour capturer les erreurs ANR. Incluez un deuxième service de création de rapports pour augmenter vos chances d'obtenir des données valides qui vous aideront à prendre une décision pour résoudre les erreurs ANR.

L'intégration de SDK de création de rapports n'a aucune incidence sur les performances des jeux ni sur la taille de l'APK.

Analyser les symboles

Analysez les rapports de votre service de création de rapports et vérifiez si les traces de la pile sont dans un format lisible. Pour en savoir plus, consultez Décoder les plantages Android et les erreurs ANR pour les jeux Unity.

Figure 2. Crashlytics affiche l'ID de compilation et les symboles libil2cpp.so manquants.

Vérifier l'ID de build du symbole

Si le système de création de rapports affiche l'ID de compilation manquant, mais que les symboles de compilation existent toujours dans le stockage de la machine de compilation, vous pouvez vérifier l'ID de compilation des symboles, puis les importer dans le service de création de rapports. Sinon, une nouvelle compilation est nécessaire pour importer les fichiers de symboles.

Sous Windows ou macOS:

  1. Accédez au dossier des symboles en fonction de votre backend de script (voir la résolution:)
    1. Utilisez la commande suivante (sous Windows, utilisez Cygwin pour exécuter l'utilitaire readelf).
    2. L'utilisation de Grep est facultative pour filtrer la sortie textuelle
    3. Rechercher l'ID de build
readelf -n libil2cpp.so | grep 'Build ID'
Build ID: b42473fb7449e44e0182dd1f580c99bab0cd8a95

Inspecter le code du jeu

Lorsque la trace de la pile affiche une fonction dans la bibliothèque libil2cpp.so, l'erreur s'est produite dans le code C#, qui est converti en C++. La bibliothèque libil2cpp.so contient non seulement le code de votre jeu, mais aussi des plug-ins et des packages.

Le nom de fichier C++ suit le nom de l'assembly défini dans le projet Unity. Sinon, le nom de fichier est celui par défaut de l'assembly C#. Par exemple, la figure 3 montre l'erreur dans le fichier Game.cpp (en bleu), qui est le nom défini dans le fichier de définition de l'assembly. Logger correspond au nom de la classe (en rouge) dans le script C#, suivi du nom de la fonction (en vert). "Finally" est le nom complet généré par le convertisseur IL2CPP (en surbrillance en orange).

Figure 3. Pile d'appels du projet de test à partir de Backtrace.

Inspectez le code de votre jeu en procédant comme suit:

  • Recherchez d'éventuels codes suspects dans le projet C#. En règle générale, les exceptions non gérées C# ne provoquent pas d'erreur ANR ni de plantage de l'application. Assurez-vous toutefois que le code s'exécute correctement dans différentes situations. Vérifiez si le code utilise un module de moteur tiers et analysez si une version récente a introduit l'erreur. Vérifiez également si vous avez récemment mis à jour Unity ou si l'erreur ne se produit que sur des appareils spécifiques.
  • Exportez le jeu en tant que projet Android Studio. Avec un accès complet au code source C# converti de votre jeu, vous pouvez trouver la fonction à l'origine de l'erreur ANR. Le code C++ est très différent de votre code C#, et la conversion de code pose rarement problème. Si vous trouvez quelque chose, envoyez une demande d'assistance à Unity.
  • Examinez le code source du jeu et assurez-vous que toute logique exécutée dans les rappels OnApplicationFocus() et OnApplicationPause() est correctement nettoyée.
    • Le moteur Unity dispose d'un délai avant expiration pour suspendre son exécution. Une charge de travail excessive sur ces rappels peut entraîner une erreur ANR.
    • Ajoutez des journaux ou des fils d'Ariane à certaines parties du code pour améliorer votre analyse de données.
  • Utilisez le profileur Unity pour examiner les performances du jeu. Le profilage de votre application peut également être un excellent moyen d'identifier les goulots d'étranglement susceptibles d'être à l'origine des erreurs ANR.
  • Un excellent moyen d'identifier les longues opérations d'E/S sur le thread principal consiste à utiliser le mode strict.
  • Analysez Android Vitals ou l'historique d'un autre service de création de rapports, et vérifiez les versions du jeu pour lesquelles l'erreur se produit le plus. Examinez votre code source dans l'historique de contrôle des versions et comparez les modifications de code entre les versions. Si vous trouvez quelque chose de suspect, testez chaque modification ou solution potentielle individuellement.
  • Examinez l'historique des rapports d'erreurs ANR Google Play pour les appareils et les versions Android qui en reçoivent le plus. Si les appareils ou les versions sont obsolètes, vous pouvez probablement les ignorer sans risque si cela n'a pas d'impact sur la rentabilité du jeu. Examinez attentivement les données, car un groupe d'utilisateurs particulier ne pourra plus jouer à votre jeu. Pour en savoir plus, consultez le tableau de bord de distribution.
  • Examinez le code source du jeu pour vous assurer que vous n'appelez aucun code susceptible de provoquer un problème. Par exemple, finish peut être destructeur si vous n'êtes pas utilisé correctement. Pour en savoir plus sur le développement Android, consultez les guides du développeur Android.
  • Après avoir examiné les données et exporté le build du jeu vers Android Studio, vous travaillez sur du code C et C++. Vous pouvez donc exploiter pleinement les outils au-delà des solutions standards d'Unity, tels que Android Memory Profiler, Android CPU Profiler et perfetto.

Code du moteur Unity

Pour savoir si un ANR se produit côté moteur Unity, recherchez libUnity.so ou libMain.so dans les traces de la pile. Si vous les trouvez, procédez comme suit:

  • Commencez par rechercher dans les canaux de la communauté (forums Unity, discussions Unity, Stackoverflow).
  • Si vous ne trouvez rien, signalez un bug pour résoudre le problème. Fournissez une trace de pile symbolisée afin que les ingénieurs du moteur puissent mieux comprendre et résoudre l'erreur.
  • Vérifiez si la dernière version d'Unity LTS a apporté des améliorations liées à vos problèmes. Si c'est le cas, mettez à niveau votre jeu pour utiliser cette version. (Cette solution n'est peut-être possible que pour certains développeurs.)
  • Si votre code utilise un Activity personnalisé au lieu du code par défaut, examinez le code Java pour vous assurer que l'activité ne cause aucun problème.

SDK tiers

  • Vérifiez que toutes les bibliothèques tierces sont à jour et qu'elles ne signalent pas de plantages ni d'erreurs ANR pour la dernière version d'Android.
  • Accédez aux forums Unity pour voir si des erreurs ont déjà été résolues dans une version ultérieure, ou si une solution de contournement a été proposée par Unity ou un membre de la communauté.
  • Consultez le rapport sur les erreurs ANR de Google Play et assurez-vous que l'erreur n'a pas déjà été identifiée par Google. Google est au courant de certaines erreurs ANR et travaille activement à leur résolution.

Bibliothèque système

Les bibliothèques système sont généralement hors du contrôle du développeur, mais elles ne représentent pas un pourcentage important d'erreurs ANR. En dehors de contacter le développeur de la bibliothèque ou d'ajouter des journaux pour affiner le problème, les erreurs ANR de la bibliothèque système sont difficiles à résoudre.

Motifs de sortie

ApplicationExitInfo est une API Android qui permet de comprendre les causes des erreurs ANR. Si votre jeu utilise Unity 6 ou une version ultérieure, vous pouvez appeler ApplicationExitInfo directement. Pour les anciennes versions d'Unity, vous devez implémenter votre propre plug-in pour activer les appels ApplicationExitInfo à partir d'Unity.

Crashlytics utilise également ApplicationExitInfo. Cependant, votre propre implémentation vous offre un contrôle plus précis et vous permet d'inclure des informations plus pertinentes.