2009-10-27 9 views
9

In Linux, il modo più semplice per guardare un processo di mappa di memoria sta guardando /proc/PID/maps, dare qualcosa di simile:Recupero della mappa di memoria del proprio processo in 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 

Come può un processo ottiene le informazioni equivalenti (intervalli di indirizzi, protezione, nome file mappato, ecc.) sulla mappa di memoria di un processo in OSX 10.5 o 10.6?

risposta

12

C'è un MacFUSE implementation of procfs. Con esso, è possibile ottenere la mappa della memoria come segue:

cat /proc/PID/task/vmmap 

Guardando il source code, sembra che sta usando il Mach virtual memory interface per ottenere la mappa della memoria dal kernel.

Ecco l'implementazione per il 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

Questo sembra davvero grande, io probabilmente l'accetto una volta ho eseguito alcuni test su questo. – Sufian

2

Date un'occhiata a this thread dal 2007 sulla mailing list di Darwin-kernel. In poche parole, le tue scelte sono a popen vmmap (che è setgid in modo appropriato) o utilizzare le API della regione Mach VM in /usr/include/mach/mach_vm.h. Ho trovato un buon esempio di utilizzo dell'API Mach nello Sage Mathematics System sources.

+0

Grazie per il thread, immagino che farlo in maniera portabile su tutte le versioni OSX non sia facile. – Sufian

+0

collegamento sage aggiornato: http://trac.sagemath.org/sage_trac/browser/sage/misc/darwin_memory_usage.c – Nickolay

+0

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

2

GNUlib (http://www.gnu.org/software/gnulib/) contiene una funzione per iterare su tutti i segmenti di memoria virtuale nella maggior parte dei sistemi operativi, tra cui Mac OS X. E 'in VMA-iter.c