pmap输出的含义


12

main.c在Linux中写道:

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

当我编译并启动它时,我可以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)除以K等于VIRT输出中的列top。现在,文本段在哪里?分别是400000、600000和601000,对吗?在哪里可以阅读解释,哪里是?man pmap没有帮助。


文本段实际上是只读的,因此它是0000000000600000。
Danila Ladner 2013年

谢谢!文本段也不应该也是可执行的吗?
Thorsten Staerk

1
你是对的。r和rx。以及0000000000400000。
Danila Ladner 2013年

Answers:


14

文本段是0x400000处的映射-标记为“ rx”以表示可读性和可执行性。0x600000处的映射是只读的,因此几乎可以肯定是可执行文件的“ .rodata”部分。GCC将C字符串文字放入只读部分。0x601000处的映射为“ rw-”,因此可能是著名的堆。您可以将您的可执行文件设置为malloc()1024字节,并打印出地址以确认。

通过查找过程的PID并执行以下操作,您可能会获得更多信息:cat /proc/$PID/maps-在我的Arch笔记本电脑上,它提供了一些额外的信息。它运行的是3.12内核,因此它也具有/proc/$PID/numa_maps和catting,这可能也会给您带来一点见识。

在可执行文件上运行的其他内容:nmobjdump -x。前者可以让您了解各种事物在内存映射中的位置,因此您可以看到0x4000000部分与其他部分中的内容。objdump -x向您显示ELF文件头以及许多其他内容,因此您可以查看所有节,包括节名以及是否在运行时映射它们。

只要找到“什么在哪里”的书面说明,您就必须为“ ELF FILE memory layout”做类似google的事情。请注意,ELF文件格式可以支持比通常使用的更多的特殊内存布局。GCC和Gnu ld和glibc都对可执行文件的布局进行了简化的假设,然后在运行时将其映射到内存中。有许多网页旨在证明这一点,但是仅适用于Linux的较早版本,GCC或glibc的较旧版本,或者仅适用于x86可执行文件。如果没有,请获取readelf命令。如果您可以编写C程序,请创建您自己的版本objdump -xreadelf熟悉可执行文件的工作方式以及其中的内容。


2
好答案。现在,程序的堆在哪里?这个[anon]是什么意思?我必须要用谷歌才能找到这个吗?
Thorsten Staerk 2013年

1
你知道吗?我对0x601000地址映射有误-可能就是堆。您必须使用readelfobjdump弄清楚它,以及所生成的任何可执行文件。我的Arch linux机器使用/usr/lib/libc-2.18.so,因此与您的机器完全不同。
Bruce Ediger 2013年

2
0x601000是数据段。它包含.data.bss并且可以通过扩展brk()[anon]表示非文件支持的内存(因此通过交换支持),通过获取mmap()。dlmalloc brk()用于小于约64Kb IIRC的mmap()分配以及较大的分配。堆是malloc分配的所有内容,包括数据段的扩展部分和mmap()基于-的分配。
ninjalj 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.