Отладка повреждения памяти с помощью Address Sanitizer

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

HWAddress Sanitizer и Address Sanitizer

HWAddress Sanitizer (HWASan) и Address Sanitizer (ASan) — это инструменты отладки повреждений памяти, которые помогают отлаживать повреждения памяти и ошибки перезаписи, например следующие:

  • Переполнение и опустошение буфера стека
  • Переполнение и опустошение буфера кучи
  • Использование стека за пределами его области применения
  • Двойные бесплатные и дикие бесплатные ошибки
  • Использование стека после возврата (только HWASan)

Мы рекомендуем включать HWASan или ASan только при отладке проблемы или в рамках автоматического тестирования. Хотя эти инструменты эффективны, их использование влечет за собой штраф.

Поведение во время выполнения

Если этот параметр включен, и HWASan, и ASan автоматически проверяют наличие повреждений памяти на протяжении всего времени выполнения вашего приложения.

Если обнаруживается ошибка памяти, приложение аварийно завершает работу с ошибкой SIGBART (прерывание сигнала) и печатает подробное сообщение в logcat. Копия сообщения также записывается в файл /data/tombstones .

Сообщение об ошибке выглядит примерно так:

ERROR: HWAddressSanitizer: tag-mismatch on address 0x0042a0826510 at pc 0x007b24d90a0c
WRITE of size 1 at 0x0042a0826510 tags: 32/3d (ptr/mem) in thread T0
    #0 0x7b24d90a08  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x2a08)
    #1 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)
    #2 0x7b8f1db364  (/apex/com.android.art/lib64/libart.so+0x18f364)
    #3 0x7b8f2ad8d4  (/apex/com.android.art/lib64/libart.so+0x2618d4)

0x0042a0826510 is located 0 bytes to the right of 16-byte region [0x0042a0826500,0x0042a0826510)
allocated here:
    #0 0x7b92a322bc  (/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so+0x212bc)
    #1 0x7b24d909e0  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x29e0)
    #2 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)

Предварительные условия

Установите сборку HWAsan ОС Android.

Чтобы использовать HWASan, следуйте инструкциям по установке в документации HWASan, чтобы установить сборку HWASan ОС Android для устройств Google Pixel.

Для других устройств обратитесь к производителю, чтобы получить сборку ОС HWASan, если она доступна, или воспользуйтесь программным инструментом ASan.

Используйте общую стандартную библиотеку C++ в своем проекте.

Из-за известной проблемы ASan несовместим с обработкой исключений C++ при использовании libc++_static . Эта проблема не наблюдается при использовании libc++_shared .

HWASan имеет собственную реализацию операторов new и delete , которую нельзя использовать, если стандартная библиотека статически скомпонована в проект.

Чтобы изменить этот параметр, см. раздел «Связывание стандартной библиотеки C++» этого документа.

Включить генерацию указателя кадра

HWASan и ASan используют быстрый механизм размотки на основе указателя кадра для создания информации трассировки стека для событий выделения и освобождения памяти. Это означает, что для использования этих функций необходимо включить генерацию указателя кадра в настройках компилятора C++. То есть вам нужно отключить оптимизацию пропуска указателя кадра.

Чтобы изменить этот параметр, см. раздел «Включение генерации указателя кадра» этого документа.

Настройка проекта Visual Studio для использования HWASan или ASan

Включение HWASan или ASan

Чтобы включить HWASan или ASan, перейдите в «Свойства конфигурации» > «Общие» на страницах свойств вашего проекта.

Меню свойств обозревателя решений Visual Studio для текущего проекта.

Рис. 1. Параметр «Свойства проекта» в окне обозревателя решений Visual Studio.

Диалоговое окно «Страницы свойств проекта» с показанными общими свойствами и выделенными настройками Address Sanitizer.

Рис. 2. Параметр Address Sanitizer (ASan) в общих свойствах проекта.

Чтобы включить HWASan для вашего проекта, измените настройку Address Sanitizer (ASan) на Hardware ASan Enabled (fsanitize=hwaddress) .

Чтобы включить ASan для вашего проекта, измените настройку Address Sanitizer (ASan) на ASan Enabled (fsanitize=address) .

Включение генерации указателя кадра

Генерация указателя фрейма контролируется параметром компилятора Omit Frame Pointer C/C++, и его можно найти на страницах свойств вашего проекта в разделе Свойства конфигурации > C/C++ > Оптимизация .

Диалоговое окно «Страницы свойств проекта», в котором показаны свойства оптимизации C/C++ и выделены настройки «Пропустить указатель фрейма».

Рис. 3. Где находится параметр «Опустить указатель кадра» .

При использовании HWASan или ASan установите для параметра «Опустить указатель кадра» значение «Нет» (-fno-omit-frame-pointer) .

Связывание стандартной библиотеки C++ в режиме общей библиотеки

Параметр режима компоновщика для стандартной библиотеки C++ можно найти на страницах свойств вашего проекта в разделе «Свойства конфигурации» > «Общие» в разделе «Параметры проекта по умолчанию» .

Диалоговое окно «Страницы свойств проекта» с выбранной категорией «Общие» и выделенным параметром «Использование STL».

Рис. 4. Где найти настройку режима компоновщика для стандартной библиотеки C++.

При использовании HWASan или ASan установите для параметра «Использование STL» значение «Использовать стандартные библиотеки C++ (.so)» . Это значение связывает стандартную библиотеку C++ с вашим проектом как общую библиотеку , необходимую для правильной работы HWASan и ASan.

Создание конфигурации сборки для использования Address Sanitizer

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

Однако, если вы считаете это полезным и планируете использовать его регулярно, вы можете рассмотреть возможность создания новой конфигурации сборки для HWASan или ASan, как показано в примере Teapot . Вы можете сделать это, если, например, вы регулярно запускаете Address Sanitizer в рамках модульных тестов или во время ночных дымовых тестов вашей игры.

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

Чтобы создать конфигурацию сборки, на страницах свойств вашего проекта нажмите кнопку «Диспетчер конфигураций…» , а затем откройте раскрывающийся список «Конфигурация активного решения» . Затем выбор и создайте новую конфигурацию сборки с соответствующим именем (например, HWASan Enabled ).