Понимание отчетов HWAsan

Когда инструмент HWASan обнаруживает ошибку памяти, процесс завершается с помощью abort() и отчет выводится в потоки stderr и logcat. Как и все родные сбои на Android, ошибки HWASan находятся в /data/tombstones .

Пример отчета

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

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/flame_hwasan/flame:Tiramisu/MASTER/7956676:userdebug/dev-keys'
Revision: 'DVT1.0'
ABI: 'arm64'
Timestamp: 2019-04-24 01:13:22+0000
pid: 11154, tid: 11154, name: sensors@1.0-ser  >>> /vendor/bin/hw/android.hardware.sensors@1.0-service <<<
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: '

[...]

[0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5








[ … regular crash dump follows …]

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

  • За пределами доступа к стеку или куче
  • Ошибка использования после освобождения в куче
  • Ошибка использования после возврата в стеке

Разделы

Вот объяснение каждого из разделов отчета HWASan.

Ошибка доступа

Содержит информацию о плохом доступе к памяти, в том числе:

  • Тип доступа ( READ или WRITE )
  • Размер доступа (сколько байтов было предпринято для доступа)
  • Номер потока доступа
  • Теги указателя и памяти (для расширенной отладки)

Трассировка стека доступа

Трассировка стека плохого доступа к памяти. См. Символизация, чтобы символизировать.

Причина

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

  • Использовать после бесплатного
  • Несоответствие тега стека, которое может быть связано с использованием стека после возврата, использованием стека после области действия или выходом за пределы.
  • Переполнение буфера кучи
  • Глобальное переполнение

Информация о памяти

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

Тип ошибки Причина Формат отчета
Несоответствие тегов Использовать после бесплатного Используйте этот формат отчета:
<address> is located N bytes inside of M-byte region [<start>, <end>)
freed by thread T0 here:
Переполнение буфера кучи Обратите внимание, что это также может быть недостаточный поток.
<address> is located N bytes to the right of M-byte region [<start>, <end>)
allocated here:
Несоответствие тегов стека В отчетах о стеке не делается различий между ошибками переполнения и потери значения, а также ошибками использования после возврата. Кроме того, чтобы найти распределение стека, которое является источником ошибки, требуется этап автономной символизации. См. раздел Понимание отчетов стека .
Недействительно бесплатно Использовать после бесплатного Двойная бесплатная ошибка. Если это происходит при завершении процесса, это может означать нарушение ODR .
<address> is located N bytes inside of M-byte region [<start>, <end>)
freed by thread T0 here:
Не могу описать адрес Либо дикое освобождение (освобождение памяти, которая не была выделена ранее), либо двойное освобождение после того, как выделенная память была исключена из свободного буфера HWASan.
0x... это теневая память HWAsan Дикое освобождение, поскольку приложение пыталось освободить внутреннюю память HWASan.

Трассировка стека освобождения

Трассировка стека того, где была освобождена память. Присутствует только для ошибок «использование после освобождения» или «без недопустимых ошибок». См. Символизация, чтобы символизировать.

Трассировка стека распределения

Трассировка стека того, где была выделена память. См. Символизация, чтобы символизировать.

Расширенная информация об отладке

Отчет HWASan также содержит некоторую дополнительную информацию об отладке, в том числе (по порядку):

  1. Список потоков в процессе
  2. Список потоков в процессе
  3. Значение тегов памяти рядом с неисправной памятью
  4. Дамп регистров в точке доступа к памяти

Дамп тегов памяти

Вы можете использовать дамп памяти тега для поиска близлежащих выделений памяти с тем же тегом, что и тег-указатель. Эти теги могут указывать на доступ за пределами границ с большим смещением. Один тег соответствует 16 байтам памяти; тег указателя — это верхние 8 бит адреса. Дамп памяти тега может дать подсказки, например, следующее переполнение буфера справа:

tags: ad/5c (ptr/mem)
[...]
Memory tags around the buggy address (one tag corresponds to 16 bytes):
  0x006f33ae1ff0: 0e  0e  0e  57  20  20  20  20  20  2e  5e  5e  5e  5e  5e  b5
=>0x006f33ae2000: f6  f6  f6  f6  f6  4c  ad  ad  ad  ad  ad  ad [5c] 5c  5c  5c
  0x006f33ae2010: 5c  04  2e  2e  2e  2e  2e  2f  66  66  66  66  66  80  6a  6a
Tags for short granules around the buggy address (one tag corresponds to 16 bytes):
  0x006f33ae1ff0: ab  52  eb  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..
=>0x006f33ae2000: ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  .. [..] ..  ..  ..
  0x006f33ae2010: ..  5c  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..  ..

Обратите внимание на 6 × 16 = 96 байт ad тегов слева, соответствующих тегу указателя.

Если размер выделения не кратен 16, оставшаяся часть размера сохраняется как тег памяти , а тег сохраняется как тег с короткими гранулами . В предыдущем примере сразу после выделенного жирным шрифтом выделения с тегом ad у нас есть выделение 5 × 16 + 4 = 84 байта для тега 5c .

Тег с нулевой памятью (например, tags: ad/ 00 (ptr/mem) ) указывает на ошибку использования стека после возврата.

Зарегистрировать дамп

Дамп регистра в отчетах HWASan соответствует инструкции, выполнившей недопустимый доступ к памяти. За этим дампом следует еще один дамп регистров из обычного обработчика сигналов Android. Не обращайте внимания на второй дамп , так как он был получен, когда HWASan вызвал abort() и не имеет отношения к ошибке.

Символизация

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

Первоначальная настройка: установите llvm-symbolizer.

Для символизации в вашей системе должен быть установлен llvm-symbolizer , доступный из $PATH . В Debian вы можете установить его с помощью sudo apt install llvm .

Получить файлы символов

Для символизации нам нужны необработанные двоичные файлы, содержащие символы. Их расположение зависит от типа постройки:

  • Для локальных сборок файлы символов находятся в out/target/product/<product>/symbols/ .
  • Для AOSP-сборок (например, прошитых из Android Flash Tool ) сборки идут на Android CI . В Артефактах для сборки есть файл ${PRODUCT}-symbols-${BUILDID}.zip .
  • Для внутренних сборок вашей организации обратитесь к документации вашей организации, чтобы получить помощь в получении файлов символов.

Символизировать

hwasan_symbolize --symbols <DECOMPRESSED_DIR>/out/target/product/*/symbols < crash

Понимание отчетов стека

Для ошибок, возникающих с переменными стека, отчет HWASan содержит следующую информацию:

Cause: stack tag-mismatch
Address 0x007d4d251e80 is located in stack of thread T64
Thread: T64 0x0074000b2000 stack: [0x007d4d14c000,0x007d4d255cb0) sz: 1088688 tls: [0x007d4d255fc0,0x007d4d259000)
Previously allocated frames:
  record_addr:0x7df7300c98 record:0x51ef007df3f70fb0  (/apex/com.android.art/lib64/libart.so+0x570fb0)
  record_addr:0x7df7300c90 record:0x5200007df3cdab74  (/apex/com.android.art/lib64/libart.so+0x2dab74)
  [...]

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

Нарушения УСО

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

После символизации нарушения ODR показывают ошибку использования после освобождения с __cxa_finalize как в стеке недопустимого доступа, так и в стеке освобожденного здесь . Ранее выделенный здесь стек содержит __dl__ZN6soinfo17call_constructorsEv и должен указывать на место в вашей программе, которое определяет переменную выше в стеке.

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

Поиск неисправностей

В этом разделе описаны некоторые ошибки и способы их устранения.

HWAddressSanitizer не может более подробно описать адрес.

Иногда HWAsan может не хватать места для информации о прошлых выделениях памяти. В этом случае отчет содержит только одну трассировку стека для немедленного доступа к памяти, за которой следует примечание:

HWAddressSanitizer can not describe address in more detail.

В некоторых случаях эту проблему можно решить, запустив тест несколько раз. Другой вариант — увеличить размер истории HWAsan. Вы можете сделать это глобально в build/soong/cc/sanitize.go (найдите hwasanGlobalOptions ) или в среде вашего процесса (попробуйте adb shell echo $HWASAN_OPTIONS чтобы увидеть текущие настройки).

Эта ошибка также может произойти, если доступная память не сопоставлена ​​или не выделена распределителем, не поддерживающим HWASan. В этом случае тег mem , указанный в заголовке сбоя, обычно равен 00 . Если у вас есть доступ к полному захоронению, возможно, будет полезно просмотреть дамп карт памяти, чтобы выяснить, какому сопоставлению (если таковое имеется) принадлежит адрес.

Вложенная ошибка в той же теме

Это означает, что произошла ошибка при создании отчета о сбое HWASan. Обычно это происходит из-за ошибки в среде выполнения HWASan. Сообщите об ошибке и предоставьте инструкции, как воспроизвести проблему, если это возможно.