Récupérer la carte mémoire de son propre processus sous OS X 10.5 / 10.6
-
06-07-2019 - |
Question
Sous Linux, la méthode la plus simple pour visualiser la carte mémoire d’un processus consiste à consulter / proc / PID / maps
, donnant ainsi l’objet suivant:
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 peut-il obtenir les informations équivalentes (plages d'adresses, protection, nom de fichier mappé, etc.) sur la mappe de mémoire d'un processus sous OSX 10.5 ou 10.6?
La solution
Il existe une implémentation de procfs par MacFUSE. Avec cela, vous pouvez obtenir la carte mémoire comme suit:
cat /proc/PID/task/vmmap
En regardant le code source , on dirait qu'il utilise le < a href = "http://www.gnu.org/software/hurd/gnumach-doc/Virtual-Memory-Interface.html#Virtual-Memory-Interface" rel = "noreferrer"> Interface de mémoire virtuelle Mach pour obtenir la carte mémoire du noyau.
Voici l'implémentation du pseudofichier vmmap
:
/*
* 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();
}
Autres conseils
Consultez ce fil de 2007 sur la liste de diffusion Darwin-kernel. En résumé, vous avez le choix entre popen vmmap
(ce qui correspond à setgid
de manière appropriée) ou d'utiliser les API de région Mach VM dans / usr / include / mach / mach_vm. h
. J'ai trouvé un bon exemple d'utilisation de l'API de Mach dans les sources du système de mathématiques Sage .
Quelques liens supplémentaires pour ceux qui recherchent une source vmmap (c'est non publié ):
- http://www.newosxbook.com /src.jl?tree=listings&file=12-1-vmmap.c
- https://code.google.com /p/psutil/source/browse/psutil/_psutil_osx.c#274 (get_process_memory_maps) et https://code.google.com/p/psutil/issues/detail?id=260
Obtention du nom du fichier mappé et des noms des bibliothèques de dyld_shared_cache: https://stackoverflow.com/a/17180619/1026
GNUlib ( http://www.gnu.org/software/gnulib/ ) contient une fonction permettant d’itérer sur tous les segments de mémoire virtuelle de la plupart des systèmes d’exploitation, y compris MAC OS X. C’est dans vma-iter.c