Отладка ошибок ANR

Решение ошибок ANR в вашей игре на Unity — это систематический процесс:

Рисунок 1. Действия по устранению ошибок ANR в играх Unity.

Интегрируйте службы отчетности

Службы отчетов, такие как Android Vitals , Firebase Crashlytics и Backtrace (сертифицированный партнер Unity), обеспечивают регистрацию ошибок и анализ вашей игры в любом масштабе. Интегрируйте SDK служб отчетов в свою игру на ранних этапах цикла разработки. Проанализируйте, какой сервис отчетов лучше всего соответствует вашим игровым потребностям и бюджету.

Различные службы отчетности используют разные способы сбора ошибок ANR. Включите вторую службу отчетов, чтобы увеличить вероятность получения достоверных данных для поддержки вашего решения по устранению ошибок ANR.

Интеграция SDK для отчетов не влияет на производительность игры или размер APK.

Анализ символов

Проанализируйте отчеты вашей службы отчетов и проверьте, находятся ли трассировки стека в удобочитаемом формате. Дополнительные сведения см. в разделе Символические сбои Android и ANR для игр Unity .

Рисунок 2. Crashlytics, показывающий идентификатор сборки и отсутствующие символы libil2cpp.so .

Как проверить идентификатор сборки символа

Если система отчетов показывает отсутствующий идентификатор сборки, но символы сборки все еще существуют в хранилище машины сборки, можно проверить идентификатор сборки символов, а затем загрузить их в службу отчетов. В противном случае для загрузки файлов символов потребуется новая сборка.

В Windows или macOS:

  1. Перейдите в папку символов в соответствии с вашим сервером сценариев (см. Решение :)
    1. Используйте следующую команду (в Windows используйте Cygwin для запуска утилиты readelf )
    2. Использование Grep не является обязательным для фильтрации текстового вывода.
    3. Найдите идентификатор сборки
readelf -n libil2cpp.so | grep 'Build ID'
Build ID: b42473fb7449e44e0182dd1f580c99bab0cd8a95

Проверьте код игры

Когда трассировка стека показывает функцию в библиотеке libil2cpp.so , ошибка произошла в коде C#, который преобразуется в C++ . Библиотека libil2cpp.so содержит не только код вашей игры, но также плагины и пакеты.

Имя файла C++ следует за именем сборки, определенным в проекте Unity. В противном случае имя файла имеет имя Assembly-C# по умолчанию. Например, на рис. 3 показана ошибка в файле Game.cpp (выделен синим цветом), имя которого определено в файле определения сборки. Logger — это имя класса (выделено красным) в сценарии C#, за которым следует имя функции (выделено зеленым). Наконец, это полное имя, сгенерированное преобразователем IL2CPP (выделено оранжевым цветом).

Рисунок 3. Стек вызовов тестового проекта из Backtrace.

