Отладка и устранение ошибок памяти

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

tl;dr

  • По возможности используйте безопасный для памяти язык , чтобы исключить ошибки памяти.
  • Всегда используйте PAC/BTI для предотвращения атак ROP/JOP
  • Всегда используйте GWP-ASan для обнаружения редких ошибок памяти в производстве.
  • Используйте HWASan для обнаружения ошибок памяти во время тестирования
  • MTE доступна в качестве опции на некоторых устройствах .
  • Используйте ASan во время тестирования только в крайнем случае.

Безопасные для памяти языки

Безопасный для памяти язык — единственный способ полностью избежать и минимизировать ошибки памяти. Другие инструменты на этой странице помогут вам сделать код, небезопасный для памяти, более безопасным и надёжным, но использование безопасного для памяти языка устраняет весь класс проблем.

Официально поддерживаемые языки программирования для Android — Java и Kotlin. Большинство приложений для Android проще разрабатывать на одном из этих языков.

Тем не менее, есть разработчики приложений, поставляющие код, написанный на Rust, и если вы читаете эту страницу, у вас, вероятно, есть веская причина использовать нативный код (переносимость, производительность или и то, и другое). Rust — лучший выбор для безопасного использования памяти нативного кода на Android. Команда NDK не обязательно сможет помочь вам с проблемами, с которыми вы столкнётесь, если вы пойдёте этим путём, но нам интересно узнать о них !

ПАК/БТИ

Аутентификация указателя и идентификация целевой ветви ( PAC/BTI), также известные как PAC/BTI, — это инструменты, подходящие для использования в производственной среде. Несмотря на то, что они являются отдельными технологиями, они управляются одним и тем же флагом компилятора, поэтому всегда используются вместе.

Эти функции обратно совместимы с устройствами, которые их не поддерживают, поскольку используемые новые инструкции не являются операциями на более ранних устройствах. Также необходимо иметь достаточно новое ядро и достаточно новую версию ОС. Поиск paca и bti в /proc/cpuinfo покажет, достаточно ли у вас новое оборудование и достаточно ли новое ядро. В Android 12 (API 31) реализована необходимая поддержка пользовательского пространства.

Плюсы:

  • Может быть включен во всех сборках, не вызывая проблем на старых устройствах или ядрах (но убедитесь, что вы действительно провели тестирование на комбинации устройство/ядро/ОС, которая поддерживает это!)

Минусы:

  • Доступно только для 64-битных приложений.
  • Не устраняет ошибки на устройствах, которые его не поддерживают.
  • 1% накладных расходов на размер кода

GWP-Асан

GWP-ASan можно использовать для обнаружения ошибок памяти в полевых условиях, однако частота дискретизации слишком низкая, чтобы обеспечить эффективное устранение ошибок.

Плюсы:

  • Отсутствие значительных затрат ресурсов ЦП и памяти
  • Простота развертывания: не требует перекомпиляции собственного кода.
  • Работает для 32-битных приложений

Минусы:

  • Низкая частота выборки требует большого количества пользователей для эффективного поиска ошибок.
  • Обнаруживает только ошибки кучи, но не ошибки стека

HWASan

Аппаратный санитайзер адресов , также известный как HWASan, идеально подходит для выявления ошибок памяти во время тестирования. Он наиболее полезен при использовании в автоматизированном тестировании, особенно при проведении фаззинга, но, в зависимости от требований к производительности вашего приложения, он может быть полезен и на высокопроизводительных телефонах в рамках тестовой среды.

Плюсы:

  • Никаких ложных срабатываний
  • Обнаруживает дополнительные классы ошибок, которые ASan не может обнаружить (использование стека после возврата)
  • Более низкий уровень ложноотрицательных результатов, чем у MTE (1 из 256 против 1 из 16)
  • Меньшие затраты памяти, чем у ASan, его ближайшей альтернативы

Минусы:

  • Значительные затраты ресурсов ЦП (~100%), размера кода (~50%) и памяти (10–35%).
  • До API 34 и NDK r26 требуется прошивка образа, совместимого с HWASan.
  • Работает только в 64-битных приложениях.

МТЕ

Расширение тегирования памяти (Memory Tagging Extension) , также известное как MTE, — это более доступная альтернатива HWASan. Помимо возможностей отладки и тестирования, оно может использоваться для обнаружения и устранения повреждений памяти в рабочей среде. Если у вас есть оборудование для тестирования сборок MTE , вам следует включить его.

Плюсы:

  • Достаточно низкие накладные расходы, приемлемые для многих приложений в производстве
  • Никаких ложных срабатываний
  • Не требует пересборки кода для обнаружения ошибок кучи (но требует для обнаружения ошибок стека)

Минусы:

  • В 2024 году на рынке нет устройств с включенной по умолчанию функцией MTE, но в документации Arm объясняется , как включить MTE для тестирования на Pixel 8/Pixel 8 Pro .
  • Ложноотрицательный результат 1 из 16 против 1 из 256 у HWASan
  • Доступно только для 64-битных приложений.
  • Требуется создание отдельных библиотек для устройств с поддержкой и без поддержки MTE.

Асан

Инструмент для очистки адресов (Address Sanitizer) , также известный как ASan, — старейший и наиболее распространённый из существующих. Он полезен для выявления ошибок памяти во время тестирования и отладки проблем, которые затрагивают только старые устройства, для которых другие инструменты недоступны. По возможности отдавайте предпочтение HWASan.

Плюсы:

  • Широко доступно. Может работать на устройствах вплоть до KitKat.
  • Никаких ложноположительных или ложноотрицательных результатов при правильном использовании

Минусы:

  • Трудно правильно собрать и упаковать
  • Наибольшие накладные расходы среди всех вариантов: ~100% ЦП, ~50% размер кода, ~100% использование памяти
  • Больше не поддерживается
  • Известны ошибки, которые не будут исправлены.