【问题标题】:malloc results in segmentation fault after mprotectmalloc 在 mprotect 之后导致分段错误
【发布时间】:2009-11-06 12:54:32
【问题描述】:

我在使用 mprotect() 保护内存区域后第一次调用 malloc() 时遇到分段错误。这是一个执行内存分配保护的代码片段:

#define PAGESIZE 4096
void* paalloc(int size){   // Allocates and aligns memory
        int type_size =  sizeof(double);
        void* p;
        p = malloc(type_size*size+PAGESIZE-1);
        p = (void*)(((long) p + PAGESIZE-1) & ~(PAGESIZE-1));
        return p;
}
void aprotect(int size, void* array){  // Protects memory after values are set
        int type_size = sizeof(double);
        if (mprotect(array, type_size*size, PROT_READ)) {
                perror("Couldn't mprotect");
        }
}

我想使用 mprotect 来避免将任何内容写入我的数组(这是预先计算的正弦/余弦值)。这是一个愚蠢的想法吗?

【问题讨论】:

  • 请同时添加类型转换 (void *)mallac....
  • @john: 你不需要演员表
  • 相关性不足以让我编辑帖子,但发现此问题的人可能也对此感兴趣:stackoverflow.com/questions/1686464/alternatives-to-mprotect Caf 关于页面对齐的答案已死,似乎是今天的热门话题: )

标签: c memory-management malloc posix


【解决方案1】:

mprotect 只能以页面为单位工作,您可能已经知道了。在这种情况下,您正确地将块的开头与页面边界对齐,但您没有做的是确保您的分配延伸到您要去的最后一页的末尾在里面使用。

这意味着您的mprotect 正在保护分配结束后的数据(直到该页的末尾),这是下一次malloc 调用假定它可以写入的空间。

最简单的解决方法是将malloc 调用中的PAGE_SIZE - 1 更改为PAGE_SIZE * 2

【讨论】:

  • 谢谢!我是否遗漏了什么或者 mprotect 的手册页中有错误?例子也有同样的问题...
  • 我怀疑您的 mprotect 手册页与我的不同,它使用 memalign 分配一个页面对齐的、页面多大小的内存块而不是 malloc。 (实际上,您也应该考虑使用memalign)。
【解决方案2】:

我建议您直接使用 mmap 创建一个匿名映射,然后在完成对数组的写入后对其调用 mprotect。因为您总是分配整个页面,所以使用堆根本没有意义。它的主要目的是处理小(ish)对象的分配和释放。在处理页面块时,它只会增加不必要的开销。

【讨论】:

    【解决方案3】:

    caf 已确定问题的原因。

    我认为你可以不使用mprotect():如果在lookup.c(或其他任何名称)中将指针声明为静态对你来说很重要,然后使用非静态double get_sine(int index); 函数。这样lookup.c之外的代码只能调用get_sine(),不能直接访问表。

    另外,来自我的 mprotect() 手册页:

    POSIX 说可以使用 mprotect() 仅在获得的内存区域上 来自 mmap(2)

    (显然这对于​​ Linux 来说不算在内。您使用的是哪个操作系统?)

    【讨论】:

      猜你喜欢
      • 2023-02-24
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      • 2013-01-27
      • 2020-05-12
      • 1970-01-01
      • 1970-01-01
      • 2016-01-25
      相关资源
      最近更新 更多