Что такое ошибка шины? - PullRequest
       73

Что такое ошибка шины?

238 голосов
/ 17 октября 2008

Что означает сообщение об ошибке шины, и чем оно отличается от ошибки сегмента?

Ответы [ 15 ]

223 голосов
/ 17 октября 2008

В настоящее время ошибки шины редки на x86 и возникают, когда ваш процессор не может даже попытаться получить доступ к памяти, как правило:

  • с использованием инструкции процессора с адресом, который не удовлетворяет его требованиям выравнивания.

Ошибки сегментации возникают при доступе к памяти, которая не принадлежит вашему процессу, они очень распространены и обычно являются результатом:

  • используя указатель на что-то, что было освобождено.
  • с использованием неинициализированного, следовательно, фиктивного указателя.
  • с использованием нулевого указателя.
  • переполнение буфера.

PS: Если быть более точным, это не манипулирование самим указателем, который вызовет проблемы, это доступ к памяти, на которую он указывает (разыменование).

78 голосов
/ 17 октября 2008

Segfault обращается к памяти, к которой у вас нет доступа. Это только для чтения, у вас нет разрешения и т. Д. *

Ошибка шины при попытке доступа к памяти, которой там быть не может. Вы использовали адрес, который не имеет смысла для системы, или неправильный адрес для этой операции.

11 голосов
/ 17 октября 2008

Я считаю, что ядро ​​поднимает SIGBUS когда приложение показывает данные рассогласование по шине данных. Я думаю что, так как большинство [?] современных компиляторов для большинства процессоров вставьте / выровняйте данные для программистов проблемы выравнивания былого (по крайней мере) смягчены, а значит, никто не видит SIGBUS слишком часто в наши дни (AFAIK).

От: Здесь

8 голосов

mmap минимальный пример POSIX 7

«Ошибка шины» возникает, когда ядро ​​отправляет SIGBUS процессу.

Минимальный пример, который производит его, потому что ftruncate был забыт:

#include <fcntl.h> /* O_ constants */
#include <unistd.h> /* ftruncate */
#include <sys/mman.h> /* mmap */

int main() {
    int fd;
    int *map;
    int size = sizeof(int);
    char *name = "/a";

    shm_unlink(name);
    fd = shm_open(name, O_RDWR | O_CREAT, (mode_t)0600);
    /* THIS is the cause of the problem. */
    /*ftruncate(fd, size);*/
    map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    /* This is what generates the SIGBUS. */
    *map = 0;
}

Запуск с:

gcc -std=c99 main.c -lrt
./a.out

Протестировано в Ubuntu 14.04.

POSIX описывает SIGBUS как:

Доступ к неопределенной части объекта памяти.

Спецификация mmap гласит:

Ссылки в пределах диапазона адресов, начинающиеся с pa и продолжающиеся для длинных байтов до целых страниц после конца объекта, должны привести к доставке сигнала SIGBUS.

И shm_open говорит, что генерирует объекты размером 0:

Объект общей памяти имеет размер ноль.

Итак, в *map = 0 мы касаемся конца выделенного объекта.

6 голосов
/ 18 октября 2008

Вы также можете получить SIGBUS, если по какой-то причине невозможно вставить кодовую страницу.

3 голосов
/ 17 октября 2008

Один классический случай ошибки шины возникает на определенных архитектурах, таких как SPARC (по крайней мере, некоторые SPARC, возможно, это было изменено), когда вы делаете неправильный доступ. Например:

unsigned char data[6];
(unsigned int *) (data + 2) = 0xdeadf00d;

Этот фрагмент пытается записать 32-разрядное целочисленное значение 0xdeadf00d по адресу, который (скорее всего) не выровнен должным образом, и сгенерирует ошибку шины на архитектурах, которые являются «требовательными» в этом отношении. Intel x86, кстати, не такая архитектура, она позволила бы доступ (хотя и выполнять его медленнее).

2 голосов
/ 16 июня 2016

Я получал ошибку шины, когда корневой каталог был на 100%.

2 голосов
/ 08 октября 2014

Конкретный пример ошибки шины, с которой я только что столкнулся при программировании C на OS X:

#include <string.h>
#include <stdio.h>

int main(void)
{
    char buffer[120];
    fgets(buffer, sizeof buffer, stdin);
    strcat("foo", buffer);
    return 0;
}

В случае, если вы не помните документы strcat добавляет второй аргумент к первому, изменяя первый аргумент (переверните аргументы, и все работает нормально). В Linux это дает ошибку сегментации (как и ожидалось), но в OS X это дает ошибку шины. Зачем? Я действительно не знаю.

2 голосов
/ 17 октября 2008

Обычно это означает неприсоединенный доступ.

Попытка получить доступ к памяти, которая физически отсутствует, также приведет к ошибке шины, но вы не увидите этого, если используете процессор с MMU и ОС, которая не глючит, потому что вы не будете иметь любую несуществующую память, сопоставленную с адресным пространством вашего процесса.

2 голосов
/ 17 октября 2008

Это зависит от вашей ОС, процессора, компилятора и, возможно, других факторов.

В целом это означает, что шина ЦП не смогла выполнить команду или столкнулась с конфликтом, но это может означать целый ряд вещей в зависимости от среды и кода, который выполняется.

-Adam

...