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.
Zero de memória de espaço de usuário inicializada
Desde o Android 12, a memória de pilha é inicializada com zero em todo o código nativo da plataforma (incluindo JNI) e a memória heap é inicializada com zero em todos os processos nativos da plataforma (como netd
), mas não no zygote
ou em aplicativos.
Recomenda-se fortemente que os aplicativos de primeira e de terceiros criados com o NDK usem o sinalizador de compilador -ftrivial-auto-var-init=zero
para inicializar com zero suas variáveis locais de pilha. O compilador otimiza qualquer zeramento desnecessário. Por exemplo, quando uma variável local é inicializada explicitamente (como int x = 123;
a variável x
é inicializada apenas uma vez). Se o programa tiver um buffer de pilha grande em um hotspot de desempenho, o desenvolvedor poderá desabilitar a inicialização usando um atributo do compilador:
__attribute__((__uninitialized__)) char buf[BUFSIZ];
Os aplicativos também podem optar pela inicialização do heap zero usando o atributo de manifesto android:nativeHeapZeroInitialized
. Alternativamente, a inicialização do heap zero pode ser controlada em tempo de execução com:
int mallopt(M_BIONIC_ZERO_INIT, level)
Onde o nível é 0 ou 1.
Zero memória de kernel inicializada
A pilha e o heap do kernel são inicializados com zero para kernels GKI, o que é altamente recomendado pelo CDD .
Para a inicialização da pilha, o GKI usa a configuração CONFIG_INIT_STACK_ALL_ZERO
, que resulta na construção do kernel usando o -ftrivial-auto-var-init=zero
. Para inicialização de heap, o GKI usa o CONFIG_INIT_ON_ALLOC_DEFAULT_ON
, que faz com que todas as alocações de heap, SLAB e SLUB de página sejam inicializadas com zero quando são criadas. Esta opção é efetivamente semelhante a passar init_on_alloc=1
como uma opção de tempo de inicialização do kernel.
Relatório de erros
Nossas ferramentas geram relatórios de bugs perspicazes que contêm informações adicionais para auxiliar 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 erros de segurança de memória causadores de raiz muito mais rapidamente.
Durante o desenvolvimento, os fornecedores devem monitorar a presença de bugs verificando /data/tombstones
e logcat
para falhas nativas. Para obter mais informações sobre como depurar o código nativo do Android, consulte as informações aqui .