Когда инструмент HWASan обнаруживает ошибку памяти, процесс завершается с помощью abort() , и отчет выводится в stderr и logcat. Как и все сбои в нативных приложениях Android, ошибки HWASan находятся в каталоге /data/tombstones .
Пример отчета
В отличие от обычных сбоев, вызванных нативными процессами, HWASan содержит дополнительную информацию в поле сообщения Abort, расположенном в верхней части сообщения об ошибке. Вот пример сбоя, связанного с кучей данных. Информацию об ошибках, связанных со стеком, см. в примечании к разделам, посвященным конкретным проблемам со стеком.
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 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: '==9569==ERROR: HWAddressSanitizer: tag-mismatch on address 0x00433ae20045 at pc 0x00623ae2a9cc READ of size 1 at 0x00433ae20045 tags: 5b/83 (ptr/mem) in thread T0 #0 0x7240450c68 (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) #1 0x723dffd490 (/vendor/lib64/sensors.ssc.so+0x34490) #2 0x723e0126e0 (/vendor/lib64/sensors.ssc.so+0x496e0) [...] [0x00433ae20040,0x00433ae20060) is a small unallocated heap chunk; size: 32 offset: 5 Cause: use-after-free 0x00433ae20045 is located 5 bytes inside of 10-byte region [0x00433ae20040,0x00433ae2004a) freed by thread T0 here: #0 0x72404d1b18 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0x10b18) #1 0x723af23040 (/vendor/lib64/libgralloccore.so+0x5040) #2 0x723af23fa4 (/vendor/lib64/libgralloccore.so+0x5fa4) [...] previously allocated here: #0 0x72404ce554 (/system/lib64/libclang_rt.hwasan-aarch64-android.so+0xd554) #1 0x7240115654 (/apex/com.android.runtime/lib64/bionic/libc.so+0x43654) #2 0x7240450ac8 (/system/lib64/vndk-sp-R/libcutils.so+0x8ac8) [...] hwasan_dev_note_heap_rb_distance: 1 1023 hwasan_dev_note_num_matching_addrs: 0 hwasan_dev_note_num_matching_addrs_4b: 0 Thread: T0 0x006a00002000 stack: [0x007fc1064000,0x007fc1864000) sz: 8388608 tls: [0x00737702ffc0,0x007377033000) Memory tags around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae1ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x006f33ae2000: 08 00 08 00 [83] 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x006f33ae2080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Tags for short granules around the buggy address (one tag corresponds to 16 bytes): 0x006f33ae1ff0: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. =>0x006f33ae2000: 72 .. d0 .. [..] .. .. .. .. .. .. .. .. .. .. .. 0x006f33ae2010: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. See https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html#short-granules for a description of short granule tags Registers where the failure occurred (pc 0x00623ae2a9cc): x0 0000007fc18623ec x1 5b0000433ae20045 x2 0000000000000013 x3 ffffffffffffffff x4 ffffffffffffffff x5 0000007fc1861da3 x6 6f7420676e696f47 x7 45522061206f6420 x8 0000000000000000 x9 0200006b00000000 x10 00000007fc18623f x11 5b0000433ae20040 x12 6f64206f7420676e x13 0a44414552206120 x14 0000000000000010 x15 ffffffffffffffff x16 000000737169ac94 x17 0000000000000007 x18 0000007377bd8000 x19 0000007fc1862498 x20 0200006b00000000 x21 0000007fc18624a8 x22 0000000000000001 x23 0000000000000000 x24 0000000000000000 x25 0000000000000000 x26 0000000000000000 x27 0000000000000000 x28 0000000000000000 x29 0000007fc1862410 x30 000000623ae2a9d0 sp 0000007fc18623d0 SUMMARY: HWAddressSanitizer: tag-mismatch (/system/lib64/vndk-sp-R/libcutils.so+0x8c68) [ … 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 (Other Deployment Disclosure ). <address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
| Не могу указать адрес | Либо происходит свободное освобождение памяти (освобождение памяти, которая ранее не была выделена), либо двойное освобождение памяти после того, как выделенная память была вытеснена из буфера свободного пространства HWASan. | |
| 0x... — это теневая память HWAsan. | Произошла несанкционированная освобождение памяти, поскольку приложение пыталось освободить память, находящуюся внутри HWASan. |
трассировка стека освобождения памяти
Трассировка стека, показывающая место освобождения памяти. Присутствует только при ошибках, связанных с использованием памяти после освобождения (use-after-free) или недопустимой свободным памятью (valid-free). См. раздел «Символизация» для символизации.
трассировка стека выделения
Трассировка стека, показывающая, где была выделена память. См. раздел «Символизация» для символизации.
Расширенная отладочная информация
В отчете HWASan также содержится некоторая расширенная отладочная информация, включая (в указанном порядке):
- Список потоков в процессе
- Список потоков в процессе
- Значения меток памяти вблизи неисправной области памяти.
- Вывод данных из регистров в момент обращения к памяти.
дамп тегов памяти
Вы можете использовать дамп памяти с тегами для поиска близлежащих выделений памяти с тем же тегом, что и тег указателя. Эти теги могут указывать на выход за пределы допустимого диапазона с большим смещением. Один тег соответствует 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. Второй дамп следует игнорировать , поскольку он был получен при вызове функции abort() в HWASan и не имеет отношения к ошибке.
Символизация
Для получения имен функций и номеров строк в трассировках стека (а также имен переменных для ошибок, связанных с использованием после завершения работы программы) необходим этап символизации в автономном режиме.
Первоначальная настройка: установите llvm-symbolizer.
Для символизации в вашей системе должен быть установлен и доступен из $PATH llvm-symbolizer . В Debian его можно установить с помощью sudo apt install llvm .
Получить файлы символов
Для символизации нам необходимы необработанные бинарные файлы, содержащие символы. Их расположение зависит от типа сборки:
- Для локальной сборки файлы символов находятся в папке
out/target/product/<product>/symbols/. - Для сборок AOSP (например, прошитых с помощью Android Flash Tool ) сборка выполняется в среде Android CI . В папке Artifacts для сборки находится файл
${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 не преобразует их в понятный человеку контент в отчете об ошибке и требует дополнительного этапа символизации .
нарушения ODR
Некоторые ошибки, связанные с использованием памяти после освобождения (use-after-free), о которых сообщает HWASan, могут указывать на нарушение правила одного определения (One Definition Rule, ODR). Нарушение ODR происходит, когда одна и та же переменная определяется несколько раз в одной и той же программе. Это также означает, что переменная уничтожается несколько раз, что может привести к ошибке use-after-free.
После символизации нарушения 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. Сообщите об ошибке и, если возможно, предоставьте инструкции по воспроизведению проблемы.