Bus error что значит

от admin

Ошибка шины — Bus error

В вычислении , А ошибка шины является неисправность поднят с помощью аппаратных средств, уведомляя об операционной системе (ОС) , что процесс пытается получить доступ к памяти , что процессор не может физически адрес: недопустимый адрес для адресной шины , отсюда и название. При современном использовании на большинстве архитектур они гораздо реже, чем ошибки сегментации , которые возникают в основном из-за нарушений доступа к памяти: проблем с логическим адресом или разрешениями.

На платформах, совместимых с POSIX , ошибки шины обычно приводят к отправке сигнала SIGBUS процессу, вызвавшему ошибку. SIGBUS также может быть вызван любой общей ошибкой устройства, которую обнаруживает компьютер, хотя ошибка шины редко означает, что компьютерное оборудование физически сломано — обычно это вызвано ошибкой в программном обеспечении . Ошибки шины могут также возникать для некоторых других ошибок пейджинга; увидеть ниже.

Содержание

Причины

Есть как минимум три основных причины ошибок шины:

Несуществующий адрес

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

Невыровненный доступ

Большинство процессоров имеют байтовую адресацию , где каждый уникальный адрес памяти относится к 8-битному байту . Большинство процессоров могут получить доступ к отдельным байтам из каждого адреса памяти, но обычно они не могут получить доступ к более крупным блокам (16 бит, 32 бита, 64 бита и т. Д.) Без того, чтобы эти блоки были » выровнены » по определенной границе ( платформа x86 является заметным исключением. ).

Например, если многобайтовый доступ должен быть выровнен по 16 битам, адреса (в байтах) 0, 2, 4, 6 и т. Д. Будут считаться выровненными и, следовательно, доступными, в то время как адреса 1, 3, 5 и так далее будет считаться невыровненным. Точно так же, если многобайтовый доступ должен быть выровнен по 32 бита, адреса 0, 4, 8, 12 и так далее будут считаться выровненными и, следовательно, доступными, а все адреса между ними будут считаться невыровненными. Попытка получить доступ к блоку размером больше байта по невыровненному адресу может вызвать ошибку шины.

Некоторые системы могут иметь их гибрид в зависимости от используемой архитектуры. Например, для оборудования на основе мэйнфрейма IBM System / 360 , включая IBM System z , Fujitsu B8000, RCA Spectra и UNIVAC Series 90 , инструкции должны находиться на 16-битной границе, то есть адреса выполнения должны начинаться с даже байт. Попытки перейти на нечетный адрес приводят к исключению спецификации. Однако данные могут быть получены с любого адреса в памяти и могут быть одним байтом или больше в зависимости от инструкции.

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

Ошибки подкачки

FreeBSD , Linux и Solaris могут сигнализировать об ошибке шины, когда страницы виртуальной памяти не могут быть выгружены , например, потому что она исчезла (например, доступ к файлу с отображением памяти или выполнение двоичного образа, который был усечен во время работы программы), или потому что только что созданный файл с отображением памяти не может быть физически выделен, потому что диск заполнен.

Отсутствующий сегмент (x86)

На x86 существует более старый механизм управления памятью, известный как сегментация . Если приложение загружает регистр сегмента с помощью селектора отсутствующего сегмента (что в POSIX-совместимых операционных системах может быть выполнено только на языке ассемблера ), генерируется исключение. Некоторые операционные системы использовали это для свопинга, но в Linux это генерирует SIGBUS.

пример

Это пример невыровненного доступа к памяти, написанный на языке программирования C с синтаксисом ассемблера AT&T .

Компиляция и запуск примера в POSIX- совместимой ОС на x86 демонстрирует ошибку:

В GDB отладчик показывает , что непосредственное значение 0x2a в настоящее время хранятся в местоположении , хранящейся в EAX регистр , используя X86 язык ассемблера . Это пример косвенной адресации регистров .

Печать младших битов адреса показывает, что он не выровнен по границе слова («двойное слово» в терминологии x86).

What is a bus error? Is it different from a segmentation fault?

What does the "bus error" message mean, and how does it differ from a segmentation fault?

17 Answers 17

Bus errors are rare nowadays on x86 and occur when your processor cannot even attempt the memory access requested, typically:

  • using a processor instruction with an address that does not satisfy its alignment requirements.

Segmentation faults occur when accessing memory which does not belong to your process. They are very common and are typically the result of:

  • using a pointer to something that was deallocated.
  • using an uninitialized hence bogus pointer.
  • using a null pointer.
  • overflowing a buffer.

PS: To be more precise, it is not manipulating the pointer itself that will cause issues. It’s accessing the memory it points to (dereferencing).

Peter Mortensen's user avatar

A segfault is accessing memory that you’re not allowed to access. It’s read-only, you don’t have permission, etc.

A bus error is trying to access memory that can’t possibly be there. You’ve used an address that’s meaningless to the system, or the wrong kind of address for that operation.

mmap minimal POSIX 7 example

«Bus error» happens when the kernel sends SIGBUS to a process.

A minimal example that produces it because ftruncate was forgotten:

Tested in Ubuntu 14.04.

POSIX describes SIGBUS as:

Access to an undefined portion of a memory object.

References within the address range starting at pa and continuing for len bytes to whole pages following the end of an object shall result in delivery of a SIGBUS signal.

And shm_open says that it generates objects of size 0:

The shared memory object has a size of zero.

So at *map = 0 we are touching past the end of the allocated object.

Unaligned stack memory accesses in ARMv8 aarch64

This was mentioned at: What is a bus error? for SPARC, but here I will provide a more reproducible example.

All you need is a freestanding aarch64 program:

That program then raises SIGBUS on Ubuntu 18.04 aarch64, Linux kernel 4.15.0 in a ThunderX2 server machine.

