память отображается с помощью mmap и используется с mprotect

Я должен предоставить области памяти для потоков и применить базовые концепции управления памятью. Идея состоит в том, чтобы создать локальное хранилище потоков и управлять записью, чтением, клонированием и стиранием. Проблема в том, что когда я пытаюсь снять защиту с помощью 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);
  }
} 

Метод защиты тот же.

Код ошибки 12.

Я ценю любую помощь. Спасибо.


person gadiaz1    schedule 28.05.2012    source источник
comment
Какая ОС и размер адреса? (Линукс x86_64?)   -  person Mat    schedule 29.05.2012
comment
ОС: Mac, размер адреса x64   -  person gadiaz1    schedule 29.05.2012


Ответы (1)


p->address = (unsigned int)map; 

Этот состав очень подозрительный. В большинстве 64-битных систем (включая OS X AFAIK) int имеет ширину 32 бита, поэтому он слишком короток для хранения указателя.
Это приведение отбрасывает 4 байта из 8, составляющих указатель.

p->address должно быть объявлено как void*, и это назначение вообще не должно нуждаться в приведении. Если вам нужно сохранить это как целочисленный тип без знака, используйте uintptr_t<stdint.h>, C99).

person Mat    schedule 29.05.2012