2009-10-27 11 views
9

En Linux, la forma más fácil mirar a un proceso de mapa de memoria está mirando /proc/PID/maps, dando algo como esto:Recuperando el mapa de memoria de su propio proceso de 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 

¿Cómo puede ¿un proceso obtiene la información equivalente (rangos de direcciones, protección, nombre de archivo asignado, etc.) sobre el mapa de memoria propio de un proceso bajo OSX 10.5 o 10.6?

Respuesta

12

Hay un MacFUSE implementation of procfs. Con él, se puede obtener el mapa de memoria de la siguiente manera:

cat /proc/PID/task/vmmap 

Mirando el source code, parece que se trata de utilizar la Mach virtual memory interface para obtener el mapa de memoria del kernel.

Aquí está la aplicación para la 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

Esto se ve muy bien, probablemente lo acepte una vez que ejecute algunas pruebas al respecto. – Sufian

2

Tome un vistazo a this thread a partir de 2007 en la lista de correo Darwin-núcleo. En pocas palabras, sus opciones son popen vmmap (que es setgid de forma adecuada) o utilice las API de región Mach VM en /usr/include/mach/mach_vm.h. Encontré un buen ejemplo del uso de Mach API en el Sage Mathematics System sources.

+0

Gracias por el hilo, creo que hacerlo de forma portátil en todas las versiones de OSX no es fácil. – Sufian

+0

Enlace de Sage actualizado: http://trac.sagemath.org/sage_trac/browser/sage/misc/darwin_memory_usage.c – Nickolay

+0

Enlace actualizado: 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 función para iterar sobre todos los segmentos de memoria virtual en la mayoría de los sistemas operativos incluyendo Mac OS X. Está en VMA-iter.c

Cuestiones relacionadas