Нулевая инициализированная память

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

Нулевая инициализированная память пользовательского пространства

Начиная с Android 12, стековая память инициализируется нулем во всем собственном коде платформы (включая JNI), а память кучи инициализируется нулем во всех собственных процессах платформы (таких как netd ), но не в zygote или в приложениях.

Приложениям первых и сторонних разработчиков, созданным с помощью NDK, настоятельно рекомендуется использовать флаг компилятора -ftrivial-auto-var-init=zero для инициализации нулями локальных переменных стека. Компилятор оптимизирует все ненужные обнуления. Например, когда локальная переменная инициализируется явно (например, int x = 123; переменная x инициализируется только один раз). Если программа имеет большой буфер стека в горячей точке производительности, разработчик может отключить инициализацию, используя атрибут компилятора:

__attribute__((__uninitialized__)) char buf[BUFSIZ];

Приложения также могут выбрать нулевую инициализацию кучи, используя атрибут манифеста android:nativeHeapZeroInitialized . Альтернативно, инициализацию нуля кучи можно контролировать во время выполнения с помощью:

int mallopt(M_BIONIC_ZERO_INIT, level)

Где уровень 0 или 1.

Нулевая инициализированная память ядра

Стек ядра и куча инициализируются нулями для ядер GKI, что настоятельно рекомендуется CDD .

Для инициализации стека GKI использует конфигурацию CONFIG_INIT_STACK_ALL_ZERO , что приводит к сборке ядра с использованием флага компилятора -ftrivial-auto-var-init=zero . Для инициализации кучи GKI использует CONFIG_INIT_ON_ALLOC_DEFAULT_ON , который делает все выделения кучи страниц, SLAB и SLUB инициализированными нулями при их создании. Этот параметр по сути аналогичен передаче init_on_alloc=1 в качестве параметра времени загрузки ядра.

Отчеты об ошибках

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

Пример созданного отчета об ошибке   с помощью инструмента безопасности памяти
Рисунок 1. Отчеты об ошибках, созданные инструментами безопасности памяти.

Во время разработки поставщики должны отслеживать наличие ошибок, проверяя /data/tombstones и logcat на наличие встроенных сбоев. Дополнительную информацию об отладке нативного кода Android смотрите здесь .