A memória não inicializada em C e C++ é uma causa comum de problemas de confiabilidade, bugs de segurança de memória e vazamentos de informações. Para evitar esses problemas, o Android inicializa o máximo de memória possível.
Memória do espaço do usuário inicializada em zero
No Android 12 e versões mais recentes, a memória da pilha é inicializada em zero
em todo o código nativo da plataforma (incluindo JNI), e a memória heap é inicializada em zero
em todos os processos nativos da plataforma (como netd
),
mas não na zygote
ou em apps.
É altamente recomendável que apps próprios e de terceiros criados com o NDK
usem a flag do compilador -ftrivial-auto-var-init=zero
para inicializar as variáveis locais da
pilha a zero. O compilador otimiza qualquer zero desnecessário.
Por exemplo, quando uma variável local é inicializada explicitamente
(como a variável int x = 123;
x
é inicializada apenas uma vez).
Se o programa tiver um buffer de pilha grande em um ponto de acesso
de desempenho, o desenvolvedor poderá desativar a inicialização usando um atributo
do compilador:
__attribute__((__uninitialized__)) char buf[BUFSIZ];
Os apps também podem ativar a inicialização de pilha zero usando o
atributo de manifesto android:nativeHeapZeroInitialized
.
Como alternativa, a inicialização do heap zero pode ser controlada no momento da execução
com:
int mallopt(M_BIONIC_ZERO_INIT, level)
Em que o nível é 0 ou 1.
Memória do kernel inicializada como zero
A pilha e o heap do kernel são inicializados em zero para kernels do GKI, o que é recomendado pelo CDD.
Para a inicialização da pilha, o GKI usa a
configuração CONFIG_INIT_STACK_ALL_ZERO
, que resulta na criação do
kernel usando a flag do compilador -ftrivial-auto-var-init=zero
.
Para a inicialização do heap, o GKI usa o
CONFIG_INIT_ON_ALLOC_DEFAULT_ON
, que faz com que todas as alocações de heap de página, SLAB
e SLUB sejam inicializadas em zero quando são criadas. Essa opção é
semelhante a transmitir init_on_alloc=1
como uma opção
de inicialização do kernel.
Relatórios de bugs
Nossas ferramentas geram relatórios de bugs úteis que contêm informações adicionais para ajudar na depuração. O rastreamento de pilha de alocação e desalocação adicional ajuda a entender melhor o ciclo de vida de uma determinada alocação e leva a bugs de segurança de memória raiz muito mais rapidamente.

Durante o desenvolvimento, os fornecedores precisam monitorar a presença de bugs verificando
/data/tombstones
e
logcat
para falhas nativas. Para mais informações sobre
a depuração de código nativo do Android, consulte as informações aqui.