macOS下为何libproc仅显示一个内存映射区域?
问题分析与解决
你的代码仅输出自身二进制的内存映射,核心原因及解决方法如下:
1. 缓冲区容量不足且未循环读取
你只分配了20个struct proc_regionwithpathinfo的数组作为缓冲区,但macOS进程的内存映射数量远多于这个值(仅系统库、堆、栈等就会有几十个)。proc_pidinfo会在缓冲区不足以容纳所有数据时,只返回当前能放下的部分内容。
同时,proc_pidinfo的第三个参数是偏移量:当第一次调用返回的字节数等于缓冲区大小时,说明还有更多数据待读取,必须循环调用该函数,每次传入上一次返回的总字节数作为新偏移量,直到返回值小于缓冲区大小或出错。
2. 补充说明
PROC_PIDREGIONPATHINFO仅返回带有文件路径关联的内存区域,进程还包含匿名映射(如堆、栈、动态分配的匿名内存),但你的问题中连libSystem.B.dylib这类有路径的库都未显示,核心矛盾还是缓冲区和循环读取的问题。
修复后的代码
#include <stdio.h> #include <unistd.h> #include <libproc.h> #include <stdlib.h> int main() { int ret; size_t offset = 0; struct proc_regionwithpathinfo *info = NULL; // 初始分配足够大的缓冲区,可根据实际情况调整 size_t buffer_size = 100 * sizeof(struct proc_regionwithpathinfo); info = malloc(buffer_size); if (!info) { perror("malloc"); return 1; } while (1) { ret = proc_pidinfo(getpid(), PROC_PIDREGIONPATHINFO, offset, info, buffer_size); if (ret < 0) { perror("proc_pidinfo"); free(info); return 1; } if (ret == 0) break; // 无更多数据可读取 int num = ret / sizeof(struct proc_regionwithpathinfo); for (int k = 0; k < num; k++) { struct proc_regionwithpathinfo *region = &info[k]; printf("0x%016llx - 0x%016llx\n", region->prp_prinfo.pri_address, region->prp_prinfo.pri_address + region->prp_prinfo.pri_size); if (region->prp_vip.vip_path[0]) { printf("\tPath = %s\n", region->prp_vip.vip_path); } } offset += ret; // 更新偏移量,读取下一批数据 } free(info); return 0; }
验证说明
编译运行修复后的代码,你会看到libSystem.B.dylib、dyld等系统库的内存映射路径,以及进程自身的其他关联区域。
内容的提问来源于stack exchange,提问作者Daniel Walker
相关产品推荐
相关产品推荐

