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

Когда я впервые сделал этот проект в прошлом семестре, код работал нормально. Теперь я получаю сообщение об ошибке шины, когда выполняется запись в 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]= '\0';
                    i++;
            }

            count++;
    }

    close(fd);
    return accounts;
}

2 ответа

Решение

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

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

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

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

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

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

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

Другие вопросы по тегам