在OS X 10.5/10.6中检索自身进程的内存映射表

10
在Linux中,查看进程内存映射的最简单方法是查看/proc/PID/maps,会得到如下信息:
08048000-08056000 r-xp 00000000 03:0c 64593      /usr/sbin/gpm
08056000-08058000 rw-p 0000d000 03:0c 64593      /usr/sbin/gpm
08058000-0805b000 rwxp 00000000 00:00 0
40000000-40013000 r-xp 00000000 03:0c 4165       /lib/ld-2.2.4.so
40013000-40015000 rw-p 00012000 03:0c 4165       /lib/ld-2.2.4.so
4001f000-40135000 r-xp 00000000 03:0c 45494      /lib/libc-2.2.4.so
40135000-4013e000 rw-p 00115000 03:0c 45494      /lib/libc-2.2.4.so
4013e000-40142000 rw-p 00000000 00:00 0
bffff000-c0000000 rwxp 00000000 00:00 0
在OSX 10.5或10.6下,一个进程如何获取关于自身内存映射的等效信息(地址范围、保护、映射文件名等)?
4个回答

13

有一个MacFUSE实现的procfs。使用它,您可以按如下方式获取内存映射:

cat /proc/PID/task/vmmap

源代码来看,它似乎使用了Mach虚拟内存接口从内核中获取内存映射。

这是vmmap伪文件的实现:

/*
 * procfs as a MacFUSE file system for Mac OS X
 *
 * Copyright Amit Singh. All Rights Reserved.
 * http://osxbook.com
 *
 * http://code.google.com/p/macfuse/
 *
 * Source License: GNU GENERAL PUBLIC LICENSE (GPL)
 */
READ_HANDLER(proc__task__vmmap)
{
    int len = -1;
    kern_return_t kr;
#define MAX_VMMAP_SIZE 65536 /* XXX */
    char tmpbuf[MAX_VMMAP_SIZE];
    task_t the_task;
    pid_t pid = strtol(argv[0], NULL, 10);

    kr = task_for_pid(mach_task_self(), pid, &the_task);
    if (kr != KERN_SUCCESS) {
        return -EIO;
    }

    vm_size_t vmsize;
    vm_address_t address;
    vm_region_basic_info_data_t info;
    mach_msg_type_number_t info_count;
    vm_region_flavor_t flavor;
    memory_object_name_t object;

    kr = KERN_SUCCESS;
    address = 0;
    len = 0;

    do {
        flavor = VM_REGION_BASIC_INFO;
        info_count = VM_REGION_BASIC_INFO_COUNT;
        kr = vm_region(the_task, &address, &vmsize, flavor,
                       (vm_region_info_t)&info, &info_count, &object);
        if (kr == KERN_SUCCESS) {
            if (len >= MAX_VMMAP_SIZE) {
                goto gotdata;
            }
            len += snprintf(tmpbuf + len, MAX_VMMAP_SIZE - len,
            "%08x-%08x %8uK %c%c%c/%c%c%c %11s %6s %10s uwir=%hu sub=%u\n",
                            address, (address + vmsize), (vmsize >> 10),
                            (info.protection & VM_PROT_READ)        ? 'r' : '-',
                            (info.protection & VM_PROT_WRITE)       ? 'w' : '-',
                            (info.protection & VM_PROT_EXECUTE)     ? 'x' : '-',
                            (info.max_protection & VM_PROT_READ)    ? 'r' : '-',
                            (info.max_protection & VM_PROT_WRITE)   ? 'w' : '-',
                            (info.max_protection & VM_PROT_EXECUTE) ? 'x' : '-',
                            inheritance_strings[info.inheritance],
                            (info.shared) ? "shared" : "-",
                            behavior_strings[info.behavior],
                            info.user_wired_count,
                            info.reserved);
            address += vmsize;
        } else if (kr != KERN_INVALID_ADDRESS) {

            if (the_task != MACH_PORT_NULL) {
                mach_port_deallocate(mach_task_self(), the_task);
            }

            return -EIO;
        }
    } while (kr != KERN_INVALID_ADDRESS);

gotdata:

    if (the_task != MACH_PORT_NULL) {
        mach_port_deallocate(mach_task_self(), the_task);
    }

    READ_PROC_TASK_EPILOGUE();
}

1
这看起来非常不错,我可能会在运行一些测试后接受它。 - Sufian
现在可以在 https://github.com/osxfuse/filesystems/blob/aee39765ffe32b426a1089f617d21bff387f5c91/filesystems-c/procfs/procfs.cc#L3364 找到此内容。 - bgamari

2
GNUlib(http://www.gnu.org/software/gnulib/)包含一个函数,可在大多数操作系统中(包括MAC OS X)迭代所有虚拟内存段。该函数位于vma-iter.c文件中。

2
请看2007年《达尔文内核邮件列表》的此线程,简而言之,您有两种选择:popen vmmap(已适当地设置了setgid),或使用/usr/include/mach/mach_vm.h中的Mach VM区域API。我在Sage数学系统源代码中找到了一个不错的Mach API使用示例。

谢谢您的主题,我想在所有OSX版本上实现可移植性并不容易。 - Sufian
更新的Sage链接:http://trac.sagemath.org/sage_trac/browser/sage/misc/darwin_memory_usage.c - Nickolay
更新的链接:http://wstein.org/home/tornaria/sage-4.1.alpha2.sagemath_only-x86_64-Linux/devel/sage-main/sage/misc/darwin_memory_usage.c - Sebastian Z
以上所有链接均已失效。这是另一个链接,希望能够长期存在:https://github.com/sagemath/sagelib/blob/master/sage/misc/darwin_memory_usage.c - EmeryBerger


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接