Cómo depurar errores de ANR

Resolver ANR en tu juego de Unity es un proceso sistemático:

Figura 1: Pasos para resolver errores de ANR en los juegos de Unity.

Integra servicios de informes

Los servicios de informes como Android vitals, Firebase Crashlytics y Backtrace (un socio certificado de Unity) proporcionan registros y análisis de errores para tu juego a gran escala. Integra los SDKs de servicios de informes en tu juego al principio del ciclo de desarrollo. Analiza qué servicio de informes se adapta mejor a las necesidades y el presupuesto de tu juego.

Los diferentes servicios de informes tienen diferentes formas de capturar los errores de ANR. Incluye un segundo servicio de informes para aumentar la probabilidad de obtener datos válidos que respalden tu decisión de corregir los errores de ANR.

La integración de SDKs de informes no afecta el rendimiento del juego ni el tamaño del APK.

Analizar símbolos

Analiza los informes desde tu servicio de informes y verifica si los seguimientos de pila están en un formato legible por humanos. Consulta Simboliza fallas de Android y ANR para juegos de Unity a fin de obtener más información.

Figura 2: Crashlytics muestra el ID de compilación y los símbolos libil2cpp.so faltantes.

Cómo verificar el ID de compilación de símbolos

Si el sistema de informes muestra el ID de compilación faltante, pero los símbolos de compilación aún existen en el almacenamiento de la máquina de compilación, es posible verificar el ID de compilación de los símbolos y, luego, subirlos al servicio de informes. De lo contrario, se requiere una compilación nueva para subir los archivos de símbolos.

En Windows o macOS:

  1. Navega a la carpeta de símbolos en función de tu backend de secuencias de comandos (consulta Resolución:)
    1. Usa el siguiente comando (en Windows, usa Cygwin para ejecutar la utilidad readelf):
    2. El uso de grep es opcional para filtrar la salida de texto
    3. Busca el ID de compilación
readelf -n libil2cpp.so | grep 'Build ID'
Build ID: b42473fb7449e44e0182dd1f580c99bab0cd8a95

Cómo inspeccionar el código de juego

Cuando el seguimiento de pila muestra una función en la biblioteca libil2cpp.so, el error ocurrió en el código C#, que se convirtió a C++. La biblioteca libil2cpp.so no solo tiene el código de tu juego, sino también complementos y paquetes.

El nombre de archivo de C++ sigue el nombre del ensamblaje definido en el proyecto de Unity. De lo contrario, el nombre de archivo tiene el nombre predeterminado Assembly-C#. Por ejemplo, en la figura 3, se muestra el error en el archivo Game.cpp (destacado en azul), que es el nombre definido en el archivo de definición de ensamblaje. Logger es el nombre de la clase (destacado en rojo) en la secuencia de comandos C#, seguido del nombre de la función (destacado en verde). Por último, se incluye el nombre completo que generó el conversor IL2CPP (destacado en naranja).

Figura 3: Prueba la pila de llamadas del proyecto desde Backtrace.