Unfortunately, I can’t reproduce it on QEMU v4.0.0 user mode, I’m not sure why.

The fault appears to be optional and controlled by the SCTLR_ELx.SA and SCTLR_EL1.SA0 fields, I have summarized the related docs a bit further here.

Читать:
Battlefield 3 как играть по сети

Ciro Santilli OurBigBook.com's user avatar

I believe the kernel raises SIGBUS when an application exhibits data misalignment on the data bus. I think that since most[?] modern compilers for most processors pad / align the data for the programmers, the alignment troubles of yore (at least) mitigated, and hence one does not see SIGBUS too often these days (AFAIK).

I agree with all the answers above. Here are my 2 cents regarding the BUS error:

A BUS error need not arise from the instructions within the program’s code. This can happen when you are running a binary and during the execution, the binary is modified (overwritten by a build or deleted, etc.).

Verifying if this is the case

A simple way to check if this is the cause is by launching a couple of instances of the same binary form a build output directory, and running a build after they start. Both the running instances would crash with a SIGBUS error shortly after the build has finished and replaced the binary (the one that both the instances are currently running).

Underlying Reason

This is because OS swaps memory pages and in some cases, the binary might not be entirely loaded in memory. These crashes would occur when the OS tries to fetch the next page from the same binary, but the binary has changed since the last time it was read.

Aditya Vikas Devarapalli's user avatar

On POSIX systems, you can also get the SIGBUS signal when a code page cannot be paged in for some reason.

Peter Mortensen's user avatar

Joshua's user avatar

A specific example of a bus error I just encountered while programming C on OS X:

In case you don’t remember the docs strcat appends the second argument to the first by changing the first argument(flip the arguments and it works fine). On linux this gives a segmentation fault(as expected), but on OS X it gives a bus error. Why? I really don’t know.

One classic instance of a bus error is on certain architectures, such as the SPARC (at least some SPARCs, maybe this has been changed), is when you do a misaligned access. For instance:

This snippet tries to write the 32-bit integer value 0xdeadf00d to an address that is (most likely) not properly aligned, and will generate a bus error on architectures that are "picky" in this regard. The Intel x86 is, by the way, not such an architecture. It would allow the access (albeit execute it more slowly).

Peter Mortensen's user avatar

I was getting a bus error when the root directory was at 100%.

goCards's user avatar

Firstly SIGBUS and SIGSEGV are not a specific type of error but are groups or families of errors. This is why you typically see a signal number(si_no) and a signal code(si_code).

They also depend on the os and architecture as to what can cause them exactly.

Ошибка сегментации шины C

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

Ошибка — это аномалия, обнаруженная операционной системой, и об этой аномалии сообщается, насколько это возможно, исходя из принципа удобства операционной системы. Точные причины ошибок шины и ошибок сегментации различаются в зависимости от версии операционной системы. Здесь описаны два типа ошибок, которые возникают в SunOS, работающей на архитектуре SPARC, и причины ошибок.

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

Сигнал генерируется из-за аппаратного прерывания. Программирование прерываний очень сложно, потому что они происходят асинхронно (время их возникновения непредсказуемо). Прочтите основной документ и файл заголовка сигнала usr/include/sys/signal.h 。

1. Захватить сигнал на ПК

Функция обработки сигналов является частью ANSI C и, как и UNIX, также подходит для ПК. Например, программисты ПК могут использовать signal() Функция перехвата сигнала Ctrl-Break, чтобы пользователи не прерывали программу таким образом.

В любом исходном файле, который использует сигналы, перед файлом должна быть добавлена ​​строка #include <singal.h> 。

Этого сообщения core dumped Частично это происходит из очень раннего прошлого, когда вся память была сделана из колец из оксида железа (то есть сердечников). Полупроводники были основным материалом для изготовления памяти более пятнадцати лет, но core Это слово до сих пор используется как синоним памяти.

2. Ошибка шины

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

Наш способ выражения правила «элементы данных не могут пересекать страницы или границы кеша» несколько сомнительный, потому что мы используем термин «выравнивание адресов», чтобы обозначить эту проблему, а не прямо заявлять, что межстраничный доступ к памяти запрещен, но они говорят в то же время вещь. Например, при доступе к 8-байтовым данным типа double адрес может быть только целым числом, кратным 8. Таким образом, двойные данные могут храниться по адресу 24, 8008 или 32768, но не по адресу 1006 (потому что он не делится на 8 без остатка). Размер страницы и кеша тщательно продуман, чтобы при соблюдении правил выравнивания можно было гарантировать, что элемент атомарных данных не пересечет границу страницы или блока кэша.

2.1 Программа, вызвавшая ошибку шины

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

[mmap][bus error]Нет свободного места на файловой системе

Есть переполненная файловая система. Свободного места нуль. Я могу создавать новые файлы, но записывать в них информацию — уже нет.

Я делаю в этой файловой системе файл fd, например, с помощью mkstemp. Потом я выполняю ftruncate (fd, getpagesize()). Наконец, mmap’лю этот файл в адресное пространство процесса. Все эти функции выполняются вроде как без ошибок, все правильно. Возвращают корректные значения.

При попытке записать что-то в эту память, указатель на которую получена функцией mmap, программа вылетает. Bus error.

Если программа вылетает, это значит, что в программе ошибка? Не может же хорошая программа вылетать только из-за того, что где-то там на файловой системе закончилось место… Я проверяю все значению, все функции выполняются правильно, никаких ошибок, я не хочу чтобы моя программа вылетала…

Объясните, пожалуйста, так и должно быть? Или такой ситуации можно как-то избежать? Или это ошибка в системе, может быть?

Похожие статьи