Linux SIGSEGVВысокая

Segmentation Fault в Linux: причины и способы исправления

Статья объясняет, что такое Segmentation Fault в Linux, его причины и предоставляет несколько способов решения проблемы, от простых до сложных.

Обновлено 15 февраля 2026 г.
10-30 мин
Средняя
FixPedia Team
Применимо к:Все дистрибутивы LinuxПриложения на C/C++/Rust/GoЯдро Linux 4.x и выше

Что означает ошибка SIGSEGV

Segmentation fault (ошибка сегментации) — это сигнал SIGSEGV, который отправляется процессу, когда он пытается обратиться к запрещённому участку памяти. Например, доступ к памяти, которая не принадлежит процессу, или попытка записи в read-only память. В Linux это обычно приводит к немедленному завершению программы с сообщением "Segmentation fault" или "Segmentation fault (core dumped)", если сгенерирован core dump.

Причины возникновения

  1. Разыменование нулевого указателя: Попытка чтения или записи по адресу NULL (0x0).
  2. Выход за границы массива: Доступ к элементу массива за пределами выделенной памяти.
  3. Использование освобождённой памяти (use-after-free): Обращение к указателю после вызова free().
  4. Переполнение стека (stack overflow): Рекурсия без условия выхода или слишком большие локальные массивы.
  5. Некорректные приведения типов: Например, приведение int* к char* и последующий доступ.
  6. Повреждение кучи (heap corruption): Переполнение буфера в куче, повреждающее метаданные.
  7. Ошибки в многопоточном коде: Гонки данных, неправильная синхронизация.
  8. Повреждённые библиотеки или драйверы: Использование устаревших или битых shared libraries.

Способ 1: Анализ core dump с GDB

Core dump — это снимок памяти процесса на момент падения. Если он включён (обычно через ulimit -c unlimited), вы можете проанализировать его с помощью GDB.

  1. Убедитесь, что core dump существует. Он обычно называется core или core.<pid> в текущей директории.
  2. Запустите GDB с исполняемым файлом и core dump:
    gdb /path/to/program core
    
  3. Внутри GDB используйте команду bt (backtrace) для получения стека вызовов. Это покажет, в какой строке кода произошла ошибка.
  4. Ищите в выводе адрес, где произошёл segfault. Часто это будет функция из вашего кода или библиотеки.

💡 Совет: Если core dump не генерируется, проверьте настройки ulimit -c и место на диске.

Способ 2: Запуск под valgrind

Valgrind — инструмент для обнаружения ошибок работы с памятью, включая segmentation fault.

  1. Установите valgrind, если ещё не установлен: sudo apt install valgrind (для Ubuntu/Debian).
  2. Запустите программу через valgrind:
    valgrind --leak-check=full ./your_program [аргументы]
    
  3. Valgrind будет выводить подробные сообщения об ошибках, включая неинициализированные переменные, доступ к освобождённой памяти и т.д.
  4. Ищите строки с "Invalid read" или "Invalid write" — они указывают на потенциальные причины segfault.

Способ 3: Использование AddressSanitizer (ASan)

AddressSanitizer — это санитайзер, встроенный в компиляторы GCC и Clang. Он обнаруживает ошибки памяти во время выполнения.

  1. Перекомпилируйте свою программу с флагами санитайзера:
    gcc -fsanitize=address -g -o program program.c
    
    Флаг -g добавляет отладочную информацию.
  2. Запустите программу:
    ./program [аргументы]
    
  3. При segmentation fault ASan выведет детальный отчёт, включая стек вызовов и тип ошибки.
  4. ASan также может обнаруживать утечки памяти.

Способ 4: Проверка кода на распространённые ошибки

Если у вас есть исходный код, проверьте его вручную или с помощью статических анализаторов.

  • Убедитесь, что все указатели проверяются на NULL перед использованием.
  • Проверьте границы массивов: индексы должны быть в диапазоне [0, size-1].
  • Избегайте возврата указателей на локальные переменные из функций.
  • В C++ используйте умные указатели (std::unique_ptr, std::shared_ptr) для автоматического управления памятью.
  • Для строк используйте безопасные функции (strncpy вместо strcpy, snprintf вместо sprintf).

Можно использовать статические анализаторы:

  • cppcheck для C/C++: cppcheck --enable=all program.c
  • clang-tidy для современного C++.

Способ 5: Обновление системных библиотек и драйверов

Иногда segmentation fault возникает из-за битых или устаревших библиотек, особенно если программа использует сторонние модули.

  1. Обновите систему:
    sudo apt update && sudo apt upgrade   # Для Debian/Ubuntu
    sudo dnf update                       # Для Fedora
    
  2. Переустановите проблемную библиотеку, если подозреваете её:
    sudo apt reinstall libexample        # Пример для Ubuntu
    
  3. Проверьте, не используете ли вы старые версии библиотек, совместимые с текущей системой. Используйте ldd для просмотра зависимостей:
    ldd /path/to/program
    
  4. Если проблема в драйвере (например, графическом), обновите драйверы через менеджер драйверов или с сайта производителя.

Способ 6: Изоляция проблемы с минимальным примером

Если segmentation fault происходит в большой программе, попробуйте создать минимальный воспроизводящий пример.

  1. Упростите код до минимального варианта, который всё ещё вызывает ошибку.
  2. Удаляйте части кода по одной, чтобы найти конкретный участок.
  3. Используйте комментарии для исключения блоков.
  4. Как только найдёте минимальный пример, станет проще диагностировать причину.
  5. Если проблема в сторонней библиотеке, проверьте её документацию на известные баги.

Профилактика

Чтобы избежать segmentation fault в будущем:

  • Используйте санитайзеры при разработке: Включайте AddressSanitizer или MemorySanitizer в процесс сборки для отладки.
  • Пишите безопасный код: Проверяйте все указатели, избегайте магических чисел для размеров массивов.
  • Тестируйте на edge cases: Проверяйте граничные условия, такие как пустые массивы, NULL-указатели.
  • Регулярно обновляйте зависимости: Следите за обновлениями библиотек и компиляторов, которые могут содержать исправления.
  • Используйте современные языки и инструменты: Языки вроде Rust имеют встроенную защиту от подобных ошибок на уровне компилятора.
  • Включать core dump в продакшене: Для продакшн-систем настройте core dump для анализа падений, но учитывайте безопасность (core dump может содержать чувствительные данные).

Часто задаваемые вопросы

Что такое segmentation fault и почему он возникает?
Как найти строку кода, вызывающую segmentation fault?
Можно ли предотвратить segmentation fault?
Segmentation fault только в Linux или и в других ОС?

Полезное

Проверка core dump
Запуск с valgrind
Использование AddressSanitizer
Проверка указателей
Обновление библиотек
Минимальный тестовый пример

Эта статья помогла вам решить проблему?