Déboguer les erreurs ANR

La résolution des 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 (un partenaire certifié Unity) fournissent une journalisation et une analyse des erreurs pour votre jeu à grande échelle. Intégrez les SDK des services de création de rapports dans votre jeu dès le début du cycle de développement. Analysez le service de création de rapports qui correspond le mieux aux besoins et au budget de votre jeu.

Les méthodes de capture des erreurs ANR varient selon les services de création de rapports. Incluez un deuxième service de création de rapports pour augmenter vos chances d'obtenir des données valides pour appuyer votre décision de corriger les erreurs ANR.

L'intégration de SDK de création de rapports n'a aucune incidence sur les performances du jeu 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 la section Décoder les plantages et ANR Android pour les jeux Unity.

Figure 2 : Crashlytics affichant l'ID de build et les symboles libil2cpp.so manquants

Vérifier l'ID de build des symboles

Si le système de création de rapports affiche l'ID de compilation manquant, mais que les symboles de compilation existent toujours dans l'espace de stockage de la machine de compilation, il est possible de vérifier l'ID de compilation de ces symboles, puis de 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 section Résolution) :
    1. Exécutez la commande suivante (sous Windows, utilisez Cygwin pour exécuter l'utilitaire readelf) :
    2. L'utilisation de Grep est facultative pour filtrer le texte de sortie
    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 votre code de jeu, mais aussi des plug-ins et des packages.

Le nom de fichier C++ suit le nom d'assembly défini dans le projet Unity. Sinon, le nom de fichier porte le nom Assembly-C# par défaut. Par exemple, la figure 3 montre l'erreur sur le fichier Game.cpp (en surbrillance en bleu), qui est le nom défini dans le fichier de définition de l'assembly. Logger est le nom de la classe (en rouge) dans le script C#, suivi du nom de la fonction (en vert). Enfin, il s'agit du nom complet généré par le convertisseur IL2CPP (surligné en orange).

Figure 3. Testez la pile d'appel de projet à partir de Backtrace.

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

  • Recherchez tout code suspect dans le projet C#. En règle générale, les exceptions non gérées en C# ne provoquent pas d'ANR ni de plantage de l'application. Néanmoins, assurez-vous 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. Un accès complet au code source C# converti de votre jeu vous permet d'identifier la fonction à l'origine de l'erreur ANR. Le code C++ est très différent du code C#, et la conversion du code pose rarement un 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 a un délai d'inactivité 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 Unity Profiler pour analyser les performances du jeu. Le profilage de votre application peut également être un excellent moyen d'identifier les goulots d'étranglement qui peuvent être à l'origine de l'erreur ANR.
  • Un excellent moyen d'identifier les opérations d'E/S longues sur le thread principal consiste à utiliser le mode strict.
  • Analysez l'historique d'Android Vitals ou 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 apportées au code entre les versions. Si vous trouvez quelque chose de suspect, testez chaque modification ou solution potentielle individuellement.
  • Examinez l'historique des rapports ANR Google Play pour les appareils et les versions d'Android qui reçoivent le plus d'erreurs ANR. Si les appareils ou les versions sont obsolètes, il est probable que vous puissiez les ignorer en toute sécurité si cela n'a pas d'incidence sur la rentabilité du jeu. Étudiez attentivement les données, car un groupe d'utilisateurs spécifique 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 pas de code susceptible de causer un problème. Par exemple, finish peut être destructeur s'il n'est pas utilisé correctement. Consultez les guides du développeur Android pour en savoir plus sur le développement Android.
  • Après avoir examiné les données et exporté le build du jeu vers Android Studio, vous traitez du code C et C++. Vous pouvez ainsi tirer pleinement parti d'outils allant au-delà des solutions standards d'Unity, tels que le Profileur de mémoire Android, le Profileur de processeur Android et perfetto.

Code de moteur Unity

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

  • Commencez par effectuer une recherche dans les chaînes de la communauté (Forums Unity, Discussions Unity et Stack Overflow).
  • Si vous n'obtenez aucun résultat, signalez un bug pour résoudre le problème. Fournissez une trace de pile décodée afin que les ingénieurs du moteur puissent mieux comprendre et résoudre l'erreur.
  • Vérifiez si la dernière version de Unity LTS a apporté des améliorations liées à vos problèmes. Si c'est le cas, mettez à jour votre jeu pour utiliser cette version. (Cette solution n'est possible que pour certains développeurs.)
  • Si votre code utilise une Activity personnalisée au lieu de la valeur 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'aucun rapport de plantage ou d'ANR n'a été signalé 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 secours a été fournie par Unity ou un membre de la communauté.
  • Consultez le rapport ANR de Google Play et assurez-vous que l'erreur n'a pas déjà été identifiée par Google. Google a connaissance de certaines erreurs ANR et met tout en œuvre pour les corriger.

Bibliothèque système

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

Motifs de sortie

ApplicationExitInfo est une API Android permettant 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 afin d'activer les appels ApplicationExitInfo depuis 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.