【问题标题】:How to identify STACK and HEAP segments in /proc/$PID/maps file?如何识别 /proc/$PID/maps 文件中的 STACK 和 HEAP 段?
【发布时间】:2013-10-15 11:12:01
【问题描述】:

我可以识别 /proc/$PID/maps 文件中的文本、ds 和 bss 段(通过猜测或借助特定段的访问说明符)。但是堆和堆栈段是依次给出的。有没有办法识别哪个段属于栈,哪个属于堆?

-----本例中如何识别堆和栈的分界 ---------- 0a8a0000-0ab2e000 rw-p 0a8a0000 00:00 0 [堆]

【问题讨论】:

  • 堆栈段是唯一标记为[stack]。几乎按照定义,每个其他可写段都是堆。否则,请给我们您对 heap 的准确定义
  • “Segment”是 20 年前相关的术语。任何现代系统都比文献给出的简单的“代码/数据/堆/堆栈段”描述复杂得多。在线程应用程序中,您将拥有与线程一样多的堆栈,堆不必是连续的,您将拥有大量与代码、只读数据和辅助数据以及来自共享库的 PLT 和 GOT 混合的数据,内存映射文件、内核维护的特殊代码映射、保护页等

标签: c linux proc


【解决方案1】:

/proc/PID/maps 文件包含当前映射的内存区域和 他们的访问权限。

格式为:

address           perms offset  dev   inode      pathname

08048000-08049000 r-xp 00000000 03:00 8312       /opt/test
08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
a7cb1000-a7cb2000 ---p 00000000 00:00 0
a7cb2000-a7eb2000 rw-p 00000000 00:00 0
a7eb2000-a7eb3000 ---p 00000000 00:00 0
a7eb3000-a7ed5000 rw-p 00000000 00:00 0          [stack:1001]
a7ed5000-a8008000 r-xp 00000000 03:00 4222       /lib/libc.so.6
a8008000-a800a000 r--p 00133000 03:00 4222       /lib/libc.so.6
a800a000-a800b000 rw-p 00135000 03:00 4222       /lib/libc.so.6
a800b000-a800e000 rw-p 00000000 00:00 0
a800e000-a8022000 r-xp 00000000 03:00 14462      /lib/libpthread.so.0
a8022000-a8023000 r--p 00013000 03:00 14462      /lib/libpthread.so.0
a8023000-a8024000 rw-p 00014000 03:00 14462      /lib/libpthread.so.0
a8024000-a8027000 rw-p 00000000 00:00 0
a8027000-a8043000 r-xp 00000000 03:00 8317       /lib/ld-linux.so.2
a8043000-a8044000 r--p 0001b000 03:00 8317       /lib/ld-linux.so.2
a8044000-a8045000 rw-p 0001c000 03:00 8317       /lib/ld-linux.so.2
aff35000-aff4a000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]

其中“address”是它占用的进程中的地址空间,“perms” 是一组权限:

r = read
 w = write
 x = execute
 s = shared
 p = private (copy on write)

“offset”是映射中的偏移量,“dev”是设备(主要:次要),并且 “inode”是该设备上的 inode。 0 表示没有关联的 inode 使用内存区域,就像使用 BSS(未初始化数据)一样。 “路径名”显示此映射的名称关联文件。如果映射 未与文件关联:

 [heap]                   = the heap of the program
 [stack]                  = the stack of the main process
 [stack:1001]             = the stack of the thread with tid 1001
 [vdso]                   = the "virtual dynamic shared object",
                            the kernel system call handler

如果为空,则映射是匿名的。 (来源https://www.kernel.org/doc/Documentation/filesystems/proc.txt

【讨论】:

  • 你的意思是说只有那些被标记为'[heap]'的段/页面属于堆段吗?但是@basile-starynkevitch 说只有那些标记为“[stack]”的段/页面属于堆栈,而所有其他属于堆段?我很困惑...
  • 如果任务将其视为堆栈,您将看到标记 [stack]。如果它的堆将显示为 [heap] ...。文档清楚地提到了这一点。
  • 如果是这样,那么操作系统为什么要为一个进程(堆栈和堆除外)分配这么多“匿名段”?
  • 其实“匿名”显示不属于任何文件的内存量。甚至与文件关联的映射也可能包含匿名页面:当 MAP_PRIVATE 和页面被修改时,文件页面被私有匿名副本替换。 “Swap”显示了多少可能是匿名的内存也被使用了,但是在swap上。如果它是匿名的,我们可以认为块特别地属于内核空间。
  • 操作系统为什么要分配不属于任何文件的内存?分配这些段有什么意义?我们从操作系统(来自我们的代码)请求的内存与“匿名”分配的内存量有何关系?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-20
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多