Arti output dari pmap

12

Saya menulis main.cdi Linux:

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

Ketika saya kompilasi dan memulainya, saya bisa 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) dibagi dengan K sama dengan VIRTkolom dalam output dari top. Sekarang di mana segmen teks? Pada 400000, 600000 dan 601000, kan? Di mana saya bisa membaca penjelasan di mana? man pmaptidak membantu.

Thorsten Staerk
sumber
segmen teks sebenarnya hanya baca, jadi di 0000000000600000.
Danila Ladner
Terima kasih! Bukankah seharusnya segmen teks juga dapat dieksekusi?
Thorsten Staerk
1
Ya kamu benar. r dan rx. 0000000000400000 juga.
Danila Ladner

Jawaban:

14

Segmen teks adalah pemetaan pada 0x400000 - ini ditandai 'rx' untuk dibaca dan dieksekusi. Pemetaan di 0x600000 hanya-baca, jadi itu hampir pasti bagian ".rodata" dari file yang dapat dieksekusi. GCC menempatkan literal string C ke dalam bagian read-only. Pemetaan di 0x601000 adalah 'rw-', jadi itu mungkin tumpukan yang terkenal. Anda dapat memiliki malloc()1024 byte yang dapat dieksekusi dan mencetak alamat untuk melihat dengan pasti.

Anda mungkin mendapatkan sedikit lebih banyak informasi dengan menemukan PID proses Anda, dan melakukan: cat /proc/$PID/maps- pada laptop Arch saya, yang memberikan beberapa info tambahan. Ini menjalankan kernel 3,12, begitu juga /proc/$PID/numa_maps, dan catting yang mungkin memberikan wawasan kecil juga.

Hal-hal lain untuk dijalankan pada file yang dapat dieksekusi: nmdan objdump -x. Yang pertama dapat memberi Anda gambaran di mana berbagai hal berada di peta memori, sehingga Anda dapat melihat apa yang ada di bagian 0x4000000 vs bagian lainnya. objdump -xmemperlihatkan kepada Anda header file ELF di antara banyak hal lain, sehingga Anda dapat melihat semua bagian, lengkap dengan nama bagian dan apakah dipetakan dalam jangka waktu berjalan atau tidak.

Sejauh menemukan penjelasan tertulis tentang "di mana", Anda harus melakukan hal-hal seperti google untuk "tata letak memori ELF FILE". Perlu diketahui bahwa format file ELF dapat mendukung tata letak memori yang lebih eksotis daripada yang biasa digunakan. GCC dan Gnu ld dan glibc semuanya membuat asumsi penyederhanaan tentang bagaimana file yang dapat dieksekusi diletakkan dan kemudian dipetakan ke dalam memori pada saat run time. Ada banyak halaman web yang dimaksudkan untuk mendokumentasikan ini, tetapi hanya berlaku untuk versi Linux yang lebih lama, versi GCC atau glibc yang lebih lama, atau hanya berlaku untuk executable x86. Jika Anda tidak memilikinya, dapatkan readelfperintah. Jika Anda dapat menulis program C, buat versi Anda sendiri objdump -xatau readelfuntuk menjadi terbiasa dengan cara kerja file yang dapat dieksekusi, dan apa yang ada di dalamnya.

Bruce Ediger
sumber
2
Jawaban yang bagus Sekarang, di mana tumpukan program? Dan apa artinya [anon] ini? Apa yang harus saya lakukan di google untuk mengetahuinya?
Thorsten Staerk
1
Kamu tahu apa? Saya salah tentang pemetaan alamat 0x601000 - itulah heapnya, mungkin. Anda harus menggunakan readelfatau objdumpmencari tahu, dan apa pun yang dapat dieksekusi yang telah Anda buat. Kotak Arch Linux saya menggunakan /usr/lib/libc-2.18.so, jadi sangat berbeda dari kotak Anda.
Bruce Ediger
2
0x601000adalah segmen data. Ini berisi .data, .bssdan dapat diperpanjang melalui brk(). [anon]menunjukkan memori yang didukung file (didukung oleh swap), diperoleh melalui mmap(). dlmalloc digunakan brk()untuk alokasi yang lebih kecil dari ~ 64Kb IIRC, dan mmap()untuk alokasi yang lebih besar. Heap adalah semua yang dialokasikan oleh malloc, baik bagian yang diperluas dari segmen data, dan mmap()alokasi yang berbasis.
ninjalj