Saya menulis main.c
di 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 VIRT
kolom dalam output dari top
. Sekarang di mana segmen teks? Pada 400000, 600000 dan 601000, kan? Di mana saya bisa membaca penjelasan di mana? man pmap
tidak membantu.
linux
process
memory
virtual-memory
Thorsten Staerk
sumber
sumber
Jawaban:
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:
nm
danobjdump -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 -x
memperlihatkan 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
readelf
perintah. Jika Anda dapat menulis program C, buat versi Anda sendiriobjdump -x
ataureadelf
untuk menjadi terbiasa dengan cara kerja file yang dapat dieksekusi, dan apa yang ada di dalamnya.sumber
readelf
atauobjdump
mencari 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.0x601000
adalah segmen data. Ini berisi.data
,.bss
dan dapat diperpanjang melaluibrk()
.[anon]
menunjukkan memori yang didukung file (didukung oleh swap), diperoleh melaluimmap()
. dlmalloc digunakanbrk()
untuk alokasi yang lebih kecil dari ~ 64Kb IIRC, danmmap()
untuk alokasi yang lebih besar. Heap adalah semua yang dialokasikan oleh malloc, baik bagian yang diperluas dari segmen data, danmmap()
alokasi yang berbasis.