pahole - Cheatsheet de Análise de Layout de Struct & Cache-Line
pahole (“poke-a-hole”) lê informações de debug DWARF ou BTF e imprime o layout de memória real de estruturas C — onde cada campo fica, quanto padding o compilador inseriu, e quantas cache lines a struct ocupa. Compiladores preenchem structs para satisfazer alinhamento, e uma struct descuidadosamente ordenada pode desperdiçar dezenas de bytes e ocupar cache lines extras. Em estruturas de dados quentes, isso se traduz diretamente em cache misses. pahole torna o desperdício visível para que você possa reordenar campos e encolhê-lo.
Instalação
| Plataforma | Comando |
|---|
| Debian/Ubuntu | sudo apt install dwarves |
| Fedora/RHEL | sudo dnf install dwarves |
| Arch Linux | sudo pacman -S pahole |
| Do fonte | build o projeto dwarves |
| Verificar | pahole --version |
Seu binary deve ser construído com info de debug (-g). Binários stripped não têm nada para pahole ler.
Uso Básico
| Comando | Descrição |
|---|
pahole ./myprogram | Mostra todas as structs no binary |
pahole -C mystruct ./myprogram | Uma struct específica |
pahole -C task_struct /sys/kernel/btf/vmlinux | Struct de kernel via BTF |
pahole --sizes ./myprogram | Lista tamanhos de struct |
pahole -H 1 ./myprogram | Apenas structs com ≥1 hole |
Lendo a Saída
struct example {
char flag; /* 0 1 */
/* XXX 7 bytes hole, try to pack */
long int counter; /* 8 8 */
char name[16]; /* 16 16 */
int id; /* 32 4 */
/* XXX 4 bytes hole, try to pack */
void * ptr; /* 40 8 */
/* size: 48, cachelines: 1, members: 5 */
/* sum members: 37, holes: 2, sum holes: 11 */
};
| Anotação | Significado |
|---|
/* offset size */ | Offset de byte e tamanho de cada campo |
XXX N bytes hole | Padding que o compilador inseriu |
size: | Tamanho total da struct |
cachelines: | Quantas linhas de 64-byte ela ocupa |
sum holes: | Total de bytes desperdiçados |
last cacheline: | Bytes usados na linha final |
Encontrando Desperdício em uma Codebase
| Comando | Encontra |
|---|
pahole -H 1 ./bin | Structs com holes |
pahole --nr_members ./bin | Ordenado por contagem de membros |
pahole -c 2 ./bin | Structs ocupando ≥2 cache lines |
pahole -E ./bin | Expande structs aninhadas inline |
pahole -a ./bin | Mostra detalhe de alinhamento/packing |
# Quais structs desperdiçam mais memória para padding?
pahole -H 8 ./myprogram | head -50
Corrigindo Layout
O fix padrão é ordenar campos do maior para o menor alinhamento:
/* Antes: 48 bytes, 11 desperdiçados */
struct bad { char flag; long counter; char name[16]; int id; void *ptr; };
/* Depois: 40 bytes, 0 desperdiçados */
struct good { long counter; void *ptr; char name[16]; int id; char flag; };
| Técnica | Efeito |
|---|
| Ordena por alinhamento descendente | Elimina a maioria dos holes |
| Agrupa campos quentes juntos | Mantém-os em uma cache line |
| Divide campos frios em uma segunda struct | Dados quentes mantêm-se densos |
__attribute__((packed)) | Remove padding — mas pode desacelerar acesso desalinhado |
| Bitfields | Compacta pequeñas flags |
pahole pode até sugerir uma reordenação com --reorganize:
pahole --reorganize -C mystruct ./myprogram
Trabalho de Kernel (BTF)
| Comando | Propósito |
|---|
pahole -C task_struct /sys/kernel/btf/vmlinux | Inspeciona uma struct de kernel ativo |
pahole -J vmlinux | Gera BTF a partir de DWARF |
pahole --btf_encode | Codificação BTF para ferramentas eBPF |
A geração de BTF é por que dwarves é uma dependência de build de kernel — o CO-RE de eBPF depende disso.
Quando Isso Importa
| Situação | Impacto |
|---|
| Milhões de instâncias de uma struct | Economia de memória escala linearmente |
| Loop quente tocando campos de struct | Menos cache lines = menos misses |
| Serialização de rede/disco | Structs menores, menos I/O |
| Memória embedded/constrangida | Cada byte conta |
| Uma struct usada duas vezes | Não se preocupe |
pahole vs Ferramentas Relacionadas
| Ferramenta | Responde |
|---|
| pahole | Como essa struct é disposta e onde está o desperdício? |
| perf | Estou realmente tendo cache-missing? |
| valgrind (cachegrind) | Comportamento de cache simulado |
| heaptrack | Para onde vai a memória heap? |
Use perf para confirmar que cache misses são seu gargalo, então pahole para corrigir o layout causando eles.
Recursos