Memory 如何判断内存页是否标记为只读?

Memory 如何判断内存页是否标记为只读?,memory,copy-on-write,Memory,Copy On Write,当使用写时复制语义在进程之间共享内存时,如何测试内存页是否可写或是否标记为只读?这可以通过调用特定的汇编程序代码、读取内存中的某个位置或通过操作系统的API来实现吗?如果您使用的是Win32,则会调用IsBadReadPtr和IsBadWritePtr。但是,不鼓励使用它们: 雷蒙德·陈(Raymond Chen)的这部作品的标题说明了一切: 对于如何处理这个问题,陈有一些有用的建议 结果是,您不应该在运行时测试这种东西。编写代码,以便您知道所交的是什么,如果不是预期的,则将其视为bug。如果

当使用写时复制语义在进程之间共享内存时,如何测试内存页是否可写或是否标记为只读?这可以通过调用特定的汇编程序代码、读取内存中的某个位置或通过操作系统的API来实现吗?

如果您使用的是Win32,则会调用IsBadReadPtr和IsBadWritePtr。但是,不鼓励使用它们:

雷蒙德·陈(Raymond Chen)的这部作品的标题说明了一切:

对于如何处理这个问题,陈有一些有用的建议


结果是,您不应该在运行时测试这种东西。编写代码,以便您知道所交的是什么,如果不是预期的,则将其视为bug。如果您真的没有选择,请查看SEH以处理异常。

在Linux上,您可以检查/proc/pid/maps:


第一列是虚拟内存地址范围,第二列包含权限(读、写、执行和私有),第3-6列包含偏移量、主要和次要设备号、索引节点以及内存映射文件的名称。

您是否在谈论通过shmget(在Unix上)分配的各种共享内存?即

如果是这样,您可以使用

int shmctl(int, int, struct shmid_ds *);
例如:

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

在Win32上,最好的方法是使用。它为地址所在的页面返回一个。其中一个成员是
Protect
,它是一些标志的组合,包含可能的保护模式。该函数还告诉您内存是空闲的、已提交的、保留的,以及它是私有的、映像部分还是共享内存部分


操作系统的API是确定页面保护的最佳方式。CPU从页面描述符读取保护模式,该描述符只能从内核模式访问。

Chris的评论适用于Windows。请务必在下面看到吉姆·尼尔森的评论和雷蒙德·陈的博客。
int shmctl(int, int, struct shmid_ds *);
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 */