Понимание отчетов 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 приведены ниже:

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

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

  • Тип доступа («ЧТЕНИЕ» или «ЗАПИСЬ»)
  • Размер доступа (сколько байтов было предпринято для доступа)
  • Номер потока доступа
  • Теги указателя и памяти (для расширенной отладки)

Доступ к трассировке стека

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

Причина

Потенциальная причина плохого доступа. Если кандидатов несколько, они перечислены в порядке убывания вероятности. Предшествует подробной информации о потенциальной причине. 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 байт тегов «рекламы» слева, которые соответствуют тегу указателя).

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

Тег с нулевой памятью (например, 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 (например, прошитых с Flashstation ) сборки можно найти на 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. Сообщите об ошибке и, если возможно, предоставьте инструкции по воспроизведению проблемы.