Ошибка шины при попытке доступа к отображенному в памяти буферу круга - PullRequest
0 голосов
/ 10 июля 2020

Я использую очередь, созданную с помощью кругового буфера в C, путем сопоставления файла с двумя половинами одного и того же базового буфера, одну за другой. Если я попытаюсь получить доступ к буферу сразу после его создания (как до, так и после сопоставления файла сверху), выдается ошибка шины.

Я программирую на машине x86, поэтому (если я правильно понимаю ), единственная причина, по которой это может произойти, заключается в том, что ячейка памяти физически недоступна. В таком случае, почему mmap возвращает физически недоступный адрес?

Мой код для создания нового кода можно увидеть ниже.

struct queue create_queue() {
    size_t pagesize = getpagesize();
    size_t sz = ((BUFFSIZE*sizeof(char *))/pagesize)*(pagesize+1); //align to page
    int fd = fileno(tmpfile());
    
    void *buffer = mmap(NULL, 2*sz, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 
    mmap(buffer, sz, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED, fd, 0); 
    mmap(buffer+sz, sz, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED, fd, 0); 
        
    struct queue new_queue;
    
    new_queue.buffer = (char **)buffer;
    new_queue.front = 0;
    new_queue.back = 0;
    sem_init(&(new_queue.sem), 0, 0); 
    
    return new_queue;
}

1 Ответ

0 голосов
/ 04 сентября 2020

Проблема в том, что:

size_t sz = ((BUFFSIZE*sizeof(char *))/pagesize)*(pagesize+1); //align to page

действительно устанавливает sz в несколько раз больше размера страницы, но в несколько единиц размера страницы плюс один. Альтернативный подход:

size_t sz = ((BUFFSIZE*sizeof(char *)+pagesize-1)/pagesize)*pagesize; //align to page
...