Назад | Перейти на главную страницу

Рекомендации по отладке Apache с ошибками сегментации PHP

Каждый час или около того дочерний процесс Apache seg. сбои на нашем веб-сервере. Мы запускаем непоточный модуль Apache PHP 5.2.17 с Apache prefork MPM. Я запустил httpd с несколькими дампами ядра, gdb и этот файл .gdbinit из репозитория php github, набрав эту команду в gdb для каждого:

dump_bt executor_globals.current_execute_data

Не имея опыта работы с gdb или внутренней работой интерпретатора php, я ничего не могу сделать из результатов.

core.22762
[0x53896ef0] () :-2118682552
[0x538977a0] () /Statement/Interface.php:113
[0x538978a0] /Zend/Db/Statement/Interface.php()

core.22791
[0x538977a0] () @:0
[0x538978a0] ()

core.5568
[0x53896ef0] () :2061035360
[0x538977a0] () :1767992432
[0x538978a0] ()

core.30384
[0x538977a0] () :0
[0x538978a0] ()

core.3091
[0x53896ef0] mysql_query():992424253
[0x538977a0] () ~:17
[0x538978a0] ()

(core.3091 также показывает это после Program terminated with signal 11, Segmentation fault.)

#0  0x00002b6e7ad8d67d in zend_do_fcall_common_helper_SPEC (execute_data=0x7fff53896ef0) at /usr/src/debug/php-5.2.17/Zend/zend_vm_execute.h:217
217                             EX_T(opline->result.u.var).var.fcall_returned_reference = return_reference;

Есть ли еще что-нибудь, что я могу ввести в gdb, чтобы лучше отслеживать трассировку стека? Что еще вы делаете при отладке ошибок сегментации Apache?

Любая помощь будет принята с благодарностью, спасибо.

Я видел это раньше ... кроме того, чтобы заставить разработчиков вашего PHP-приложения проверить свой код и убедиться, что у вас есть актуальные версии (из вашего дистрибутива) PHP и apache, вы мало что можете сделать.

Если вы используете кэшер Op-Code (eaccelerator, APC или XCache), вы можете попробовать отключить их, они, как известно, вызывают странный segfault.

В прошлом нам приходилось внедрять некоторые впечатляюще хакерские решения для системы segfaulting, конечно, для краткосрочных исправлений. Например, эта cronjob хорошо сработала:

# Restart apache when a segfault is found in the most recent line of errorlog #*/5 * * * * tail -n1 /var/log/apache2/error.log | grep 'Segmentation fault' && /etc/init.d/apache2 restart

Или вы можете попробовать что-нибудь более умное: #*/5 * * * * /usr/bin/wget http://www.my-site.com/ -T10 -O 2> /dev/null - | grep "Hosted by" > /dev/null || /usr/local/bin/brutally_restart_apache.sh

Где brutally_restart:

    #!/bin/sh
    /usr/sbin/apache2ctl stop
    sleep 6
    killall -9 apache2
    sleep 4
    /usr/sbin/apache2ctl start