Ошибка шины при записи в данные mmaped

#c #shared-memory #mmap #bus-error

#c #разделяемая память #mmap #ошибка шины

Вопрос:

Когда я впервые сделал этот проект в прошлом семестре, код работал нормально. Теперь я получаю ошибку шины, когда записывается память mmapped для совместного использования между процессами, и я не уверен, почему она больше не работает.

 Account_Info *mapData()
{
    int fd;
    //open/create file with read and write permission and check return value
    if ((fd = open("accounts", O_RDWR|O_CREAT, 0644)) == -1)
    {
            perror("Unable to open account list file.");
            exit(0);
    }

    //map data to be shared with different processes
    Account_Info *accounts = mmap((void*)0, (size_t) 100*(sizeof(Account_Info)), PROT_WRITE,
    MAP_SHARED, fd, 0);

    int count= 0;

    //loop to initialize values of Account_Info struct
    while (count != 20)
    {
            //bus error occurs here
            accounts[count].CurrBalance= 0;
            accounts[count].flag = 0;
            int i = 0;
            while (i != 100)
            {
                    //place NULL terminator into each element of AccName
                    accounts[count].AccName[i]= '';
                    i  ;
            }

            count  ;
    }

    close(fd);
    return accounts;
}
  

Ответ №1:

Документированная причина для SIGBUS с mmap

Попытка доступа к части буфера, которая не соответствует файлу (например, за пределами конца файла, включая случай, когда другой процесс обрезал файл).

Я предполагаю, что accounts файл не существовал, поэтому open с O_CREAT его созданием. Но он имеет нулевой размер, поэтому любая попытка чтения или записи через сопоставление приведет к сбою. Вам нужно заполнить файл достаточным количеством нулей (или чем-то еще), чтобы покрыть сопоставление, например, с помощью ftruncate .

Ответ №2:

Вы получите SIGBUS , если попытаетесь выполнить запись за пределы отображенной области файла.

Велика вероятность того, что ваш файл хранилища резервных accounts копий усечен / слишком короткий. (например) если в файле есть место для 10 записей структуры, и вы записываете в 11-ю, вы получите SIGBUS

Выполните fstat , чтобы получить st_size и сравнить это с параметром длины, который вы предоставляете mmap

Возможно, вы захотите рассмотреть ftruncate возможность расширения файла перед выполнением mmap