Para inspeccionar el código de tu juego, haz lo siguiente:

  • Examina el proyecto de C# para buscar código sospechoso. Por lo general, las excepciones no controladas de C# no causan un error de ANR ni una falla de la aplicación. Aun así, asegúrate de que el código se ejecute correctamente en diferentes situaciones. Verifica si el código usa un módulo de motor de terceros y analiza si una versión reciente introdujo el error. Además, revisa si actualizaste Unity recientemente o si el error solo ocurre en dispositivos específicos.
  • Exporta el juego como un proyecto de Android Studio. Con acceso completo al código fuente C# convertido de tu juego, puedes encontrar la función que causa el error de ANR. El código de C++ es muy diferente al código de C#, y la conversión de código rara vez tiene un problema. Si encuentras algo, envía un ticket de asistencia a Unity.
  • Revisa el código fuente del juego y asegúrate de que se limpie correctamente cualquier lógica que se ejecute en las devoluciones de llamada OnApplicationFocus() y OnApplicationPause().
    • El motor de Unity tiene un tiempo de espera para pausar su ejecución. Las cargas de trabajo excesivas en estas devoluciones de llamada pueden causar un error de ANR.
    • Agrega registros o rutas de navegación a partes del código para mejorar tu análisis de datos.
  • Usa el Generador de perfiles de Unity para investigar el rendimiento del juego. Crear perfiles de tu app también puede ser una excelente manera de identificar cuellos de botella que podrían estar causando el error de ANR.
  • Una excelente manera de identificar las operaciones de E/S largas en el subproceso principal es usar el modo estricto.
  • Analiza Android vitals o algún otro historial del servicio de informes y verifica las versiones de actualización del juego en las que más ocurre el error. Revisa tu código fuente en tu historial de control de versiones y compara los cambios de código entre las versiones. Si encuentras algo sospechoso, experimenta con cada cambio o posible solución de forma individual.
  • Examina el historial de informes de ANR de Google Play para los dispositivos y las versiones de Android que reciben la mayor cantidad de ANR. Si los dispositivos o las versiones están desactualizados, lo más probable es que puedas ignorarlos de forma segura si hacerlo no afecta la rentabilidad del juego. Estudia los datos con cuidado, ya que un grupo de usuarios en particular ya no podrá jugar. Para obtener más información, consulta el panel de distribución.
  • Revisa el código fuente del juego para asegurarte de no llamar a ningún código que pueda causar un problema, por ejemplo, finish puede ser destructivo si no se usa correctamente. Si quieres obtener más información sobre el desarrollo de Android, consulta las guías para desarrolladores de Android.
  • Después de revisar los datos y exportar la compilación del juego a Android Studio, trabajarás con el código C y C++, de modo que puedas aprovechar al máximo las herramientas más allá de las soluciones estándar de Unity, como el Generador de perfiles de memoria de Android, el Generador de perfiles de CPU de Android y perfetto.

Código de motor de Unity

Para saber si se produce un error de ANR en el motor de Unity, busca libUnity.so o libMain.so en los seguimientos de pila. Si los encuentras, sigue estos pasos:

  • Primero, busca en los canales de la comunidad (Foros de Unity, Debates de Unity y Stackoverflow).
  • Si no encuentras nada, informa un error para resolver el problema. Proporciona un seguimiento de pila simbolizado para que los ingenieros del motor puedan comprender mejor y resolver el error.
  • Consulta si la versión más reciente de Unity LTS incluye mejoras relacionadas con tus problemas. Si es así, actualiza el juego para usar esa versión. (esta solución solo puede ser posible para algunos desarrolladores).
  • Si tu código usa un Activity personalizado en lugar del predeterminado, revisa el código Java para asegurarte de que la actividad no cause problemas.

SDK de terceros

  • Verifica que todas las bibliotecas de terceros estén actualizadas y no tengan informes de fallas o errores de ANR de la versión más reciente de Android.
  • Visita los foros de Unity para ver si se resolvieron algunos errores en una versión posterior o si Unity o un miembro de la comunidad proporcionaron una solución alternativa.
  • Revisa el informe de ANR de Google Play y asegúrate de que Google no haya identificado el error. Google está al tanto de algunos errores de ANR y está trabajando activamente para solucionarlos.

Biblioteca del sistema

Por lo general, las bibliotecas del sistema están lejos del control del desarrollador, pero no representan un porcentaje significativo de errores de ANR. Además de comunicarte con el desarrollador de la biblioteca o agregar registros para limitar el problema, los errores de ANR de la biblioteca del sistema son difíciles de resolver.

Motivos de salida

ApplicationExitInfo es una API de Android para comprender las causas de los errores de ANR. Si tu juego usa Unity 6 o versiones posteriores, puedes llamar directamente a ApplicationExitInfo. En las versiones anteriores de Unity, debes implementar tu propio complemento para habilitar las llamadas a ApplicationExitInfo desde Unity.

Crashlytics también usa ApplicationExitInfo. Sin embargo, tu propia implementación te brinda un control más preciso y te permite incluir información más relevante.