info proc mappings的核心作用是查看进程当前虚拟内存布局,用于定位段错误、非法访问及库加载异常等问题,其输出反映内核维护的/proc/[pid]/maps快照,每行含地址范围、权限与映射源三要素。

info proc mappings 的核心作用是查看进程当前的虚拟内存布局,不是“查有没有堆”或“看用了多少内存”,而是定位段错误、非法访问、库加载异常等问题的起点。它输出的是内核维护的 /proc/[pid]/maps 快照,每一行都对应一个内存映射区域,关键在“地址范围 + 权限 + 映射源”的组合是否合理。
怎么看懂 info proc mappings 的输出格式
典型输出长这样(64位系统):
0x555555554000 0x555555555000 0x1000 0x0 r--p /path/to/program 0x7ffff7d86000 0x7ffff7d89000 0x3000 0x0 rw-p 0x7ffff7f9e000 0x7ffff7fa2000 0x4000 0x214000 r--p /usr/lib/x86_64-linux-gnu/libc.so.6 0x7ffffffde000 0x7ffffffff000 0x21000 0x0 rw-p [stack]
每列含义:
-
StartAddr和EndAddr:该段起止虚拟地址(必须用十六进制理解) -
Size:段大小(EndAddr - StartAddr),单位字节 -
Offset:在映射文件中的偏移(对[heap]或[stack]为 0) -
Perms:权限标记,r/w/x/p分别代表可读、可写、可执行、私有;s表示共享(少见) -
objfile:映射来源,可能是可执行文件、so 库、[heap]、[stack]、[vdso]等
重点看权限是否匹配操作:比如尝试向 r-xp 段写入 → 段错误;解引用 NULL(地址 0)→ 查不到任何映射(第一个有效地址通常是 0x400000)→ 段错误。
什么时候必须用 info proc mappings 定位问题
它不是日常命令,而是在以下场景中不可替代:
- 崩溃后
bt显示地址不在任何已知函数范围内(例如0x7ffff7a12345),需确认该地址落在哪个段、是否有写权限 - 怀疑
malloc返回地址属于非法区域(比如落在.text段里),对比[heap]范围和分配地址 - 动态库加载失败或符号解析异常,检查
.so是否真被映射、权限是否为r-xp(缺x就不能执行函数) - 多线程栈溢出,观察多个
[stack]区域是否重叠或过于接近其他段(如[heap]) - 使用
mmap分配的内存行为异常,确认映射参数(PROT_READ|PROT_WRITE)是否与Perms一致
常见误用和坑点
这个命令容易被当成“内存快照工具”,但实际限制很多:
- 只在 GDB attach 或 run 后的**当前时刻**生效;程序继续运行后映射可能变化(如
brk扩展堆、mmap新增段),需重新执行 - 不显示未映射的“空洞”区域(比如两个段之间有 1GB 间隙),但这些间隙访问也会段错误——要意识到“没列出 = 不可访问”
- 权限
p(私有)和s(共享)不影响段错误判断,但影响fork后的写时复制行为,调试fork相关 bug 时需留意 - 在容器或 chroot 环境中,
objfile路径可能不可达,但地址和权限仍可信;不要因为路径不存在就忽略该行 -
[heap]段通常只有一条,但 glibc 实际使用arena管理多个堆块,info proc mappings看不到内部结构,需配合malloc_stats或heap命令(需安装glibc-source)
结合其他命令才能闭环分析
info proc mappings 单独用价值有限,必须联动:
- 看到崩溃地址
0x7ffff7a12345→ 先info proc mappings找它属于哪一行 → 再x/4i 0x7ffff7a12345看是不是有效指令 - 怀疑堆损坏 → 先
info proc mappings确认[heap]范围 → 再x/20wx <heap_start></heap_start>查看malloc管理头信息(如fastbin链表) - 发现某
.so权限是r--p(缺x)→ 很可能被mprotect错误修改过,或加载时 flags 设错 - 调试
fork后子进程段错误 → 必须先set follow-fork-mode child,再info proc mappings,否则看到的是父进程映射
真正容易被忽略的是:它反映的是内核视角的映射状态,和用户代码的“逻辑预期”之间常有 gap——比如你认为某指针该指向堆,但 info proc mappings 显示它落在 [stack] 段末尾,那大概率是栈溢出覆盖了返回地址,而不是堆分配错了。











