Когда инструмент 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: '==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 . <address> is located N bytes inside of M-byte region [<start>, <end>) freed by thread T0 here: |
Не могу описать адрес | Либо дикое освобождение (освобождение памяти, которая не была выделена ранее), либо двойное освобождение после того, как выделенная память была исключена из свободного буфера HWASan. | |
0x... это теневая память HWAsan | Дикое освобождение, поскольку приложение пыталось освободить внутреннюю память HWASan. |
Трассировка стека освобождения
Трассировка стека того, где была освобождена память. Присутствует только для ошибок «использование после освобождения» или «без недопустимых ошибок». См. Символизация, чтобы символизировать.
Трассировка стека распределения
Трассировка стека того, где была выделена память. См. Символизация, чтобы символизировать.
Расширенная информация об отладке
Отчет 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. Не обращайте внимания на второй дамп , так как он был получен, когда 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. Сообщите об ошибке и предоставьте инструкции, как воспроизвести проблему, если это возможно.