大约每小时一次,我们的 Web 服务器上就会出现 Apache 子进程分段故障。我们正在运行一个非线程的 PHP 5.2.17 Apache 模块和 Apache prefork MPM。我运行了 httpd,出现了一些核心转储、gdb 和这个 .gdbinit 文件来自 php 的 github repo,为每个命令在 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 分段错误时,您还能做什么吗?
任何帮助都将不胜感激,谢谢。
答案1
我以前见过这种情况......除了让你的 PHP 应用程序开发人员检查他们的代码,并确保你拥有最新版本(来自你的发行版)的 PHP 和 apache 之外,你无能为力。
如果您正在运行 Op-Code 缓存器(eaccelerator、APC 或 XCache),您可以尝试关闭它们,因为它们会导致奇怪的段错误。
过去,我们不得不为分段错误系统部署一些令人印象深刻的黑客解决方案,当然,只是为了短期修复。例如,这个 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