Enquanto brincava um pouco com o sistema de auditoria do kernel, fiz um pequeno programa em C:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv){
void *t;
while(1){
t = malloc(1);
free(t);
}
return 0;
}
E aplicou os seguintes filtros para auditar:
-a always,exit -F arch=b32 -S open,openat -F exit=-EACCES -F key=access
-a always,exit -F arch=b64 -S open,openat -F exit=-EACCES -F key=access
-a always,exit -F arch=b32 -S brk
-a always,exit -F arch=b64 -S brk
Depois de compilar e executar, notei que sys_brk
não estava aparecendo no log de auditoria. Além disso, também não apareceu em strace
, mesmo que malloc
tenha sido chamado (verificado com ltrace). Por fim, removi o gratuito e as chamadas sys_brk
começaram a aparecer.
O que está causando esse tipo de comportamento? A glibc faz algum tipo de otimização malloc
e free
funções para evitar syscalls inúteis?
TL;DR: free
seguido por malloc
não chama o kernel. Por quê?
Seu programa começa com um heap inicial e sua alocação de um byte se encaixa nesse heap. Quando você libera imediatamente a memória alocada, o heap nunca precisa crescer, então você nunca vê uma chamada de sistema correspondente.
Consulte Com que rapidez/frequência as medições de memória do processo são atualizadas no kernel? para um experimento semelhante.