Linux SIGSEGV (11)Средняя

Переполнение стека в Linux: причины и быстрое исправление

Ошибка Stack overflow в Linux возникает при превышении лимита памяти стека. Разберём причины сбоя и покажем проверенные способы увеличения лимита и исправления кода.

Обновлено 8 апреля 2026 г.
10-15 мин
Средняя
FixPedia Team
Применимо к:Ubuntu 20.04/22.04/24.04 LTSDebian 11/12Fedora 38+Любые дистрибутивы Linux с ядром 5.0+

Что означает ошибка Stack overflow / SIGSEGV (11)

В Linux эта проблема проявляется как сигнал SIGSEGV с сообщением Segmentation fault (core dumped) или Stack smashing detected. Ошибка возникает, когда процесс исчерпывает выделенную ему область памяти стека. По умолчанию в большинстве дистрибутивов лимит жёстко зафиксирован на уровне 8 МБ. Если программа пытается записать данные за пределы этого участка, ядро Linux аварийно завершает процесс, чтобы предотвратить повреждение соседних областей памяти или сбой всей системы.

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

  1. Бесконечная или слишком глубокая рекурсия. Функция вызывает саму себя без корректного условия выхода, быстро заполняя стек кадрами вызовов.
  2. Объявление крупных локальных массивов. Попытка создать массив размером в несколько мегабайт внутри функции (например, double matrix[1000][1000]) мгновенно резервирует место в стеке и вызывает сбой.
  3. Некорректная настройка потоков. При создании потоков через pthread_create можно вручную задать слишком маленький размер стека, который не подходит для вашей бизнес-логики.
  4. Переполнение буфера. Запись данных за границы выделенной переменной активирует защиту компилятора (stack canary) и принудительно останавливает выполнение приложения.

Способы решения

Способ 1: Временное увеличение лимита через ulimit

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

  1. Проверьте текущий лимит в килобайтах:
ulimit -s
  1. Увеличьте лимит до 16 МБ или снимите его полностью:
ulimit -s 16384
# или полностью снять ограничение для сессии
ulimit -s unlimited
  1. Запустите вашу программу в том же окне терминала. Изменения действуют до закрытия сессии и не влияют на другие запущенные сервисы.

💡 Совет: Значение unlimited снимает жёсткое ограничение оболочки, но процесс всё равно ограничен физической оперативной памятью и параметром vm.max_map_count ядра.

Способ 2: Постоянное изменение лимита через PAM

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

  1. Откройте файл конфигурации с правами суперпользователя:
sudo nano /etc/security/limits.conf
  1. Добавьте в конец файла строки (замените username на ваше имя или используйте * для всех пользователей):
username soft stack 32768
username hard stack 32768
  1. Сохраните файл, полностью выйдите из системы и войдите снова. Проверьте применение изменений командой ulimit -s.

Способ 3: Поиск и исправление проблемного кода с GDB

Увеличение стека — лишь временная мера. Если ошибка вызвана архитектурными недочётами программы, её необходимо найти и исправить на уровне исходного кода.

  1. Скомпилируйте проект с отладочными символами:
gcc -g -O0 -o my_app main.c
  1. Запустите отладчик и выполните программу:
gdb ./my_app
(gdb) run
  1. При падении введите bt (backtrace) для просмотра полного стека вызовов:
(gdb) bt
  1. Найдите повторяющуюся функцию или укажите на строку в вашем коде. Измените логику: замените рекурсию на итеративный цикл, а крупные локальные массивы перенесите в кучу через malloc() или std::vector. Скомпилируйте заново и протестируйте.

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

Регулярная проверка кода на предмет утечек и аномалий экономит часы отладки. Всегда компилируйте проекты с включёнными флагами безопасности: -fstack-protector-strong и -Wall -Wextra. Для многопоточных приложений явно задавайте размер стека через pthread_attr_setstacksize(), а не полагайтесь на системный дефолт. Если работаете с большими структурами данных, размещайте их в динамической памяти (куче) или используйте static для глобального доступа. Настройте статический анализ в CI/CD пайплайне с помощью инструментов вроде Valgrind или AddressSanitizer, чтобы отлавливать переполнения до выкатки в продакшен.

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

Почему возникает ошибка Stack overflow при запуске программы?
Безопасно ли увеличивать размер стека через ulimit?
Как отличить переполнение стека от нехватки оперативной памяти?
Можно ли отключить защиту компилятора от переполнения?

Полезное

Проверка текущего лимита стека
Временное увеличение лимита
Постоянная настройка через limits.conf
Отладка с помощью GDB

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