2008-10-17 9 views
203

Что означает сообщение «ошибка шины» и как оно отличается от segfault?Что такое ошибка шины?

+2

Я хотел бы добавить простое объяснение для обоих: Ошибка сегментации означает, что вы пытаетесь получить доступ к памяти, которой вам не разрешено (например, она не входит в вашу программу). Однако при ошибке шины обычно означает, что вы пытаетесь получить доступ к памяти, которая не существует (например, вы пытаетесь получить доступ к адресу на 12G, но у вас есть только 8G-память), или если вы превысите предел полезной памяти. – xdevs23 2017-10-03 13:45:34

ответ

189

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

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

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

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

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

2

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

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

-Adam

9

Я считаю, что ядро ​​вызывает SIGBUS , когда экспонаты данные приложений перекосы на шине данных. Я думаю , что так как большинство [?] Современные компиляторы для большинства процессоров колодка/выравнивание данных для программистов, выравнивания проблема былых (по крайней мере) смягчена, и, следовательно, один не видит SIGBUS слишком часто в эти дни (НАСКОЛЬКО МНЕ ИЗВЕСТНО).

От: Here

+0

Зависит от неприятных трюков, которые вы делаете с кодом. Вы можете вызвать ошибку BUS/Alignment Trap, если вы делаете что-то глупое, как make pointer math, а затем typecast для доступа к проблемному режиму (т. Е. Вы настраиваете массив uint8_t, добавляете один, два или три указателя массива, а затем typecast к короткому, int или длинному, и попытайтесь получить доступ к оскорбительному результату.) Системы X86 в значительной степени позволят вам сделать это, хотя и при реальном снижении производительности. * НЕКОТОРЫЕ * Системы ARMv7 позволят вам сделать это, но большинство ARM, MIPS, Power и т. Д. Будут рябить над вами. – Svartalf 2014-12-16 18:39:57

68

выдаёт ошибку сегментации обращается к памяти, что вы не разрешен доступ. Это доступно только для чтения, у вас нет разрешения и т. Д.

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

2

Обычно это означает, что вы не выровнены.

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

+2

У моего i7 наверняка есть MMU, но я все еще сталкивался с этой ошибкой, изучая C на OS X (передавая неинициализированный указатель на `scanf`). Означает ли это, что OS X Mavericks глючит? Каким было бы поведение на не-багги OS? – 2014-02-17 00:55:38

3

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

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

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

+1

В случае, у меня были данные [8]; Это теперь кратное 4 в 32-битной архитектуре. Таким образом, он выровнен. У меня все еще будет ошибка? Кроме того, пожалуйста, объясните, это плохая идея преобразования типов данных для указателей. Это приведет к ошибкам ошибочного выравнивания на хрупкой архитектуре. Пожалуйста, уточните, это поможет мне. – 2013-10-01 12:49:43

+0

Хех. Это не столько преобразование типов, сколько преобразование типов на указателе, на котором вы указали математику указателя. Посмотрите * тщательно * на приведенный выше код. Компилятор тщательно dword выровнял ваш указатель для данных, а затем вы вставляете все в компилятор, смещая ссылку на TWO и typecasting на очень нуждающийся, чтобы быть согласованным с dword доступом на том, что станет границей без слова. – Svartalf 2014-12-16 18:28:04

+0

«Fragile» - это не то слово, которое я бы использовал для всего этого.Машины и код X86 заставили людей делать довольно глупые вещи какое-то время, это один из них. Переосмыслите свой код, если у вас возникла такая проблема - с X86 это не очень хорошо. – Svartalf 2014-12-16 18:31:01

5

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

-1

Типичное переполнение буфера, который приводит к ошибке шины является,

{ 
    char buf[255]; 
    sprintf(buf,"%s:%s\n", ifname, message); 
} 

Вот если размер строки в двойных кавычках («») больше, чем размер Buf он дает ошибку шины.

0

Чтобы добавить к тому, что ответил blxtd, ошибки шины также возникают, когда ваш процесс не может попытаться получить доступ к памяти определенной «переменной».

for (j = 0; i < n; j++) { 
       for (i =0; i < m; i++) { 
         a[n+1][j] += a[i][j]; 
       } 
     } 

Обратите внимание на 'непреднамеренное' использование переменной 'I' в первого цикла 'для'? В этом случае возникает ошибка шины.

2

Конкретный пример ошибки шины я только что столкнулся при программировании 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 она дает ошибку шины. Зачем? Я действительно не знаю.

0

Я только что обнаружил, что на ARMv7-процессоре вы можете написать код, который дает вам ошибку сегментации при неоптимизации, но дает ошибку шины при компиляции с -O2 (оптимизируйте больше). Я использую gcc arm gnueabihf cross compiler от ubuntu x64.

3

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 describesSIGBUS как:

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

mmap spec говорит, что:

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

И shm_opensays that он создает объекты размером 0:

Общий объект памяти имеет размер, равный нулю.

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

1

Моей причиной ошибки шины в Mac OS X было то, что я попытался выделить около 1 Мб в стеке. Это хорошо работает в одном потоке, но при использовании openMP эти диски приводят к ошибке шины, поскольку Mac OS X имеет очень ограниченный stack size for non-main threads.

-2

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

2

У меня возникла ошибка шины, когда корневой каталог был на 100%.