Il significato dell'output di pmap


12

Ho scritto main.cin Linux:

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

Quando lo compilo e lo avvio, posso pmapfarlo:

# 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

totale (3876) diviso per K è uguale alla VIRTcolonna nell'output di top. Ora dov'è il segmento di testo? A 400000, 600000 e 601000, giusto? Dove posso leggere una spiegazione cos'è? man pmapnon ha aiutato.


i segmenti di testo sono effettivamente di sola lettura, quindi è 0000000000600000.
Danila Ladner,

Grazie! Anche il segmento di testo non dovrebbe essere eseguibile?
Thorsten Staerk il

1
Si hai ragione. r e rx. 0000000000400000 pure.
Danila Ladner,

Risposte:


14

Il segmento di testo è la mappatura a 0x400000 - è contrassegnato 'rx' per leggibile ed eseguibile. Il mapping su 0x600000 è di sola lettura, quindi è quasi sicuramente la sezione ".rodata" del file eseguibile. GCC inserisce i letterali di stringhe C in una sezione di sola lettura. La mappatura su 0x601000 è 'rw-', quindi è probabilmente il famoso heap. Potresti avere i tuoi malloc()1024 byte eseguibili e stampare l'indirizzo per vedere con certezza.

Puoi ottenere un po 'più di informazioni trovando il PID del tuo processo e facendo: cat /proc/$PID/maps- sul mio laptop Arch, che fornisce alcune informazioni extra. Sta eseguendo un kernel 3.12, quindi ha anche /proc/$PID/numa_mapse catting che potrebbe dare anche una piccola intuizione.

Altre cose da eseguire sul file eseguibile: nme objdump -x. Il primo può darti un'idea di dove si trovano varie cose nella mappa di memoria, così puoi vedere cosa c'è nella sezione 0x4000000 rispetto alle altre sezioni. objdump -xmostra le intestazioni dei file ELF tra molte altre cose, quindi puoi vedere tutte le sezioni, complete di nomi di sezione e se sono mappate in un tempo di esecuzione o meno.

Per quanto riguarda la ricerca di una spiegazione scritta di "che cosa è dove", dovrai fare cose come Google per "layout di memoria ELF FILE". Tenere presente che il formato di file ELF può supportare layout di memoria più esotici di quelli comunemente utilizzati. GCC e Gnu ld e glibc fanno tutti ipotesi semplificative su come un file eseguibile viene disposto e quindi mappato in memoria in fase di esecuzione. Esistono molte pagine Web che pretendono di documentarlo, ma si applicano solo alle versioni precedenti di Linux, alle versioni precedenti di GCC o glibc o si applicano solo agli eseguibili x86. Se non lo hai, ottieni il readelfcomando. Se riesci a scrivere programmi in C, crea la tua versione di objdump -xo readelfper familiarizzare con il funzionamento dei file eseguibili e cosa contiene.


2
Bella risposta. Ora, dov'è l'heap del programma? E cosa significa questo [anon]? Che cosa devo cercare su Google per scoprirlo?
Thorsten Staerk il

1
Sai cosa? Ho sbagliato sulla mappatura degli indirizzi 0x601000 - probabilmente è questo l'heap. Dovrai usarlo readelfo objdumpcapirlo, e qualunque sia l'eseguibile che hai creato. La mia casella Linux Arch usa /usr/lib/libc-2.18.so, quindi è abbastanza diversa dalla tua casella.
Bruce Ediger,

2
0x601000è il segmento di dati. Esso contiene .data, .bsse può essere esteso tramite brk(). [anon]indica la memoria non supportata da file (quindi supportata da swap), ottenuta tramite mmap(). dlmalloc utilizza brk()per allocazioni inferiori a ~ 64Kb IIRC e mmap()per allocazioni più grandi. L'heap è tutto allocato da malloc, sia la parte estesa del segmento di dati, sia le mmap()allocazioni basate su.
ninjalj,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.