info proc mappings 是唯一可靠、直接、无需额外符号或内核支持的查看进程内存映射方式,输出内核 /proc/[pid]/maps 实时快照,包含地址范围、权限、映射来源等完整信息,适用于排查段错误、堆栈越界等问题。

info proc mappings 是唯一可靠、直接、无需额外符号或内核支持的查看进程内存映射方式。它输出的是内核 /proc/[pid]/maps 的实时快照,比 info files 或 info target 更底层、更完整,尤其适合排查段错误、堆栈越界、库加载异常等内存类问题。
为什么必须用 info proc mappings 而不是其他命令
很多人误以为 info files 或 info target 也能看内存布局,但它们只列出加载的可执行文件和共享库路径,不包含地址范围、权限标记(如 r-xp)、是否为 [heap] 或 [stack] 等关键信息。而 info proc mappings 输出每一行都对应一个虚拟内存区域,字段含义明确:
-
StartAddr和EndAddr:该区域起止虚拟地址 -
Size:大小(十六进制) -
Offset:在映射文件中的偏移(对匿名映射为 0) -
Perms:权限,如rwxp(可读/写/执行/私有),---p表示不可访问 -
objfile:映射来源,可能是可执行文件、libc.so.6、[heap]、[stack]或[vdso]
没有这个输出,你根本无法判断某次 segfault 是踩到了栈溢出、堆损坏,还是误写了只读代码段。
info proc mappings 必须在进程运行中执行
这条命令不能在 GDB 启动后、run 前使用——此时进程还没创建,/proc/[pid]/maps 不存在,GDB 会报错 No process is being debugged 或 process not available。正确时机是:
- 已
run或continue进入运行态(哪怕只执行了一条指令) - 或已在某个断点处暂停(如
break main后run) - 或程序因信号(如
SIGSEGV)自动中断时
常见错误是刚启动 GDB 就敲 i proc mappings,结果空屏或报错,然后怀疑命令失效——其实是时机错了。
如何快速定位关键内存区域
输出通常几十行,手动翻找效率低。重点关注以下几类行:
- 含
[heap]的行:堆的起始地址(如0x555555559000),malloc分配的内存都在此范围内;若看到堆区被mprotect改为不可写,可能触发后续free失败 - 含
[stack]的行:栈顶通常在高地址(如0x7ffffffde000),大小约 8MB;若发现栈区Size异常小(如仅0x1000),说明可能已被耗尽 - 权限为
---p的行:这是“空洞”,任何访问都会触发segfault;如果崩溃地址落在这个区间,基本就是野指针解引用 - 多个
libc.so.6映射段:确认是否加载了多个版本(比如 LD_PRELOAD 干扰),可能导致malloc行为不一致
可以用 grep 辅助(需 GDB 支持 shell):shell grep "\[heap\]" /proc/$(pidof your_program)/maps,但不如直接在 GDB 中执行 i proc mappings 可靠,因为进程 PID 可能变动。
容易忽略的权限细节和陷阱
权限列(Perms)里的第四个字符看似不起眼,却决定行为差异:
-
p(private):写时复制,修改不会影响原始文件 —— 绝大多数映射都是这个 -
s(shared):修改会同步回文件或被其他进程看到 —— mmap(MAP_SHARED) 才会出现 - 缺失
p或s:极少见,通常表示内核映射异常,需警惕
另外,[vdso] 和 [vvar] 区域权限通常是 r--p,但它们由内核动态生成,地址每次运行都变;如果调试时发现崩溃地址落在 0xffffffffff600000 附近,别急着查代码——先确认是不是 vdso 调用失败(比如系统调用号错乱)。


















