2009-10-27 14 views
9

In Linux, ist die einfachste Art und Weise in einem Prozess Speicherkarte zu suchen ist auf /proc/PID/maps suchen, so etwas wie diesen gibt: kanndie Speicherkarte von einem eigenen Prozess in OS Abrufen von X 10.5/10.6

 
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 

Wie ein Prozess die äquivalenten Informationen (Adressbereiche, Schutz, abgebildeter Dateiname, etc ...) über eine prozesseigene Memory Map unter OSX 10.5 oder 10.6 erhält?

Antwort

12

Es gibt eine MacFUSE implementation of procfs. Mit ihm können Sie die Speicherkarte erhalten wie folgt:

cat /proc/PID/task/vmmap 

Mit Blick auf die source code, es sieht aus wie es die Mach virtual memory interface ist mit der Speicherkarte aus dem Kernel zu bekommen.

Hier ist die Implementierung für die vmmap Pseudo:

/* 
* 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(); 
} 
+0

Das ist wirklich gut aussieht, ich werde es wohl akzeptieren einmal laufe ich ein paar Tests, dass auf. – Sufian

2

Werfen Sie einen Blick auf this thread aus dem Jahr 2007 auf der Darwin-Kernel-Mailingliste. Kurz gesagt, wählen Sie popen vmmap (setgid entsprechend) oder verwenden Sie die Mach VM Region APIs in /usr/include/mach/mach_vm.h. Ich fand ein anständiges Beispiel für die Verwendung der Mach-API in der Sage Mathematics System sources.

+0

Danke für den Thread, ich denke, dies portabel über alle OSX-Versionen zu tun ist nicht einfach. – Sufian

+0

Aktualisierter Sage-Link: http://trac.sagemath.org/sage_trac/browser/sage/misc/darwin_memory_usage.c – Nickolay

+0

Aktualisierter Link: http://wstein.org/home/tornaria/sage-4.1.alpha2.sagemath_only- x86_64-Linux/devel/saga-main/sage/misc/darwin_memory_usage.c –

2

GNUlib (http://www.gnu.org/software/gnulib/) enthält eine Funktion zur Iteration über die alle virtuellen Speichersegmente in den meisten Betriebssystemen einschließlich MAC OS X. in VMA-iter.c Es ist