调用mmap后/proc/self/maps为何未显示新分配的内存映射
问题根因
你的mmap()调用实际执行失败了,没有创建任何新的内存映射,因此两次读取/proc/self/maps的输出完全一致。
代码里的核心错误:
- 传入
mmap()的文件描述符fd初始值为-1,且映射标志使用了MAP_SHARED。MAP_SHARED属于文件映射标志,要求必须传入有效、已打开的文件描述符,传入-1是非法参数,mmap()会直接返回MAP_FAILED(即(void*)-1),不会分配内存。 - 你没有检查
mmap()的返回值,误以为映射已经创建成功。
你可以在mmap()调用后增加错误校验,运行后就能看到明确的报错:
pa = mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if (pa == MAP_FAILED) { printf("mmap调用失败: %s\n", strerror(errno)); }
执行后会输出mmap调用失败: Bad file descriptor,对应无效文件描述符的错误。
正确测试方法
mmap()调用成功后,对应的内存区域一定会实时出现在/proc/self/maps中,不存在默认隐藏的情况。你可以根据测试场景调整mmap()参数,就能观测到对应映射:
- 测试匿名内存映射(不关联实体文件,最常用的堆外内存分配方式)
将映射标志改为MAP_PRIVATE | MAP_ANONYMOUS,文件描述符固定传-1即可:
映射成功后,pa = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (pa == MAP_FAILED) { // 错误处理 }/proc/self/maps中会出现一段权限为rw-p、inode值为0的4KB大小映射段,就是本次分配的匿名内存。 - 测试共享文件映射
先打开一个真实文件获取有效fd,提前将文件扩展到目标映射长度(避免后续访问触发SIGBUS信号),再调用mmap():
映射成功后,fd = open("test.tmp", O_RDWR|O_CREAT, 0644); ftruncate(fd, 4096); // 将文件大小设置为4KB pa = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (pa == MAP_FAILED) { // 错误处理 }/proc/self/maps中会出现一段权限为rw-s、关联到test.tmp文件inode的4KB映射段。
其他观测方式
如果需要查看更详细的内存映射属性,可以使用以下方式:
- 执行
pmap -x <进程pid>命令,可直接输出结构化的内存映射统计,包含映射的地址范围、权限、驻留内存大小、关联文件等信息,比直接读/proc/self/maps更易读。 - 读取
/proc/self/pagemap文件(需要root权限),可以获取每个虚拟内存页对应的物理页帧、页状态等底层信息,适合做深度内存分析。
内容的提问来源于stack exchange,提问作者Runner
相关产品推荐
相关产品推荐

