Что означает ошибка Bus Error
Bus Error (сигнал SIGBUS) — это ошибка, которую система отправляет процессу при попытке некорректного доступа к физической памяти. В отличие от Segmentation Fault (SIGSEGV), который связан с виртуальной адресацией, SIGBUS обычно указывает на:
- Нарушение выравнивания данных (например, попытка чтения 4-байтового значения по невыровненному адресу на некоторых архитектурах, таких как SPARC или старые ARM).
- Аппаратные сбои — проблемы с оперативной памятью (RAM), шиной (bus) или процессором.
- Повреждение данных при вводе-выводе (например, ошибка чтения с диска в отображённый файл).
- Ошибки в драйверах или ядре, приводящие к некорректному отображению памяти.
Типичное сообщение в логах (dmesg или системном журнале):
[12345.678] myapp[1234]: unaligned access to address 0x7fffdcba
[12345.679] myapp[1234]: Bus error (core dumped)
Или в терминале:
Bus error (core dumped)
Ошибка часто проявляется в высоконагруженных системах, на Raspberry Pi, при работе с отображёнными файлами (mmap) или при использовании низкоуровневых операций (например, прямой доступ к /dev/mem).
Причины возникновения
- Неверное выравнивание данных
Программа пытается получить доступ к данным по адресу, который не кратен размеру типа данных (например, 4-байтовыйintпо адресу0x1001). На некоторых архитектурах (SPARC, Alpha, ARM в определённых режимах) это вызываетSIGBUS. - Неисправности оперативной памяти (RAM)
Сбои в модулях RAM, перегрев или несовместимость часто приводят к ошибкам шины при чтении/записи. - Проблемы с диском или файловой системой
Повреждённые сектора на диске, ошибки в файловой системе (например, после внезапного отключения питания) могут привести к тому, что отображённый в память файл содержит некорректные данные. - Ошибки в драйверах оборудования или ядре
Сбои в драйвере (например, графического или сетевого) могут некорректно настроить таблицы страниц памяти, вызвавSIGBUSпри доступе. - Перегрев процессора или проблемные разгоны
На Raspberry Pi и других одноплатных компьютерах перегрев или нестабильный разгон (overclock) часто вызывают ошибки шины. - Некорректное использование системных вызовов
Например, передача некорректного указателя или длины вread()/write()для отображённого файла, который был усечён другим процессом.
Способ 1: Проверка и замена оперативной памяти
Аппаратные проблемы с RAM — самая частая причина SIGBUS на Linux-серверах и рабочих станциях.
- Загрузите memtest86+
Перезагрузите систему и выберите memtest86+ в меню загрузчика (GRUB). Если его нет, установите:sudo apt update && sudo apt install memtest86+
Или для RHEL/CentOS:sudo yum install memtest86+ - Запустите тест
Memtest начнёт автоматически. Дайте ему пройти минимум 4 полных цикла (это может занять несколько часов). Любые ошибки (красные строки) указывают на неисправную планку RAM. - Если ошибки найдены
- Выключите компьютер, отсоедините кабель питания.
- Извлеките все модули RAM, протрите контакты спиртом.
- Установите модули по одному, тестируя каждый слот и планку.
- Замените неисправные модули.
- Проверьте нагрев
Используйтеsensors(установитеlm-sensors):sensors
Температура RAM (если поддерживается) не должна превышать 85–90°C.
Способ 2: Обновление системы и ядра
Устаревшие драйверы или ядро с ошибками могут вызывать SIGBUS, особенно при работе с новым железом.
- Обновите все пакеты
Для Ubuntu/Debian:sudo apt update && sudo apt full-upgrade
Для CentOS/RHEL 8+:sudo dnf update
Для Raspberry Pi OS:sudo apt update && sudo apt full-upgrade - Установите последнее ядро
На Ubuntu:sudo apt install linux-generic-hwe-22.04
На CentOS:sudo dnf install kernel
Перезагрузитесь после установки. - Проверьте версию ядра
uname -r
Убедитесь, что используется новая версия (например,5.15.0-78-genericили новее). - Если проблема после обновления
Загрузитесь в предыдущее ядро из меню GRUB (Advanced options) и проверьте, исчезла ли ошибка. Если да — проблема в новом ядре, сообщите об ошибке в баг-трекер дистрибутива.
Способ 3: Диагностика диска и файловой системы
Ошибки чтения с диска в отображённый файл (mmap) — распространённая причина SIGBUS.
- Проверьте SMART-статус дисков
Установитеsmartmontools:sudo apt install smartmontools # Debian/Ubuntu sudo dnf install smartmontools # RHEL/CentOS
Проверка для диска/dev/sda:sudo smartctl -a /dev/sda
Ищите строкиSMART overall-health self-assessment test result: PASSEDи атрибутыReallocated_Sector_Ct,Current_Pending_Sector. Ненулевые значения — признак износа. - Запустите тест SMART
sudo smartctl -t long /dev/sda
После завершения (может занять несколько часов) проверьте результаты:sudo smartctl -a /dev/sda | grep -A5 " SMART" - Проверьте файловую систему
Для несмонтированных разделов:sudo fsck -f /dev/sda1
Дляext4можно добавить-cдля поиска bad blocks:sudo fsck -fcc /dev/sda1
Внимание: Не запускайтеfsckна смонтированном корневом разделе. Используйте LiveCD или загрузитесь в rescue-режиме. - Проверьте целостность отображённых файлов
Если ошибка возникает в конкретном приложении (например, база данных), проверьте файлы его данных:# Для PostgreSQL sudo -u postgres pg_checksums -D /var/lib/postgresql/14/main # Для MySQL sudo mysqlcheck -u root -p --all-databases --auto-repair
Способ 4: Отладка проблемного приложения
Если ошибка возникает только в одной программе, проблема, скорее всего, в её коде.
- Запустите программу под valgrind
Valgrind обнаруживает ошибки доступа к памяти:valgrind --tool=memcheck ./ваша_программа
Ищите сообщенияInvalid addressилиMisaligned address. - Используйте gdb для анализа core-файла
Если программа сбрасывает core-файл (обычноcoreилиcore.<pid>в текущей директории):gdb ./ваша_программа core
Внутри gdb:(gdb) bt (gdb) info registers
Последние команды покажут стек вызовов и адрес, вызвавшийSIGBUS. - Проверьте выравнивание в коде
Если вы разработчик, убедитесь, что:- Структуры данных выровнены (
alignasв C++,__attribute__((aligned))в C). - Используются функции для выровненного доступа (например,
memcpyвместо прямого копирования через указатель при выравнивании). - Нет доступа за границы массивов.
- Структуры данных выровнены (
- Попробуйте скомпилировать с флагами защиты
Добавьте вCFLAGS:-fsanitize=address,undefined -fno-omit-frame-pointer
Это поможет выявить ошибки на этапе компиляции/запуска.
Профилактика
- Регулярно тестируйте RAM
Запускайте memtest86+ раз в квартал, особенно после изменений в железе или перегрева. - Следите за температурами
Установитеlm-sensorsиpsensorдля мониторинга. На Raspberry Pi используйтеvcgencmd measure_temp. - Используйте стабильные разгоны
На Raspberry Pi и других одноплатных компьютерах избегайте агрессивного overclock’а. Проверяйте стабильность стресс-тестами (stress-ng). - Обновляйте прошивку
Для Raspberry Pi:sudo rpi-eeprom-update -a
Для серверов — обновляйте BIOS/UEFI и микрокод процессора (intel-microcodeилиamd-microcode). - Корректно обрабатывайте отображённые файлы
В коде:- Всегда проверяйте результат
mmapнаMAP_FAILED. - Убедитесь, что размер файла не меняется другим процессом во время отображения.
- Используйте
msyncдля синхронизации изменений.
- Всегда проверяйте результат
- Выбирайте качественные компоненты
При сборке системы отдавайте предпочтение ECC-памяти (на серверах) и сертифицированным дискам. На Raspberry Pi используйте официальный блок питания и качественную SD-карту (Class 10/UHS-I). - Настройте мониторинг
Добавьте вsyslogфильтр дляSIGBUS:sudo grep -i "bus error" /var/log/syslog
Настройте оповещения (например, черезlogwatchилиfail2banдля повторяющихся ошибок).