Cómo depurar errores de ANR

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

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

Cómo integrar servicios de informes

Los servicios de informes, como Android vitals, Firebase Crashlytics y Backtrace (un socio certificado de Unity), proporcionan registro y análisis de errores para tu juego a gran escala. Integra los SDK de servicios de informes en tu juego al principio del ciclo de desarrollo. Analiza cuál es el servicio de informes que mejor se ajusta a las necesidades y el presupuesto de tu juego.

Los diferentes servicios de informes tienen diferentes formas de capturar errores de ANR. Incluye un segundo servicio de informes para aumentar las probabilidades 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.

Cómo analizar símbolos

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

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

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, haz lo siguiente:

  1. Navega a la carpeta de símbolos según tu backend de secuencias de comandos (consulta la solución:)
    1. Usa el siguiente comando (en Windows, usa Cygwin para ejecutar la utilidad readelf).
    2. El uso de Grep es opcional para filtrar el resultado 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 del 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 los complementos y paquetes.

El nombre del archivo C++ sigue el nombre del ensamblado definido en el proyecto de Unity. De lo contrario, el nombre del archivo tiene el nombre predeterminado de 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 ensamblado. Logger es el nombre de la clase (destacado en rojo) en la secuencia de comandos de C#, seguido del nombre de la función (destacado en verde). Por último, se encuentra el nombre completo que generó el conversor de 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# en busca de 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 arrojó 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 convertido en C# de tu juego, puedes encontrar la función que causa el error de ANR. El código C++ se ve muy diferente al código 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 borre 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. Una carga de trabajo excesiva en estas devoluciones de llamada puede 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. Generar perfiles de tu app también puede ser una excelente manera de ayudar a identificar los cuellos de botella que podrían estar causando el error de ANR.
  • Una excelente manera de identificar operaciones de E/S largas en el subproceso principal es usar el modo estricto.
  • Analiza Android Vitals o el historial de otro servicio de informes y verifica las versiones de lanzamiento del juego en las que ocurre el error con más frecuencia. Revisa el código fuente en el historial de control de versión y compara los cambios de código entre las versiones. Si encuentras algo sospechoso, experimenta con cada cambio o posible solución por separado.
  • 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, es probable 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 tu juego. 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 pudiera causar un problema. Por ejemplo, finish puede ser destructivo si no se usa correctamente. Consulta las guías para desarrolladores de Android para obtener más información sobre el desarrollo de Android.
  • Después de revisar los datos y exportar la compilación del juego a Android Studio, estarás trabajando con código C y C++, por lo que podrás 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 del 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, Unity Discussions, Stackoverflow).
  • Si no encuentras nada, informa un error para resolver el problema. Proporciona un seguimiento de pila simbólica para que los ingenieros del motor puedan comprender y resolver mejor el error.
  • Verifica si la LTS más reciente de Unity realizó mejoras relacionadas con tus problemas. Si es así, actualiza tu jogo para usar esa versión. (Es posible que esta solución solo sea 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 ningún problema.

SDK de terceros

  • Comprueba que todas las bibliotecas de terceros estén actualizadas y no tengan informes de fallas ni errores de ANR para la versión más reciente de Android.
  • Ve a 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 ya 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 acotar 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 una versión posterior, puedes llamar a ApplicationExitInfo directamente. 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 ofrece un control más preciso y te permite incluir información más relevante.