Чтение отчетов об ошибках

Ошибки являются реальностью в любом типе разработки, и отчеты об ошибках имеют решающее значение для выявления и решения проблем. Все версии Android поддерживают захват отчетов об ошибках с помощью Android Debug Bridge (adb) ; Android версии 4.2 и выше поддерживают опцию разработчика для получения отчетов об ошибках и обмена ими по электронной почте, на Диске и т. д.

Отчеты об ошибках Android содержат dumpsys , dumpstate и logcat в текстовом формате (.txt), что позволяет легко искать определенный контент. В следующих разделах подробно описаны компоненты отчетов об ошибках, описаны распространенные проблемы и даны полезные советы и команды grep для поиска журналов, связанных с этими ошибками. Большинство разделов также содержат примеры команды grep и вывода и/или вывода dumpsys .

Логкэт

Журнал logcat представляет собой строковый дамп всей информации logcat . Системная часть зарезервирована для фреймворка и имеет более длинную историю, чем основная , которая содержит все остальное. Каждая строка обычно начинается с timestamp UID PID TID log-level , хотя в старых версиях Android этот UID может отсутствовать.

Просмотр журнала событий

Этот журнал содержит строковые представления сообщений журнала в двоичном формате. Он менее зашумлен, чем журнал logcat , но его немного сложнее читать. При просмотре журналов событий вы можете искать в этом разделе определенный идентификатор процесса (PID), чтобы увидеть, что делает процесс. Основной формат: timestamp PID TID log-level log-tag tag-values .

Уровни журнала включают следующее:

  • В: многословный
  • Д: отладка
  • я: информация
  • В: предупреждение
  • Э: ошибка

Другие полезные теги журнала событий см. в /services/core/java/com/android/server/EventLogTags.logtags .

ANR и взаимоблокировки

Отчеты об ошибках могут помочь вам определить, что вызывает ошибки Application Not Responding (ANR) и события взаимоблокировки.

Выявление не отвечающих приложений

Когда приложение не отвечает в течение определенного времени, обычно из-за заблокированного или занятого основного потока, система завершает процесс и сбрасывает стек в /data/anr . Чтобы обнаружить виновника ANR, выполните grep для am_anr в журнале двоичных событий.

Вы также можете найти ANR in журнале logcat , который содержит больше информации о том, что использовало ЦП во время ANR.

Поиск следов стека

Часто можно найти трассировки стека, соответствующие ANR. Убедитесь, что отметка времени и PID в трассировках ВМ соответствуют анализируемому ANR, а затем проверьте основной поток процесса. Иметь ввиду:

  • Основной поток сообщает вам только то, что поток делал во время ANR, что может соответствовать или не соответствовать истинной причине ANR. (Стек в отчете об ошибке может быть невинным; что-то еще могло зависнуть на долгое время — но недостаточно долго для ANR — прежде чем отклеиться.)
  • Может существовать более одного набора трассировок стека ( VM TRACES JUST NOW и VM TRACES AT LAST ANR ). Убедитесь, что вы просматриваете правильный раздел.

Поиск взаимоблокировок

Взаимоблокировки часто сначала появляются как ANR, потому что потоки застревают. Если тупик поражает системный сервер, сторожевой таймер в конечном итоге уничтожит его, что приведет к записи в журнале, похожей на: WATCHDOG KILLING SYSTEM PROCESS . С точки зрения пользователя устройство перезагружается, хотя технически это перезапуск во время выполнения, а не настоящая перезагрузка.

  • При перезапуске во время выполнения системный сервер умирает и перезапускается; пользователь видит, как устройство возвращается к анимации загрузки.
  • При перезагрузке происходит сбой ядра; пользователь видит, что устройство возвращается к загрузочному логотипу Google.

Чтобы найти тупиковые ситуации, проверьте разделы трассировки VM на наличие шаблона потока A, ожидающего чего-то, удерживаемого потоком B, который, в свою очередь, ожидает чего-то, удерживаемого потоком A.

мероприятия

Действие — это компонент приложения, который предоставляет экран, с которым пользователи взаимодействуют, чтобы сделать что-то, например, набрать номер, сделать снимок, отправить электронное письмо и т. д. С точки зрения отчета об ошибке, действие — это единая целенаправленная вещь, которую может сделать пользователь. , что делает очень важным определение активности, которая была в центре внимания во время аварии. Действия (через ActivityManager) запускают процессы, поэтому обнаружение всех остановок и запусков процессов для данного действия также может помочь в устранении неполадок.

