PHP编程seg错误

时间:2011-07-20 22:54:40

标签: php apache segmentation-fault mysqli mod-fcgid

我一直在使用以下网站编程:

  1. Zend Framework 1.11.5(完整的MVC)
  2. PHP 5.3.6
  3. Apache 2.2.19
  4. vps上的CentOS 5.6 i686 virtuozzo
  5. cPanel WHM 11.30.1(build 4)
  6. Mysql 5.1.56-log
  7. Mysqli API 5.1.56
  8. 突然对mysql做了一些“SHOW CREATE TABLE”查询,我得到了这个。

    [Wed Jul 20 17:35:23 2011
    ] [notice] EACCELERATOR(5827): PHP crashed on opline 138 of fetch_fields() at /usr/lib/php/Zend/Db/Statement/Mysqli.php:235
    

    我已尝试禁用eaccelerator但未成功

    [Wed Jul 20 17:45:34 2011] [warn] [client 190.78.208.30] (104)Connection reset by peer: mod_fcgid: error reading data from FastCGI server
    [Wed Jul 20 17:45:34 2011] [error] [client 190.78.208.30] Premature end of script headers: index.php
    [Wed Jul 20 17:45:34 2011] [error] mod_fcgid: process /usr/local/cpanel/cgi-sys/php5(11562) exit(communication error), get unexpected signal 11
    [Wed Jul 20 17:45:34 2011] [warn] [client 190.78.208.30] (104)Connection reset by peer: mod_fcgid: error reading data from FastCGI server
    [Wed Jul 20 17:45:34 2011] [error] [client 190.78.208.30] Premature end of script headers: index.php
    

    有问题的一行是这样的:$ row = $ db-> fetchRow(“SHOW CREATE TABLE 222AFI”);.如果我在执行之前返回,一切都很顺利。 $ db是Zend_Db_Adapter_Mysqli的实例。最糟糕的是,这不是确定性的。该程序可以通过一些时间而其他一些不通过。通常它不会在没有崩溃的情况下通过该行。

    <?php
    class Admin_DbController extends Controller_BaseController
    {
        /**
         * 
         */
        public function updateSqlDefinitionsAction()
        {
            $db = Zend_Registry::get('db'); 
            $row = $db->fetchRow("SHOW CREATE TABLE 222AFI");
        }
    }
    ?>
    

    我没有写信给internals@lists.php.net因为我没有https://bugs.php.net/bugs-generating-backtrace.php。它可能是愚蠢的,但我尝试用“--enable-debug”重新编译apache,(这是一个生产服务器)。但是“PHP Apache模块:运行httpd -X,并访问崩溃PHP的脚本”是我无法工作的部分。服务器告诉我端口80已被使用。

    有人能给我一些建议吗? 如果我正在做一些疯狂的事情,至少还有其他一些选择吗?

    我可以尝试在午夜重新编译apache,但知道我不会破坏任何东西真是太棒了。你怎么看这对我来说非常重要。

    修改

    我用--enable-debug编译php。这很奇怪,它没有像往常那样崩溃。很难,20次尝试也许一次崩溃。如果使用-X启动apache,则更难让php崩溃,因为httpd需要很长时间才能响应。

    EDIT2

    即使它是在20次尝试之后,如果我在没有-X标志的情况下启动httpd,我也会崩溃。但是我模仿了一个初始化$ _SERVER变量的脚本,以使Zend相信它是通过浏览器调用的。当我用“php crash.php”多次执行此脚本(如50)时,一切正常。我开始相信它与php重用过程有关。我正在使用mod_fcgi和

    运行apache
    Server version: Apache/2.2.19 (Unix)
    Server built:   Jul 20 2011 19:18:58
    Cpanel::Easy::Apache v3.4.2 rev9999
    Server's Module Magic Number: 20051115:28
    Server loaded:  APR 1.4.5, APR-Util 1.3.12
    Compiled using: APR 1.4.5, APR-Util 1.3.12
    Architecture:   32-bit
    Server MPM:     Prefork
      threaded:     no
        forked:     yes (variable process count)
    Server compiled with....
     -D APACHE_MPM_DIR="server/mpm/prefork"
     -D APR_HAS_SENDFILE
     -D APR_HAS_MMAP
     -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
     -D APR_USE_SYSVSEM_SERIALIZE
     -D APR_USE_PTHREAD_SERIALIZE
     -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
     -D APR_HAS_OTHER_CHILD
     -D AP_HAVE_RELIABLE_PIPED_LOGS
     -D DYNAMIC_MODULE_LIMIT=128
     -D HTTPD_ROOT="/usr/local/apache"
     -D SUEXEC_BIN="/usr/local/apache/bin/suexec"
     -D DEFAULT_PIDLOG="logs/httpd.pid"
     -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
     -D DEFAULT_LOCKFILE="logs/accept.lock"
     -D DEFAULT_ERRORLOG="logs/error_log"
     -D AP_TYPES_CONFIG_FILE="conf/mime.types"
     -D SERVER_CONFIG_FILE="conf/httpd.conf"
    

5 个答案:

答案 0 :(得分:2)

请看一下https://bugs.php.net/bug.php?id=55414,有人终于得到了它。部分解决方案比我的更好。

答案 1 :(得分:0)

你可以在服务器上运行phpinfo()并发布thread_safety的结果吗?如果您的apache不是线程安全的,那么php应该以相同的方式编译。

答案 2 :(得分:0)

首先尝试编写一个重现问题的最小示例,即不使用Zend框架,Apache等。只需要一个10行左右的脚本来设置数据库连接并发出查询。

答案 3 :(得分:0)

我找到了一个临时解决方案。这很难看,但很适合:

public function selectCmd($q){

    $charsFrom = array("\\a", "\\t", "\\n", "\\v", "\\f", "\\r", "\\\\", "\\0", "\\\"", "\\\'", "\\b");
    $charsTo = array("\a", "\t", "\n", "\v", "\f", "\r", "\\", "\0", "\"", "\'", "\b");

    exec('echo ' . escapeshellarg($q) . ' | mysql' .
        ' -h ' . escapeshellarg($this->_config['host']).
        ' -u ' . escapeshellarg($this->_config['username']).
        ' -p' . escapeshellarg($this->_config['password']).
        ' ' . escapeshellarg($this->_config['dbname']), $output);

    $colNames = explode("\t", array_shift($output));
    foreach ($colNames as &$colName){
        $colName = str_replace($charsFrom, $charsTo, $colName);
    }
    unset($colName);

    $rowSet = array();
    foreach ($output as $line){
        $row = array();
        $rawRow = explode("\t", $line);
        for ($i = 0; $i < count($rawRow); ++ $i){
            $row[$colNames[$i]] = str_replace($charsFrom, $charsTo, $rawRow[$i]);
        }
        $rowSet[] = $row;
    }
    return $rowSet;
}

您需要使用真实连接数组替换$ this-&gt; _config。

此脚本运行任何返回行的SQL命令。现在是我正在采取的解决方案。如果有人希望主动帮助我,我仍然有消息来源。我也是使用PHPUnit和Zend(确定性)的PHP seg-fault的人。我在工作中做这一切,没有足够的资源来测试它。谢谢你的理解。

答案 4 :(得分:0)

此处的建议有助于解决我正在处理的网络服务的分段错误:

http://kb.zend.com/index.php?View=entry&EntryID=436

“解决方法是在php.ini中为参数'date.timezone'设置一个值。例如:

date.timezone =“America / New_York” 支持的时区列表可在此处获取 - www.php.net/manual/en/timezones.php“