Проверьте код игры, выполнив следующие действия:

  • Проверьте проект C# на наличие подозрительного кода. Обычно необработанные исключения C# не вызывают ошибок ANR или сбоя приложения. Несмотря на это, убедитесь, что код работает правильно в различных ситуациях. Проверьте, использует ли код сторонний модуль ядра, и проанализируйте, не возникла ли ошибка в недавнем выпуске. Кроме того, проверьте, обновляли ли вы недавно Unity или ошибка возникает только на определенных устройствах.
  • Экспортируйте игру как проект Android Studio. Имея полный доступ к преобразованному исходному коду C# вашей игры, вы можете найти функцию, вызывающую ошибку ANR. Код C++ сильно отличается от вашего кода C#, и при преобразовании кода редко возникают проблемы. Если вы что-то найдете, отправьте заявку в службу поддержки Unity.
  • Просмотрите исходный код игры и убедитесь, что вся логика, выполняющаяся в обратных вызовах OnApplicationFocus() и OnApplicationPause() , надлежащим образом очищена.
    • Движок Unity имеет тайм-аут для приостановки выполнения; чрезмерная нагрузка на эти обратные вызовы может вызвать ошибку ANR.
    • Добавляйте журналы или навигационные цепочки к частям кода, чтобы улучшить анализ данных.
  • Используйте Unity Profiler, чтобы исследовать производительность игры. Профилирование вашего приложения также может быть отличным способом выявить узкие места, которые могут вызывать ошибки ANR.
  • Отличный способ определить длинные операции ввода-вывода в основном потоке — использовать строгий режим .
  • Проанализируйте историю Android Vitals или другой службы отчетов и проверьте версии выпуска игры, в которых ошибка возникает чаще всего. Просмотрите исходный код в истории контроля версий и сравните изменения кода между выпусками. Если вы обнаружите что-то подозрительное, поэкспериментируйте с каждым изменением или возможным исправлением индивидуально.
  • Изучите историю отчетов об ошибках ANR в Google Play для устройств и версий Android, получивших наибольшее количество ошибок ANR. Если устройства или версии устарели, скорее всего, вы можете их спокойно игнорировать, если это не повлияет на прибыльность игры. Внимательно изучите данные, поскольку определенная группа пользователей больше не сможет играть в вашу игру. Дополнительную информацию см. в разделе Панель распространения .
  • Просмотрите исходный код игры и убедитесь, что вы не вызываете какой-либо код, который может вызвать проблемы, например, функция Finish может оказаться разрушительной, если ее неправильно использовать. Дополнительные сведения о разработке для Android см. в руководствах для разработчиков Android .
  • После просмотра данных и экспорта сборки игры в Android Studio вы имеете дело с кодом C и C++ и можете в полной мере воспользоваться преимуществами инструментов, выходящих за рамки стандартных решений Unity, таких как Android Memory Profiler , Android CPU Profiler и perfetto .

Код движка Unity

Чтобы узнать, происходит ли ошибка ANR на стороне движка Unity, проверьте наличие libUnity.so или libMain.so в трассировках стека. Если вы их обнаружили, выполните следующие действия:

  • Сначала выполните поиск по каналам сообщества ( форумы Unity , обсуждения Unity , Stackoverflow ).
  • Если вы ничего не нашли, сообщите об ошибке , чтобы решить проблему. Предоставьте символьную трассировку стека, чтобы инженеры ядра могли лучше понять и устранить ошибку.
  • Проверьте, внесла ли последняя версия Unity LTS улучшения, связанные с вашими проблемами. Если да, обновите игру, чтобы использовать эту версию. (Это решение может быть доступно только некоторым разработчикам.)
  • Если в вашем коде используется пользовательское Activity вместо действия по умолчанию, просмотрите код Java, чтобы убедиться, что это действие не вызывает каких-либо проблем.

Сторонний SDK

  • Убедитесь, что все сторонние библиотеки обновлены и на них нет отчетов о сбоях или ошибках ANR для последней версии Android.
  • Посетите форумы Unity, чтобы узнать, были ли уже устранены какие-либо ошибки в более поздней версии или был ли предоставлен обходной путь от Unity или члена сообщества.
  • Просмотрите отчет ANR Google Play и убедитесь, что ошибка еще не обнаружена Google. Google знает о некоторых ошибках ANR и активно работает над их устранением.

Системная библиотека

Системные библиотеки обычно находятся далеко от контроля разработчика, но они не составляют значительный процент ошибок ANR. Помимо обращения к разработчику библиотеки или добавления журналов, чтобы сузить проблему, ошибки ANR системной библиотеки трудно устранить.

Причины выхода

ApplicationExitInfo — это API Android для понимания причин ошибок ANR. Если ваша игра использует Unity 6 или более позднюю версию, вы можете напрямую вызвать ApplicationExitInfo . Для более старых версий Unity вам необходимо реализовать собственный плагин для включения вызовов ApplicationExitInfo из Unity.

Crashlytics также использует ApplicationExitInfo ; однако ваша собственная реализация дает вам более точный контроль и позволяет включать более релевантную информацию .