1) Скачиваем и устанавливаем отладочную информацию для PHP (ссылку для CentOS приводил выше); 2) Включаем генерацию core dump в Apache; 3) Открываем core dump в gdb; 4) Получаем вывод debug_backtrace() PHP с помощью магической команды:
Код
dump_bt executor_globals.current_execute_data
Другой вариант:
Код
zbacktrace
Работает также — показывает backtrace скриптов PHP до момента падения, но смотрится менее эффектно.
Способ проверенный и неоднократно применялся в боевых условиях.
Иван пишет: Статью всегда можно найти в архиве Интернета.
Короткий пересказ:
1) Скачиваем и устанавливаем отладочную информацию для PHP (ссылку для CentOS приводил выше); 2) Включаем генерацию core dump в Apache; 3) Открываем core dump в gdb; 4) Получаем вывод debug_backtrace() PHP с помощью магической команды:
Код
dump_bt executor_globals.current_execute_data
Регулярно появляется такая же ошибка в логе апача. Но в ответ на команду dump_bt executor_globals.current_execute_data в gdb пусто.
Разве не должен быть собран php с ключем --enable-debug? На виртуальной машине Битрикс php собран как раз с ключом '--disable-debug'.
Специально развернул чистую виртуальную машину Битрикс, обеспечил падение PHP (с помощью глубокой рекурсии) и провел анализ core dump как это описано в статье. Результат.
Рекомендую еще раз, очень внимательно, выполнить все шаги, описанные в статье.
Есть подзрение что апач падает не из-за PHP. В этой статье описывается поиск причин падения апача, но в моем дампе нету функции execute.
Код
(gdb) bt
#0 0x408dfe62 in zval_mark_grey (pz=<value optimized out>) at /usr/src/debug/php-5.3.3/Zend/zend_gc.c:372
#1 0x408e08b5 in gc_mark_roots () at /usr/src/debug/php-5.3.3/Zend/zend_gc.c:433
#2 gc_collect_cycles () at /usr/src/debug/php-5.3.3/Zend/zend_gc.c:660
#3 0x408c1fc5 in zend_deactivate () at /usr/src/debug/php-5.3.3/Zend/zend.c:900
#4 0x40868dc8 in php_request_shutdown (dummy=0x0) at /usr/src/debug/php-5.3.3/main/main.c:1634
#5 0x409508e4 in php_apache_request_dtor (r=0x520417d0) at /usr/src/debug/php-5.3.3/sapi/apache2handler/sapi_apache2.c:509
#6 php_handler (r=0x520417d0) at /usr/src/debug/php-5.3.3/sapi/apache2handler/sapi_apache2.c:681
#7 0x400266a1 in ap_run_handler (r=0x520417d0) at /usr/src/debug/httpd-2.2.15/server/config.c:158
#8 0x4002a426 in ap_invoke_handler (r=0x520417d0) at /usr/src/debug/httpd-2.2.15/server/config.c:376
#9 0x400371a8 in ap_process_request (r=0x520417d0) at /usr/src/debug/httpd-2.2.15/modules/http/http_request.c:282
#10 0x40033c98 in ap_process_http_connection (c=0x410bc878) at /usr/src/debug/httpd-2.2.15/modules/http/http_core.c:190
#11 0x4002ef11 in ap_run_process_connection (c=0x410bc878) at /usr/src/debug/httpd-2.2.15/server/connection.c:43
#12 0x4003caea in child_main (child_num_arg=<value optimized out>) at /usr/src/debug/httpd-2.2.15/server/mpm/prefork/prefork.c:667
#13 0x4003ce7e in make_child (s=<value optimized out>, slot=0) at /usr/src/debug/httpd-2.2.15/server/mpm/prefork/prefork.c:763
#14 0x4003de53 in perform_idle_server_maintenance (_pconf=0x4052c0a8, plog=0x4055a160, s=0x4052dfa0)
at /usr/src/debug/httpd-2.2.15/server/mpm/prefork/prefork.c:898
#15 ap_mpm_run (_pconf=0x4052c0a8, plog=0x4055a160, s=0x4052dfa0) at /usr/src/debug/httpd-2.2.15/server/mpm/prefork/prefork.c:1102
#16 0x40010ad2 in main (argc=1, argv=0xbfdb2804) at /usr/src/debug/httpd-2.2.15/server/main.c:760
Это очень похоже на старую проблему со сборщиком мусора в PHP. Проблема тянется уже очень давно, как минимум с версии PHP 5.2, и фикс был предложен только сейчас, для версии 5.5. Чтобы дать какие-то рекомендации, необходимо больше информации. Если есть возможность, прошу выполнить следующие команды и выложить содержимое файла /tmp/sys_info, например, в pastebin:
Код
OUT="/tmp/sys_info"
uname -a >> "$OUT"
yum list httpd | grep -vE "(Load|\*)" >> "$OUT"
yum list php | grep -vE "(Load|\*)" >> "$OUT"
yum list php-debuginfo | grep -vE "(Load|\*)" >> "$OUT"
cout() { find $1 -type f -iname "$2" | while read i; do printf "\n\n$i\n" >> "$OUT"; cat "$i" >> "$OUT"; done; }
cout /etc/httpd/ "*.conf"
cout /etc/php.d/ "*.ini"
cout /etc/ "php.ini"
Если в конфигурационных файлах Apache или PHP указаны какие-нибудь пароли, IP адреса или иная частная информация, необходимо удалить ее из /tmp/sys_info.
Иван пишет: Это очень похоже на старую проблему со сборщиком мусора в PHP. Проблема тянется уже очень давно, как минимум с версии PHP 5.2, и фикс был предложен только сейчас, для версии 5.5. Чтобы дать какие-то рекомендации, необходимо больше информации. Если есть возможность, прошу выполнить следующие команды и выложить содержимое файла /tmp/sys_info, например, в pastebin :
Код
OUT="/tmp/sys_info"
uname -a >> "$OUT"
yum list httpd | grep -vE "(Load|\*)" >> "$OUT"
yum list php | grep -vE "(Load|\*)" >> "$OUT"
yum list php-debuginfo | grep -vE "(Load|\*)" >> "$OUT"
cout() { find $1 -type f -iname "$2" | while read i; do printf "\n\n$i\n" >> "$OUT"; cat "$i" >> "$OUT"; done; }
cout /etc/httpd/ "*.conf"
cout /etc/php.d/ "*.ini"
cout /etc/ "php.ini"
Если в конфигурационных файлах Apache или PHP указаны какие-нибудь пароли, IP адреса или иная частная информация, необходимо удалить ее из /tmp/sys_info.
Спасибо, стало гораздо проще. Теперь прошу создать в рамках сайта файл test.php (название произвольное) со следующим содержимым:
Код
<?php
class A {
public $c;
public function segfault() {
$GLOBALS['a']->get()->e = true;
$this->c = new B();
$this->c->d[] = true;
}
public function get() {
return $this->c;
}
}
class B {}
$a = new A();
$a->segfault();
Затем, обратиться к файлу через браузер. Интересует следующее:
1) Случится ли Segmentation fault; 2) Если да, то будет ли backtrace соответствовать приведенному в комментарии #17.