Lors de l'utilisation de la sémantique copy-on-write pour partager la mémoire entre processus, comment pouvez-vous tester si une page de mémoire est accessible en écriture ou si elle est marquée en lecture seule? Est-ce que cela peut être fait en appelant un code assembleur spécifique, ou en lisant un certain endroit en mémoire, ou à travers l'API du système d'exploitation?Comment pouvez-vous savoir si une page de mémoire est marquée en lecture seule?
Répondre
Sur Linux, vous pouvez examiner/proc/pid/cartes:
$ cat /proc/self/maps
002b3000-002cc000 r-xp 00000000 68:01 143009 /lib/ld-2.5.so
002cc000-002cd000 r-xp 00018000 68:01 143009 /lib/ld-2.5.so
002cd000-002ce000 rwxp 00019000 68:01 143009 /lib/ld-2.5.so
002d0000-00407000 r-xp 00000000 68:01 143010 /lib/libc-2.5.so
00407000-00409000 r-xp 00137000 68:01 143010 /lib/libc-2.5.so
00409000-0040a000 rwxp 00139000 68:01 143010 /lib/libc-2.5.so
0040a000-0040d000 rwxp 0040a000 00:00 0
00c6f000-00c70000 r-xp 00c6f000 00:00 0 [vdso]
08048000-0804d000 r-xp 00000000 68:01 379298 /bin/cat
0804d000-0804e000 rw-p 00004000 68:01 379298 /bin/cat
08326000-08347000 rw-p 08326000 00:00 0
b7d1b000-b7f1b000 r--p 00000000 68:01 226705 /usr/lib/locale/locale-archive
b7f1b000-b7f1c000 rw-p b7f1b000 00:00 0
b7f28000-b7f29000 rw-p b7f28000 00:00 0
bfe37000-bfe4d000 rw-p bfe37000 00:00 0 [stack]
La première colonne est la plage d'adresses de mémoire virtuelle, la deuxième colonne contient les permissions (lecture, écriture, exécution et privé), les colonnes 3 à 6 contiennent le décalage, les numéros de périphériques majeur et mineur, l'inode et le nom des fichiers mappés en mémoire.
Si vous utilisez Win32, il existe les appels IsBadReadPtr et IsBadWritePtr. Cependant, leur utilisation est déconseillée:
Le titre de la prise de Raymond Chen sur ce dit tout: "IsBadXxxPtr should really be called CrashProgramRandomly"
Chen a quelques conseils utiles sur la façon de traiter cette question here. En conséquence, vous ne devriez pas tester ce genre de chose lors de l'exécution. Code pour que vous sachiez ce qui vous a été remis, et si ce n'est pas ce qui est attendu, traitez-le comme un bug. Si vous n'avez vraiment pas le choix, regardez dans SEH pour gérer l'exception.
Parlez-vous de la variété de mémoire partagée allouée via shmget (sous Unix)? C'est à dire.
int shmget(key_t, size_t, int);
Si oui, vous pouvez interroger cette mémoire à l'aide
int shmctl(int, int, struct shmid_ds *);
Par exemple:
key_t key = /* your choice of memory api */
int flag = /* set of flags for your app */
int shmid = shmget(key, 4096, flag);
struct shmid_ds buf;
int result = shmctl(shmid, IPC_STAT, &buf);
/* buf.ipc_perm.mode contains the permissions for the memory segment */
Sur Win32, la meilleure façon est d'utiliser VirtualQuery. Il renvoie un MEMORY_BASIC_INFORMATION
pour la page d'une adresse. L'un des membres est Protect
, qui est une combinaison de these drapeaux, qui contiennent les modes de protection possibles. La fonction vous indique également si la mémoire est libre, validée, réservée et si elle est privée, partie d'une image ou section de mémoire partagée.
L'API du système d'exploitation est le meilleur moyen de déterminer la protection d'une page. La CPU lit le mode de protection à partir d'un descripteur de page, accessible uniquement depuis le mode noyau.
Le commentaire de Chris est correct pour Windows. Soyez sûr de voir le commentaire de Jim Nelson et les blogs de Raymond Chen ci-dessous. – Foredecker