c - 堆对齐内存上的 mprotect 神秘地工作

标签 c linux malloc mmap

所以我试图检查是否可以使用 mprotect 正确更改映射分配内存的访问权限这就是我写的:

#include <stdio.h>
#include <sys/mman.h>
#include <malloc.h>
#include <unistd.h>

void main()
{
        int pagesize;
        pagesize = getpagesize();
        void *p;
        p = malloc(pagesize);
        getchar();
        int q = posix_memalign(&p, pagesize, pagesize);
        getchar();
        int a = mprotect(p, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC);
        getchar();
        free(p);
}

现在,在我使用的每个函数之后 getchar使用 cat /proc/<pid>/maps 分析我的内存段文件,这就是我得到的: (仅显示有关堆的信息,因为这是我唯一关心的) 之后posix_memalign :

01776000-01798000 rw-p 00000000 00:00 0                                  [heap]

mprotect之后功能:

01776000-01778000 rw-p 00000000 00:00 0                                  [heap]
01778000-01779000 rwxp 00000000 00:00 0                                  [heap]
01779000-01798000 rw-p 00000000 00:00 0                                  [heap]

因此,如果您注意到在我使用 mprotect 之后之前分配的堆被分为三个部分并且只有堆的第二部分获得了我在函数中给出的访问权限。 为什么会发生这种划分,为什么只有划分堆的第二个区域获得权限? 注意:我搜索了联机帮助页,但没有发现任何与此相关的内容。

最佳答案

您分配了0x1000地址 p 处的字节,即0x1778000在你的例子中。当您调用mprotect时使用这些参数,它确实按照您想要的方式工作并标记为 01778000-01779000 rwxp .

因此,您的问题可以更恰本地表述为,为什么posix_memalign(3)似乎分配的空间比您要求的多?

让我们看一下man posix_memalign :

POSIX requires that memory obtained from posix_memalign() can be freed using free(3).

但是free(3)怎么办?知道要释放多少字节吗?它需要将其存储在您分配的页面之外的某个位置。以及如何后续调用 malloc(3)或者 friend 知道哪里可以找到释放的 block 吗?这些也需要存储在某个地方。

堆分配器将用于管理堆的数据结构存储在堆上也就不足为奇了。

如果您想要一种更底层的方式来分配页面,请使用 mmap(2) :

p = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);

当您调用munmap(2)时,该内存由您管理。 ,直接通知内核删除映射。用户空间中没有进行回收或管理。

关于c - 堆对齐内存上的 mprotect 神秘地工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35239300/

相关文章:

c - 我的 makefile 有什么问题?

mysql - 查询期间失去与 MySQL 服务器的连接 mysqlclient-dev 多线程

c - malloc行为解释

c - 调试断言失败。 C

linux - 如何在没有安装 git 的情况下应用 git diff --binary 补丁?

linux - 如何找出docker镜像中安装了哪个Linux?

c# - Linux、Mono、共享库和未解析的符号

C - 字符数组似乎可以复制,但仅限于循环范围内

cuda 和 cudamalloc 分配大内存块失败

c - c语言中如何存储超过9位的数字?