【问题标题】:memory mapped with mmap, and used with mprotect使用 mmap 映射的内存,并与 mprotect 一起使用
【发布时间】:2012-06-03 03:41:47
【问题描述】:

我必须为线程提供内存区域并应用内存管理的基本概念。这个想法是创建一个线程本地存储,并通过写入、读取、克隆和擦除来管理。问题是当我尝试使用 mprotect 取消保护与 TLS 中的线程关联的页面时,这会向我发送一个错误。这是我的结构:

每个页面的分配

int cnt;
for (cnt = 0; cnt < page_num; cnt++) {
    struct page *p;
    p = (struct page *) calloc(1, sizeof(struct page));

    int *map =  mmap(0, page_size, 0, MAP_ANON | MAP_PRIVATE, 0, 0);
    if (map == MAP_FAILED) {
        perror("Error mmapping the file");
        exit(EXIT_FAILURE);
    }

    p->address = (unsigned int)map; 

它是由mmap映射的,但是当我尝试使用此代码保护页面时(或取消保护我有同样的错误,这是我第一次尝试)

for(int i = 0; i < currentTLS->page_num; i++){
    tls_unprotect(currentTLS->pages[i]);
}

还有 tls_unprotect 方法:

void tls_protect(struct page *p){
  if (mprotect((void *) p->address,PAGESIZE, PROT_READ | PROT_WRITE)) {
      fprintf(stderr, "tls_unprotect: could not unprotect page\n");
      exit(errno);
  }
} 

保护方法同理。

errorno 代码是 12。

感谢任何形式的帮助。谢谢。

【问题讨论】:

  • 什么操作系统和地址大小? (Linux x86_64?)
  • 操作系统:Mac,地址大小 x64

标签: c mmap mprotect


【解决方案1】:
p->address = (unsigned int)map; 

这个演员很可疑。在大多数 64 位系统(包括 OS X AFAIK)上,int 是 32 位宽,因此太短而无法容纳指针。
该转换丢弃了构成指针的 8 个字节中的 4 个字节。

p-&gt;address 应该声明为void*,并且该赋值根本不需要强制转换。如果您需要将其存储为无符号整数类型,请使用 uintptr_t(在 &lt;stdint.h&gt;,C99 中)。

【讨论】:

    猜你喜欢
    • 2014-05-24
    • 2023-03-06
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 1970-01-01
    • 2016-03-10
    相关资源
    最近更新 更多