Просмотр целенаправленных действий

Чтобы просмотреть историю целенаправленных действий, выполните поиск am_focused_activity .

Начинается процесс просмотра

Чтобы просмотреть историю запусков процессов, найдите Start proc .

Аппарат тормозит?

Чтобы определить, не am_proc_died и am_proc_start за короткий промежуток времени.

объем памяти

Поскольку устройства Android часто имеют ограниченный объем физической памяти, управление оперативной памятью (ОЗУ) имеет решающее значение. Отчеты об ошибках содержат несколько индикаторов нехватки памяти, а также состояние дампа, которое обеспечивает моментальный снимок памяти.

Определение нехватки памяти

Недостаток памяти может привести к зависанию системы, так как она убивает некоторые процессы, чтобы освободить память, но продолжает запускать другие процессы. Чтобы просмотреть подтверждающие доказательства нехватки памяти, проверьте концентрации записей am_proc_died и am_proc_start в журнале двоичных событий.

Недостаток памяти также может замедлить переключение задач и помешать попыткам возврата (поскольку задача, к которой пользователь пытался вернуться, была уничтожена). Если программа запуска была убита, она перезапускается, когда пользователь касается кнопки «Домой», и журналы показывают, что программа запуска перезагружает свое содержимое.

Просмотр исторических показателей

Запись am_low_memory в бинарном журнале событий указывает на то, что последний кешированный процесс умер. После этого система начинает убивать сервисы.

Просмотр индикаторов пробуксовки

Другие индикаторы перегрузки системы (пейджинг, прямое восстановление и т. д.) включают циклы потребления kswapd , kworker и mmcqd . (Имейте в виду, что собираемый отчет об ошибке может повлиять на индикаторы сбоев.)

Журналы ANR могут предоставить аналогичный снимок памяти.

Получение снимка памяти

Моментальный снимок памяти представляет собой состояние дампа, в котором перечислены запущенные процессы Java и собственные процессы (подробности см. в разделе Просмотр общего распределения памяти ). Имейте в виду, что снимок дает только состояние в определенный момент времени; система могла быть в лучшем (или худшем) состоянии до моментального снимка.

Трансляции

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

Просмотр исторических передач

Исторические передачи — это уже отправленные, перечисленные в обратном хронологическом порядке.

Сводный раздел представляет собой обзор последних 300 трансляций в активном режиме и последних 300 трансляций в фоновом режиме.

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

  • BroadcastFilter регистрируются во время выполнения и отправляются только уже запущенным процессам.
  • ResolveInfo регистрируется через записи манифеста. ActivityManager запускает процесс для каждого ResolveInfo , если он еще не запущен.

Просмотр активных трансляций

Активные рассылки — это те, которые еще не были отправлены. Большое число в очереди означает, что система не может отправлять широковещательные сообщения достаточно быстро, чтобы не отставать.

Просмотр слушателей трансляции

Чтобы просмотреть список приемников, прослушивающих широковещательную рассылку, проверьте таблицу распознавателей получателей в dumpsys activity broadcasts . В следующем примере отображаются все приемники, прослушивающие USER_PRESENT .

Мониторинг конфликтов

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

В системном журнале:

10-01 18:12:44.343 29761 29914 W art     : Long monitor contention event with owner method=void android.database.sqlite.SQLiteClosable.acquireReference() from SQLiteClosable.java:52 waiters=0 for 3.914s

В журнале событий:

10-01 18:12:44.364 29761 29914 I dvm_lock_sample: [com.google.android.youtube,0,pool-3-thread-9,3914,ScheduledTaskMaster.java,138,SQLiteClosable.java,52,100]

Компиляция фона

Компиляция может быть дорогостоящей и нагружать устройство.

Компиляция может выполняться в фоновом режиме при загрузке обновлений магазина Google Play. В этом случае сообщения из приложения магазина Google Play ( finsky ) и installd появляются перед сообщениями dex2oat .

Компиляция также может происходить в фоновом режиме, когда приложение загружает файл dex, который еще не был скомпилирован. В этом случае вы не увидите finsky или installd .

Повествование

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

Синхронизация графиков

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

Временные метки системы и журнала событий находятся в том же часовом поясе, что и пользователь (как и большинство других временных меток). Например, когда пользователь нажимает кнопку «Домой», системный журнал сообщает:

