Linux中获取页属性

在Linux中,获取内存页属性(如可读、可写、可执行等)通常涉及查看进程的虚拟内存映射或物理页表信息。以下是几种常见方法:


1. 通过 /proc 文件系统获取虚拟内存映射

  • 路径/proc/[PID]/maps
    该文件记录了进程的虚拟内存区域(VMAs)及其属性(读/写/执行、共享/私有等)。
    示例

    1
    cat /proc/$$/maps  # 查看当前Shell进程的内存映射

    输出格式:
    address perms offset dev inode pathname
    例如:
    55a23d4d6000-55a23d4d7000 r--p 00000000 08:01 123456 /usr/bin/bash
    其中 perms 列表示权限(r=读, w=写, x=执行, s=共享, p=私有)。

  • 更详细的信息/proc/[PID]/smaps
    包含每个内存区域的详细统计(如物理页大小、脏页数量等)。


2. 使用命令行工具

  • pmap 命令
    显示进程的内存映射及属性:

    1
    pmap -X [PID]
  • vmmap 命令(部分系统需安装)
    macOS中常见,Linux下可用 pmap 替代。

  • gdb 调试器
    附加到进程并检查内存:

    1
    2
    gdb -p [PID]
    (gdb) info proc mappings

3. 物理页属性(需内核级操作)

  • 内核接口
    物理页属性通常通过页表项(Page Table Entries, PTE)的flags字段存储(如_PAGE_RW_PAGE_USER等)。普通用户无法直接读取,需内核模块或调试工具:
    • crash 工具:分析内核转储文件,查看页表项。
    • 编写内核模块:遍历页表并提取pte_flags()

4. 编程方式获取虚拟内存属性

通过解析 /proc/self/maps 或调用系统函数:

1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <unistd.h>

int main() {
char cmd[64];
sprintf(cmd, "cat /proc/%d/maps", getpid());
system(cmd);
return 0;
}


示例:查看进程的虚拟内存权限

1
2
3
4
5
# 查看进程1(init)的内存映射(需root权限)
sudo cat /proc/1/maps

# 使用pmap查看进程内存
pmap 1234 | less

注意事项

  • 虚拟内存属性是进程视角的权限,物理页的实际属性可能因共享或映射方式不同。
  • 修改页属性需使用mprotect()系统调用(编程实现)。

如果有更具体的需求(如物理页或NUMA信息),请进一步说明场景!