在 Linux 中,当我访问特定程序的 /proc 时,它会在映射文件中显示该程序的内存映射。
像这样的东西:
address perms offset dev inode pathname
00400000-00452000 r-xp 00000000 08:02 173521 /usr/bin/dbus-daemon
00651000-00652000 r--p 00051000 08:02 173521 /usr/bin/dbus-daemon
00652000-00655000 rw-p 00052000 08:02 173521 /usr/bin/dbus-daemon
00e03000-00e24000 rw-p 00000000 00:00 0 [heap]
00e24000-011f7000 rw-p 00000000 00:00 0 [heap]
...
35b1800000-35b1820000 r-xp 00000000 08:02 135522 /usr/lib64/ld-2.15.so
35b1a1f000-35b1a20000 r--p 0001f000 08:02 135522 /usr/lib64/ld-2.15.so
35b1a20000-35b1a21000 rw-p 00020000 08:02 135522 /usr/lib64/ld-2.15.so
35b1a21000-35b1a22000 rw-p 00000000 00:00 0
35b1c00000-35b1dac000 r-xp 00000000 08:02 135870 /usr/lib64/libc-2.15.so
35b1dac000-35b1fac000 ---p 001ac000 08:02 135870 /usr/lib64/libc-2.15.so
35b1fac000-35b1fb0000 r--p 001ac000 08:02 135870 /usr/lib64/libc-2.15.so
35b1fb0000-35b1fb2000 rw-p 001b0000 08:02 135870 /usr/lib64/libc-2.15.so
...
f2c6ff8c000-7f2c7078c000 rw-p 00000000 00:00 0 [stack:986]
...
7fffb2c0d000-7fffb2c2e000 rw-p 00000000 00:00 0 [stack]
7fffb2d48000-7fffb2d49000 r-xp 00000000 00:00 0 [vdso]
我想知道映射到内核堆栈或用户堆栈的[堆栈]内存是什么,以及如何访问该内存区域内的内容?
/proc 目录中还有另一个名为 stack 的文件,但正如 proc(5) 的手册页所确认的那样,它是内核堆栈
另外,我想知道为什么这个进程映射中有2个[堆]?
我还检查了进程所有线程的 [stack] 地址范围,发现它们对于所有线程都是相同的。当线程不共享堆栈时,这怎么可能?
答案1
堆栈条目描述于man 5 proc
:[stack]
是主线程的堆栈,[stack:986]
是线程986的堆栈。自 4.5 以来,后者在内核上不再可见。这也解决了您的最后一个问题:[stack]
仅由主线程使用,每个其他线程在不同的地址处都有不同的堆栈。您可以像访问给定进程中映射的任何其他内存一样访问堆栈。
我主要是在这里猜测,但这两个堆可以解释为事实上,brk
最终可能会分配一个新的 VMA;这应该显示为 中的单独条目/proc/…/maps
。但请注意,虚拟地址始终是连续的。