pmap输出的意义

Tho*_*erk 13 linux process memory virtual-memory

main.c在 Linux 中写道:

int main()
{
  while (1){}
}
Run Code Online (Sandbox Code Playgroud)

当我编译并启动它时,我可以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
Run Code Online (Sandbox Code Playgroud)

总计 (3876) 除以 K 等于VIRT输出中的列top。现在文本段在哪里?在 400000、600000 和 601000,对吧?我在哪里可以阅读解释 what is where?man pmap没有帮助。

Bru*_*ger 15

文本段是 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内存布局”。请注意,ELF 文件格式可以支持比通常使用的更奇特的内存布局。GCC 和 Gnu ld 以及 glibc 都简化了关于可执行文件如何在运行时布局然后映射到内存的假设。有许多网页声称记录了这一点,但仅适用于旧版 Linux、旧版 GCC 或 glibc,或仅适用于 x86 可执行文件。如果您没有它,请获取readelf命令。如果您可以编写 C 程序,请创建您自己的版本objdump -xreadelf熟悉可执行文件的工作方式以及其中的内容。

  • 很好的答案。现在,程序的堆在哪里?这 [ anon ] 是什么意思?我需要谷歌什么才能找到这个? (2认同)
  • `0x601000` 是数据段。它包含`.data`、`.bss`并且可以通过`brk()`进行扩展。`[anon]` 表示通过 `mmap()` 获得的非文件支持的内存(因此由交换支持)。dlmalloc 使用 `brk()` 分配小于 ~64Kb IIRC,使用 `mmap()` 进行更大的分配。堆是 malloc 分配的所有内容,包括数据段的扩展部分和基于 `mmap()` 的分配。 (2认同)