2012-05-28 2 views
1

Мне нужно сделать области памяти для потоков и применять основные концепции управления памятью. Идея заключается в создании локального хранилища потоков и управлении с помощью записи, чтения и клонирования и стирания. Проблема в том, что когда я пытаюсь снять защиту с mprotect страницы, связанной с потоком в TLS, это присылает мне сообщение об ошибке. Это моя структура:память, сопоставленная с mmap, и используется с mprotect

Распределение для каждой страницы

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; 

Он отображается на ттар, но когда я пытаюсь защитить страницу с этим кодом (или снятия защиты у меня такая же ошибка, и это в первый раз я стараюсь)

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.

Я Цените любую помощь. Благодарю.

+0

Какой размер ОС и адресов? (Linux x86_64?) – Mat

+0

Os: Mac, размер адреса x64 – gadiaz1

ответ

3
p->address = (unsigned int)map; 

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

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

+0

Спасибо, кажется, работает. – gadiaz1

Смежные вопросы