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,这也可能会提供一些见解。
要在可执行文件上运行的其他内容:nm和objdump -x. 前者可以让您了解内存映射中的各种内容,因此您可以查看 0x4000000 部分与其他部分中的内容。objdump -x向您显示 ELF 文件头以及许多其他内容,因此您可以查看所有部分,包括部分名称以及它们是否在运行时映射。
至于找到“什么是哪里”的书面解释,你必须像谷歌一样搜索“ELF FILE内存布局”。请注意,ELF 文件格式可以支持比通常使用的更奇特的内存布局。GCC 和 Gnu ld 以及 glibc 都简化了关于可执行文件如何在运行时布局然后映射到内存的假设。有许多网页声称记录了这一点,但仅适用于旧版 Linux、旧版 GCC 或 glibc,或仅适用于 x86 可执行文件。如果您没有它,请获取readelf命令。如果您可以编写 C 程序,请创建您自己的版本objdump -x或readelf熟悉可执行文件的工作方式以及其中的内容。