能否为非文件后端mmap区域设置proc/maps可显示的自定义名称
匿名mmap自定义/proc/maps标识实现说明
核心结论
你想要的效果完全可以通过Linux原生接口实现,最终展示形式和你示例里的[New VMA area]完全一致。
从Linux 5.15版本开始,内核正式提供了针对匿名VMA(无文件后端的mmap区域)的自定义命名能力,设置完成后,名称会直接展示在/proc/[pid]/maps对应内存行的末尾。
具体实现规则
直接使用prctl系统调用即可完成设置,无需root权限、无需自定义内核:
- 固定调用格式:
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, 内存起始地址, 生效长度, 自定义名称字符串指针) - 内核会自动在展示时给名称补上两侧的方括号,传入名称时不需要手动加
[] - 名称最长支持80个字符,超出部分会被内核自动截断
- 仅匿名VMA可以使用这个接口设置名称,基于文件映射的内存区域无法通过该方式修改标识
兼容性处理
- 系统glibc版本低于2.35时,不会内置上述两个prctl命令的宏定义,可以手动补充固定宏值,只要运行环境的内核版本≥5.15就能正常调用:
#define PR_SET_VMA 0x53564d00 #define PR_SET_VMA_ANON_NAME 0
- 内核版本低于5.15的系统没有官方支持的通用命名接口,历史上Chrome、HotSpot虚拟机等程序曾通过非公开的内核机制实现类似效果,但这类方案没有跨版本兼容性,不建议在新代码中采用。
最小代码示例
#include <sys/mman.h> #include <sys/prctl.h> #include <unistd.h> // 适配老版本glibc的宏定义 #ifndef PR_SET_VMA #define PR_SET_VMA 0x53564d00 #define PR_SET_VMA_ANON_NAME 0 #endif int main() { // 申请10页大小的匿名mmap区域 const size_t area_size = 4096 * 10; void* area = mmap( NULL, area_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 ); // 给区域设置自定义名称 prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, area, area_size, "My custom mmap buffer"); // 保持进程存活,方便查看maps输出 sleep(300); return 0; }
编译运行上述程序后,在/proc/[pid]/maps中就能看到对应内存行的末尾展示[My custom mmap buffer],和示例中的标识效果完全一致。
注意:调用时如果传入的内存范围没有对齐VMA边界,内核会自动对齐到相邻的VMA边界,不会拆分已有的内存映射区域。
内容的提问来源于stack exchange,提问作者xiaogw
相关产品推荐
相关产品推荐

