O significado da saída do pmap

12

Eu escrevi main.c no Linux:

int main()
{
  while (1){}
}

Quando eu compilo e inicio, posso pmap it:

# 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
O total de

(3876) dividido por K é igual à coluna VIRT na saída de top . Agora, onde está o segmento de texto? Em 400000, 600000 e 601000, certo? Onde posso ler uma explicação do que é onde? man pmap não ajudou.

    
por Thorsten Staerk 17.12.2013 / 18:46

1 resposta

13

O segmento de texto é o mapeamento em 0x400000 - está marcado como 'r-x' para legível e executável. O mapeamento em 0x600000 é somente leitura, então é quase certo que a seção ".rodata" do arquivo executável. O GCC coloca os literais de string C em uma seção somente leitura. O mapeamento em 0x601000 é 'rw-', então é provavelmente o famoso heap. Você poderia ter seu executável malloc() 1024 bytes 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, que fornece algumas informações adicionais. Ele está rodando um kernel 3.12, então ele também tem /proc/$PID/numa_maps , e catting isso pode dar uma pequena visão também.

Outras coisas para executar no arquivo executável: nm e objdump -x . O primeiro pode lhe dar uma idéia de onde várias coisas estão no mapa de memória, para que você possa ver o que está na seção 0x4000000 em relação às outras seções. objdump -x mostra cabeçalhos de arquivos ELF entre muitas outras coisas, para que você possa ver todas as seções, com nomes de seção e se elas estão mapeadas em um tempo de execução ou não.

No que diz respeito a encontrar uma explicação por escrito de "o que é onde", você terá que 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 usados. GCC e Gnu ld e glibc fazem suposições simplificadoras sobre como um arquivo executável é apresentado e depois mapeado na memória em tempo de execução. Existem muitas páginas da Web que pretendem documentar isso, mas só se aplicam a versões mais antigas do Linux, versões mais antigas do GCC ou glibc, ou se aplicam apenas a executáveis x86. Se você não tiver, obtenha o comando readelf . Se você pode escrever programas em C, crie sua própria versão de objdump -x ou readelf para se familiarizar com o funcionamento dos arquivos executáveis e o que há neles.

    
por 17.12.2013 / 20:26