Znaczenie produkcji pmap


12

Napisałem main.cw systemie Linux:

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

Kiedy kompiluję i uruchamiam, mogę 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

suma (3876) podzielona przez K równa się VIRTkolumnie na wyjściu top. Gdzie jest teraz segment tekstu? Przy 400000, 600000 i 601000, prawda? Gdzie mogę przeczytać wyjaśnienie, gdzie jest? man pmapnie pomogło.


segmenty tekstowe są w rzeczywistości tylko do odczytu, więc jest to 0000000000600000.
Danila Ladner

Dzięki! Czy segment tekstowy nie powinien być również wykonywalny?
Thorsten Staerk

1
Tak masz rację. r i rx. 0000000000400000 również.
Danila Ladner

Odpowiedzi:


15

Segment tekstowy jest mapowany na 0x400000 - jest oznaczony jako „rx”, aby można go było odczytać i wykonać. Mapowanie w 0x600000 jest tylko do odczytu, więc prawie na pewno jest to sekcja „.rodata” pliku wykonywalnego. GCC umieszcza literały ciągów C w sekcji tylko do odczytu. Mapowanie w 0x601000 to „rw-”, więc prawdopodobnie jest to słynna sterta. Możesz mieć wykonywalne malloc()1024 bajty i wydrukować adres, aby się upewnić.

Możesz uzyskać trochę więcej informacji, znajdując PID swojego procesu i wykonując: cat /proc/$PID/maps- na moim laptopie Arch, daje to dodatkowe informacje. Działa z jądrem 3.12, więc ma również /proc/$PID/numa_mapsi catting, który może dać trochę wglądu.

Inne rzeczy do uruchomienia na pliku wykonywalnym: nmi objdump -x. Ten pierwszy może dać ci wyobrażenie o tym, gdzie różne rzeczy leżą na mapie pamięci, dzięki czemu możesz zobaczyć, co jest w sekcji 0x4000000 w porównaniu do innych sekcji. objdump -xpokazuje nagłówki plików ELF wśród wielu innych rzeczy, dzięki czemu można zobaczyć wszystkie sekcje, wraz z nazwami sekcji i tym, czy są one mapowane w czasie wykonywania, czy nie.

Jeśli chodzi o znalezienie pisemnego wyjaśnienia „co jest gdzie”, musisz zrobić takie rzeczy jak Google dla „Układu pamięci ELF FILE”. Należy pamiętać, że format pliku ELF może obsługiwać bardziej egzotyczne układy pamięci, niż się powszechnie stosuje. GCC i Gnu ld i glibc przyjmują uproszczone założenia, w jaki sposób plik wykonywalny jest układany, a następnie odwzorowywany w pamięci w czasie wykonywania. Istnieje wiele stron internetowych, które mają to udokumentować, ale dotyczą tylko starszych wersji Linuksa, starszych wersji GCC lub glibc lub dotyczą tylko plików wykonywalnych x86. Jeśli go nie masz, pobierz readelfpolecenie. Jeśli potrafisz pisać programy w języku C, utwórz własną wersję objdump -xlub readelfzapoznaj się ze sposobem działania plików wykonywalnych i ich zawartością.


2
Świetna odpowiedź. Gdzie jest teraz stos programu? A co to znaczy [anon]? Co muszę znaleźć w Google, aby się tego dowiedzieć?
Thorsten Staerk,

1
Wiesz co? Myliłem się co do mapowania adresów 0x601000 - to prawdopodobnie kupa. Będziesz musiał go użyć readelflub objdumprozgryźć, i niezależnie od tego, jaki plik wykonywalny stworzyłeś. My Arch Linux korzysta z /usr/lib/libc-2.18.so, więc jest zupełnie inny niż twój box.
Bruce Ediger,

2
0x601000to segment danych. Zawiera on .data, .bssi może zostać przedłużony przez brk(). [anon]wskazuje pamięć nieopartą na plikach (tak zabezpieczoną przez swap), uzyskaną przez mmap(). dlmalloc używa brk()do przydziałów mniejszych niż ~ 64Kb IIRC oraz mmap()do większych przydziałów. Na stercie jest wszystko przydzielane przez malloc, zarówno rozszerzona część segmentu danych, jak i mmap()przydziały oparte na bazie .
ninjalj
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.