10-03 17:19:52.939  1963  2071 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.google.android.googlequicksearchbox/com.google.android.launcher.GEL (has extras)} from uid 1000 on display 0

Для того же действия журнал событий сообщает:

10-03 17:19:54.279  1963  2071 I am_focused_activity: [0,com.google.android.googlequicksearchbox/com.google.android.launcher.GEL]

Журналы ядра ( dmesg ) используют другую временную базу, помечая элементы журнала секундами с момента завершения загрузчика. Чтобы зарегистрировать эту временную шкалу для других временных шкал, найдите сообщения о выходе из приостановки и входе в приостановку:

<6>[201640.779997] PM: suspend exit 2015-10-03 19:11:06.646094058 UTC
…
<6>[201644.854315] PM: suspend entry 2015-10-03 19:11:10.720416452 UTC

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

Определение времени сообщения об ошибке

Чтобы определить, когда был получен отчет об ошибке, сначала проверьте системный журнал (Logcat) на dumpstate: begin :

10-03 17:19:54.322 19398 19398 I dumpstate: begin

Затем проверьте временные метки журнала ядра ( dmesg ) на наличие Starting service 'bugreport' :

<5>[207064.285315] init: Starting service 'bugreport'...

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

Сила

Журнал событий содержит информацию о состоянии питания экрана, где 0 — экран выключен, 1 — экран включен, а 2 — включена защита клавиатуры.

Отчеты об ошибках также содержат статистику о блокировках пробуждения — механизме, используемом разработчиками приложений, чтобы указать, что их приложение должно оставаться включенным. (Подробнее о блокировках пробуждения см. в разделах PowerManager.WakeLock и Keep the CPU on .)

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

Для получения дополнительной помощи по визуализации состояния питания используйте Battery Historian , инструмент Google с открытым исходным кодом для анализа потребителей батареи с помощью файлов отчетов об ошибках Android.

Пакеты

Раздел DUMP OF SERVICE package содержит версии приложений (и другую полезную информацию).

Процессы

Отчеты об ошибках содержат огромное количество данных для процессов, включая время запуска и остановки, продолжительность выполнения, связанные службы, оценку oom_adj и т. д. Подробнее о том, как Android управляет процессами, см. в разделе Процессы и потоки .

Определение времени выполнения процесса

Раздел procstats содержит полную статистику о том, как долго запущены процессы и связанные с ними службы. Чтобы получить краткую удобочитаемую сводку, выполните поиск по запросу AGGREGATED OVER , чтобы просмотреть данные за последние три или 24 часа, а затем выполните поиск по запросу Summary: чтобы просмотреть список процессов, как долго эти процессы выполнялись с различными приоритетами и их ОЗУ. использование отформатировано как мин-средне-макс PSS/мин-средне-макс USS.

Почему процесс запущен?

В dumpsys activity processes перечислены все запущенные в данный момент процессы, упорядоченные по показателю oom_adj (Android указывает важность процесса, присваивая процессу значение oom_adj , которое может динамически обновляться с помощью ActivityManager). Вывод аналогичен снимку памяти , но включает дополнительную информацию о причинах запуска процесса. В приведенном ниже примере записи, выделенные жирным шрифтом, указывают на то, что процесс gms.persistent работает с vis (видимым) приоритетом, поскольку системный процесс привязан к своему NetworkLocationService .

Сканы

Выполните следующие шаги, чтобы определить приложения, выполняющие чрезмерное сканирование Bluetooth с низким энергопотреблением (BLE):

  • Найти сообщения журнала для BluetoothLeScanner :
    $ grep 'BluetoothLeScanner' ~/downloads/bugreport.txt
    07-28 15:55:19.090 24840 24851 D BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5
    
  • Найдите PID в сообщениях журнала. В этом примере «24840» и «24851» — это PID (идентификатор процесса) и TID (идентификатор потока).
  • Найдите приложение, связанное с PID:
    PID #24840: ProcessRecord{4fe996a 24840:com.badapp/u0a105}
    
    .

    В этом примере имя пакета — com.badapp .

  • Найдите название пакета в Google Play, чтобы определить ответственное приложение: https://play.google.com/store/apps/details?id=com.badapp .

Примечание . Для устройств под управлением Android 7.0 система собирает данные для сканирования BLE и связывает эти действия с инициирующим приложением. Дополнительные сведения см. в разделе Сканирование с низким энергопотреблением (LE) и Bluetooth .