2009-10-27 8 views
9

W Linuksie, najprostszy sposób spojrzeć na proces mapa pamięci patrząc na /proc/PID/maps, dając coś takiego:Odzyskiwanie mapę pamięci własnego procesu w OS 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 

Jak można proces uzyskuje równoważne informacje (zakresy adresów, ochrona, zmapowana nazwa pliku, itp.) na temat "własnej mapy pamięci" w OSX 10.5 lub 10.6?

Odpowiedz

12

Istnieje MacFUSE implementation of procfs. Dzięki niemu można uzyskać mapę pamięci w następujący sposób:

cat /proc/PID/task/vmmap 

Patrząc na source code, wygląda to za pomocą Mach virtual memory interface dostać mapę pamięci z jądrem.

Oto realizacja dla vmmap pseudofile:

/* 
* 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

To wygląda naprawdę świetnie, prawdopodobnie zaakceptuję to po uruchomieniu niektórych testów na ten temat. – Sufian

2

Spójrz na this thread od 2007 roku na liście dyskusyjnej Darwin-jądra. W skrócie, twoje wybory to popen vmmap (czyli odpowiednio setgid) lub użyj funkcji API Mach VM w /usr/include/mach/mach_vm.h. Znalazłem przyzwoity przykład użycia Mach API w Sage Mathematics System sources.

+0

Dzięki za wątek, myślę, że robienie tego przenośnie we wszystkich wersjach OSX nie jest łatwe. – Sufian

+0

zaktualizowany link sage: http://trac.sagemath.org/sage_trac/browser/sage/misc/darwin_memory_usage.c – Nickolay

+0

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