如何根据进程PID查询其占用内存页列表及属性,含GDB实现方案
根据进程PID查询内存页列表的方法
前置说明
你提到的4KB内存页起始地址末尾12个比特位为0的判断是正确的:4KB=2^12字节,内存页按4KB对齐时,起始地址必须是4096的整数倍,对应二进制低12位全为0。
通用Linux环境查询方案
不需要额外工具,直接读取进程的proc文件系统即可:
- 执行命令:
cat /proc/<替换为目标PID>/maps - 输出每一行对应一段连续的、权限属性相同的内存区域,格式为:
起始地址-结束地址 权限 偏移 设备号 inode 关联文件路径 - 权限位共4位,第二位为
w表示可写,第三位为x表示可执行,完全匹配你的查询需求 - 如果需要拆分到单个4KB页,只需将每段的起始地址按4KB步长递增直到段结束地址即可,拆分后所有页的权限和所属段的权限一致
示例输出说明:
示例行:
55f8d79c9000-55f8d79cb000 r--p 00000000 103:02 131476 /usr/bin/bash
该段大小为8KB,包含2个4KB页,起始地址分别为0x55f8d79c9000、0x55f8d79ca000,权限为只读、不可写、不可执行。
GDB调试场景查询方案
如果你已经用GDB attach到目标进程或者直接启动调试目标,可以用以下两种方式获取:
1. 直接执行内置命令
在GDB交互界面执行:info proc mappings,输出格式和/proc/[pid]/maps完全一致,可直接查看内存段的地址和权限。
2. 用Python API批量输出单页信息
如果需要直接得到拆分后的所有4KB页的信息,可以在GDB中执行Python脚本批量处理:
import gdb PAGE_SIZE = 4096 # 跳过info proc mappings输出的前4行表头 map_lines = gdb.execute("info proc mappings", to_string=True).splitlines()[4:] for line in map_lines: line = line.strip() if not line: continue parts = line.split() start = int(parts[0], 16) end = int(parts[1], 16) perm = parts[2] # 遍历当前段内所有4KB页 cur = start while cur < end: print(f"页起始地址:0x{cur:x},权限:{perm},可写:{'是' if 'w' in perm else '否'},可执行:{'是' if 'x' in perm else '否'}") cur += PAGE_SIZE
操作方式:在GDB交互界面输入python回车,粘贴上述代码后按Ctrl+D即可执行,直接输出所有符合要求的内存页信息。
内容的提问来源于stack exchange,提问作者Aaa Bbb
相关产品推荐
相关产品推荐

