PHP-FPM Ошибка: child exited on signal 11 (SIGSEGV core dumped)
Механизм ошибки нарушения сегментации памяти (Segmentation Fault)
Системный сигнал Signal 11 (SIGSEGV) посылается ядром Linux процессу, когда тот пытается обратиться к защищенному или недопустимому участку оперативной памяти (например, разыменование нулевого указателя NULL pointer dereference, запись в область Read-Only или выход за границы выделенного буфера). Поскольку чистый PHP-код исполняется внутри виртуальной машины Zend Engine, сам интерпретатор не должен падать по SIGSEGV. Ошибка «WARNING: [pool www] child exited on signal 11 (SIGSEGV - core dumped)» свидетельствует о наличии критического бага в скомпилированном C-коде расширения PHP, Zend OPcache, сторонней библиотеке (ImageMagick, libxml, cURL) или в самом ядре PHP.
Бизнес-риски
Внезапный обрыв выполнения пользовательских транзакций, спонтанные ошибки HTTP 502 Bad Gateway в Nginx, потенциальная уязвимость к переполнению буфера.
Типовые источники возникновения SIGSEGV в PHP
| Источник | Причина сбоя | Метод устранения |
|---|---|---|
| Несовместимые C-расширения | Конфликт версий расширений (например, Xdebug + OPcache + IonCube). | Поочередное отключение модулей в conf.d. |
| Сбои Zend OPcache | Повреждение структуры байткода в разделяемой памяти (SHM). | Очистка кэша, отключение JIT или увеличение памяти OPcache. |
| Обработка медиафайлов | Переполнение стека в libpng/libjpeg/ImageMagick при парсинге битых картинок. | Обновление системных библиотек из репозитория. |
Регламент локализации сбоя через отладчик GDB и Core Dump
Шаг 1: Включение генерации дампов памяти (Core Dumps) в Linux и PHP-FPM
По умолчанию ядро блокирует создание дампов процессов, меняющих UID (воркеры fpm работают от пользователя www-data):
# 1. Разрешение создания core-дампов на уровне ядра Linux:
sudo sysctl -w fs.suid_dumpable=2
sudo sysctl -w kernel.core_pattern=/var/crash/core-%e-%p-%t
# 2. Включение coredump в конфигурации PHP-FPM:
sudo nano /etc/php/8.2/fpm/php-fpm.conf
# Раскомментируйте или добавьте в секцию [global]:
rlimit_core = unlimited
# 3. Перезапуск службы:
sudo systemctl restart php8.2-fpmШаг 2: Анализ упавшего процесса с помощью GNU Debugger (GDB)
После повторения падения в каталоге /var/crash/ появится файл core-php-fpm-...:
# 1. Установка GDB и отладочных символов:
sudo apt install -y gdb php8.2-dbg
# 2. Запуск отладки дампа:
sudo gdb /usr/sbin/php-fpm8.2 /var/crash/core-php-fpm-*
# 3. В консоли GDB выполните команду получения трассировки стека вызовов:
(gdb) bt
# Или полная трассировка всех локальных переменных:
(gdb) bt full
# 4. Анализ вывода: найдите имя проблемной функции и .so модуля
# (например: in zif_imagick_readimage () from /usr/lib/php/.../imagick.so)Шаг 3: Локализация методом отключения проблемных PHP-расширений
# 1. Просмотр подключенных модулей:
php -m
# 2. Временное отключение подозрительного модуля (например, imagick или xdebug):
sudo phpdismod -v 8.2 imagick
sudo systemctl restart php8.2-fpmТиповые ошибки администраторов
- Использование несовместимых версий IonCube Loader: Подключение сборки IonCube, скомпилированной под другую подверсию PHP, гарантированно приводит к SIGSEGV при старте.
- Включение JIT-компилятора (opcache.jit) в нестабильных версиях PHP: В некоторых релизах PHP 8.0/8.1 баги в трансляторе JIT вызывали SIGSEGV на сложных регулярных выражениях.
Специалисты ITSTM проведут дизассемблирование C-стека через GDB, локализуют сбоящий модуль и устранят падения FastCGI-сервера.
Частые вопросы (FAQ)
Почему SIGSEGV появляется только при загрузке определенных файлов?
Часто сбой происходит в C-библиотеках парсинга (libxml2, ImageMagick, PDF-генераторы) из-за поврежденных бинарных заголовков загружаемых файлов или атак типа Zip-bomb.
Что делать, если bt в gdb показывает только вопросительные знаки (??)?
Это означает, что не установлены отладочные символы (Debug Symbols). Установите пакет php-dbg (например, apt install php8.2-dbg).
Может ли OPcache вызывать Signal 11?
Да, при переполнении буфера OPcache (opcache.memory_consumption) или некорректной инвалидации кэша в разделяемой памяти SHM.
Как временно отключить JIT компилятор для проверки гипотезы?
Установите opcache.jit = 0 и opcache.jit_buffer_size = 0 в php.ini и перезапустите php-fpm.