2009-10-27 2 views
9

Dans Linux, la meilleure façon de regarder un processus carte mémoire est à la recherche à /proc/PID/maps, donnant quelque chose comme ceci:Récupération de la carte mémoire de son propre processus dans 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 

Comment un processus obtient les informations équivalentes (plages d'adresses, protection, nom de fichier mappé, etc ...) sur la propre carte mémoire d'un processus sous OSX 10.5 ou 10.6?

Répondre

12

Il existe un MacFUSE implementation of procfs. Avec elle, vous pouvez obtenir la carte mémoire comme suit:

cat /proc/PID/task/vmmap 

En regardant le source code, on dirait qu'il est à l'aide du Mach virtual memory interface pour obtenir la carte mémoire du noyau.

est ici la mise en œuvre du vmmap pseudofichier:

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

Cela semble vraiment génial, je vais probablement l'accepter une fois que j'ai fait des tests sur ce point. – Sufian

2

Jetez un oeil à this thread de 2007 sur la liste de diffusion du noyau Darwin. En un mot, vos choix sont à popen vmmap (qui est setgid de manière appropriée) ou utilisez les API de région Mach VM dans /usr/include/mach/mach_vm.h. J'ai trouvé un exemple décent d'utilisation de l'API Mach dans le Sage Mathematics System sources.

+0

Merci pour le fil, je suppose que ce portabilité dans toutes les versions d'OSX n'est pas facile. – Sufian

+0

mis à jour lien sage: http://trac.sagemath.org/sage_trac/browser/sage/misc/darwin_memory_usage.c – Nickolay

+0

mis à jour le lien: http://wstein.org/home/tornaria/sage-4.1.alpha2.sagemath_only- x86_64-Linux/devel/sauge-main/sauge/misc/darwin_memory_usage.c –

2

gnulib (http://www.gnu.org/software/gnulib/) contient une fonction pour itérer sur tous les segments de mémoire virtuelle dans la plupart des systèmes d'exploitation, y compris MAC OS X. Il est dans l'AVL-iter.c

Questions connexes