Eu escrevi main.c
no Linux:
int main()
{
while (1){}
}
Quando eu compilo e inicio, posso pmap
:
# pmap 28578
28578: ./a.out
0000000000400000 4K r-x-- /root/a.out
0000000000600000 4K r---- /root/a.out
0000000000601000 4K rw--- /root/a.out
00007f87c16c2000 1524K r-x-- /lib/libc-2.11.1.so
00007f87c183f000 2044K ----- /lib/libc-2.11.1.so
00007f87c1a3e000 16K r---- /lib/libc-2.11.1.so
00007f87c1a42000 4K rw--- /lib/libc-2.11.1.so
00007f87c1a43000 20K rw--- [ anon ]
00007f87c1a48000 128K r-x-- /lib/ld-2.11.1.so
00007f87c1c55000 12K rw--- [ anon ]
00007f87c1c65000 8K rw--- [ anon ]
00007f87c1c67000 4K r---- /lib/ld-2.11.1.so
00007f87c1c68000 4K rw--- /lib/ld-2.11.1.so
00007f87c1c69000 4K rw--- [ anon ]
00007fff19b82000 84K rw--- [ stack ]
00007fff19bfe000 8K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
total 3876K
total (3876) dividido por K é igual à VIRT
coluna na saída de top
. Agora, onde está o segmento de texto? Em 400000, 600000 e 601000, certo? Onde posso ler uma explicação, o que é onde? man pmap
não ajudou.
linux
process
memory
virtual-memory
Thorsten Staerk
fonte
fonte
Respostas:
O segmento de texto é o mapeamento em 0x400000 - está marcado como 'rx' para legível e executável. O mapeamento em 0x600000 é somente leitura, portanto é quase certamente a seção ".rodata" do arquivo executável. O GCC coloca literais da cadeia C em uma seção somente leitura. O mapeamento em 0x601000 é 'rw-', então essa é provavelmente a famosa pilha. Você pode ter seus
malloc()
1024 bytes executáveis e imprimir o endereço para ter certeza.Você pode obter um pouco mais de informações encontrando o PID do seu processo e fazendo:
cat /proc/$PID/maps
- no meu laptop Arch, isso fornece algumas informações extras. Ele está rodando um kernel 3.12, por isso também tem/proc/$PID/numa_maps
, e o catting também pode fornecer uma pequena visão.Outras coisas para executar no arquivo executável:
nm
eobjdump -x
. O primeiro pode dar uma idéia de onde estão várias coisas no mapa de memória, para que você possa ver o que está na seção 0x4000000 em comparação às outras seções.objdump -x
mostra os cabeçalhos de arquivo ELF entre muitas outras coisas, para que você possa ver todas as seções, completas com os nomes das seções e se elas estão mapeadas em tempo de execução ou não.Quanto a encontrar uma explicação por escrito de "o que é onde", você precisará fazer coisas como o google para "layout de memória ELF FILE". Esteja ciente de que o formato de arquivo ELF pode suportar layouts de memória mais exóticos do que normalmente são usados. GCC, Gnu ld e glibc fazem suposições simplificadoras sobre como um arquivo executável é organizado e, em seguida, mapeado para a memória em tempo de execução. Existem muitas páginas da Web que pretendem documentar isso, mas se aplicam apenas a versões mais antigas do Linux, versões mais antigas do GCC ou glibc, ou apenas a executáveis x86. Se você não tiver, obtenha o
readelf
comando. Se você puder escrever programas em C, crie sua própria versãoobjdump -x
oureadelf
se familiarize com o funcionamento dos arquivos executáveis e o que há neles.fonte
readelf
ouobjdump
descobrir, e qualquer que seja o executável que você criou. Minha caixa do Linux linux usa /usr/lib/libc-2.18.so, então é bem diferente da sua caixa.0x601000
é o segmento de dados. Ele contém.data
,.bss
e pode ser estendido viabrk()
.[anon]
indica memória não suportada por arquivo (suportada por troca), obtida viammap()
. O dlmalloc usabrk()
para alocações menores que ~ 64Kb IIRC emmap()
para alocações maiores. O heap é tudo alocado pelo malloc, tanto a parte estendida do segmento de dados quanto asmmap()
alocações baseadas em.