linux - 为什么我们在映射内存时需要 MAP_PRIVATE 标志?

标签 linux assembly x86-64

我正在尝试匿名映射一页内存。这是它:

mov rax, 0x09   ; SYS_mmap
mov rdi, 0x00   ; addr is NULL
mov rsi, 0x8000 ; x86 page_size
mov rdx, 0x02   ; PROT_WRITE
mov r10, 0x20   ; MAP_ANONYMOUS
mov r8, -1      ; fd = -1
mov r9, 0x00    ; offset = 0
syscall

mov [rax], dword -2 ; Segmentation fault, rax = -22

这是段错误。但是当我将 MAP_PRIVATE 添加到标志时它工作正常:

mov rax, 0x09   ; SYS_mmap
mov rdi, 0x00   ; addr is NULL
mov rsi, 0x8000 ; x86 page_size
mov rdx, 0x02   ; PROT_WRITE
mov r10, 0x22   ; MAP_ANONYMOUS | MAP_PRIVATE 
mov r8, -1      ; fd = -1
mov r9, 0x00    ; offset = 0
syscall

mov [rax], dword -2 ; Now it works ok, rax = 0x7ffff7ff2000

我不太明白为什么 mmap 会失败,为什么我们在不指定 MAP_PRIVATE 标志的情况下进行匿名映射?

最佳答案

您不需要MAP_PRIVATE,您需要MAP_PRIVATEMAP_SHARED 之一。

The flags argument determines whether updates to the mapping are visible to other processes mapping the same region, and whether updates are carried through to the underlying file. This behavior is determined by including exactly one of the following values in flags:

     MAP_SHARED
                Share this mapping. [...]

     MAP_PRIVATE
                Create a private copy-on-write mapping. [...]


mmap让您选择如何传播对映射区域所做的任何更改:

  • MAP_PRIVATE 由文件备份
    映射同一文件的其他进程看不到任何更新。
    没有更新写入支持文件。
    COW 进行了更新页。

    对于就地处理文件的内容很有用。

  • MAP_PRIVATE | MAP_ANONYMOUS(例如,由文件备份)
    没有要更新的文件。
    对 COW 页面进行更新。

    用于分配内存,不与 fork 进程共享。

  • MAP_SHARED 由文件备份
    更新对其他进程可见。
    更新被传播到支持文件。

    对转换文件很有用。
    使用名称与其他进程共享内存区域很有用(请参阅 shm_open )。

  • MAP_SHARED | MAP_ANONYMOUS(例如,由文件备份)
    更新对映射到同一区域的所有进程都是可见的。
    没有要更新的文件。

    与 fork 进程共享内部内存区域很有用。

关于linux - 为什么我们在映射内存时需要 MAP_PRIVATE 标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48883547/

相关文章:

linux - 如何检查命令是否可用或存在?

使用 64 位变量的 C++ 尾递归

c - x86, amd64 : Why SIGTRAP' ucontext instruction pointer does not point to related int3

c++ - 性能 AVX/SSE 汇编与内部函数

java - 程序集 MASM 事件驱动就像 JAVA 一样

c - 编译 gcc-2.7.2.3 时出错

c - 如何计算我的 frameCount 函数中的堆栈帧数?

c - 在 Linux 下从 C 中的字符串中删除特殊字符

python - 没有名为组合的模块(来自 import wx.combo) - pyspread

python - 无法在 Linux Mint 18.2 Cinnamon 64 位的 Anaconda Navigator 中打开 Spyder