简体   繁体   English

PHP 编程段故障

[英]PHP programming seg fault

I've been programming a site using:我一直在使用以下方法编写网站:

  1. Zend Framework 1.11.5 (complete MVC) Zend Framework 1.11.5(完整的 MVC)
  2. PHP 5.3.6 PHP 5.3.6
  3. Apache 2.2.19 Apache 2.2.19
  4. CentOS 5.6 i686 virtuozzo on vps CentOS 5.6 i686 virtuozzo 在 vps
  5. cPanel WHM 11.30.1 (build 4) cPanel WHM 11.30.1(构建 4)
  6. Mysql 5.1.56-log Mysql 5.1.56-日志
  7. Mysqli API 5.1.56 Mysqli API 5.1.56

Suddenly doing a few "SHOW CREATE TABLE" query to mysql, i got this.突然对 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

I've tried disabling eaccelerator without success我试过禁用加速器但没有成功

[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

The problematic line is this: $row = $db->fetchRow("SHOW CREATE TABLE 222AFI ");.有问题的行是:$row = $db->fetchRow("SHOW CREATE TABLE 222AFI");。 If i return before it executes, everything goes fine.如果我在它执行之前返回,一切都会好起来的。 $db is instance of Zend_Db_Adapter_Mysqli. $db 是 Zend_Db_Adapter_Mysqli 的实例。 The worst part is that is not deterministic.最糟糕的部分是它不是确定性的。 The program can pass some times and some others not.该程序有时可以通过,而另一些则不能。 Normally it WON'T pass the line without crashing php.通常它不会通过线路而不崩溃 php。

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

I haven't written to internals@lists.php.net because i haven't the https://bugs.php.net/bugs-generating-backtrace.php .我没有写信给 internals@lists.php.net 因为我没有https://bugs.php.net/bugs-generating-backtrace.php It may be dumb, but i tried recompiling apache with "--enable-debug", (this is a production server).它可能很愚蠢,但我尝试使用“--enable-debug”重新编译 apache,(这是生产服务器)。 However "PHP Apache Module: Run httpd -X, and access the script that crashes PHP" Is the part i don't get working.但是“PHP Apache 模块:运行 httpd -X,并访问使 PHP 崩溃的脚本”是我无法正常工作的部分。 The server tells me the port 80 is already being used.服务器告诉我端口 80 已被使用。

Can anyone give me some advice?谁能给我一些建议? If i'm doing something mad, at least some other options?如果我在做一些疯狂的事情,至少还有其他选择?

I can try to recompile apache at midnight, but it'd be great to know i won't break anything.我可以尝试在午夜重新编译 apache,但很高兴知道我不会破坏任何东西。 How you see this is very important to me.你如何看待这对我来说非常重要。

EDIT :编辑

I got to compile php with --enable-debug.我必须使用 --enable-debug 编译 php。 This is weird, it is not crashing as it would normally do.这很奇怪,它没有像通常那样崩溃。 It's hard, of 20 attempts maybe one crashes.这很难,20 次尝试中可能有一次崩溃。 And if start apache with -X, it's even harder to get php crashing because httpd takes too long to respond.如果使用 -X 启动 apache,则更难让 php 崩溃,因为 httpd 响应时间太长。

EDIT2 :编辑2

Even if it's after 20 attempts, i can make it crash if i start httpd without -X flag.即使在 20 次尝试之后,如果我在没有 -X 标志的情况下启动 httpd,我也可以让它崩溃。 However i emulated a script which initializes $_SERVER variables to make Zend believe it's being called through a browser.但是我模拟了一个初始化 $_SERVER 变量的脚本,以使 Zend 相信它是通过浏览器调用的。 When i execute this script with "php crash.php" many times (like 50) everything goes normal.当我用“php crash.php”多次(如50次)执行此脚本时,一切正常。 I'm starting to believe it has something to do with php re-used processes.我开始相信它与 php 重用进程有关。 I'm running apache with mod_fcgi and:我正在使用 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"

please take a look at https://bugs.php.net/bug.php?id=55414 , someone finally got with it.请看一下https://bugs.php.net/bug.php?id=55414 ,终于有人接受了。 The partial solution is better implemented than mine.部分解决方案比我的实施得更好。

can you run a phpinfo() on the server and post the result for thread_safety?您可以在服务器上运行 phpinfo() 并发布 thread_safety 的结果吗? if your apache is not thread safe, then php should be compiled the same way.如果您的 apache 不是线程安全的,那么 php 应该以相同的方式编译。

First try writing a minimal example that reproduces the problem, ie not using Zend framework, Apache etc. Just a 10-line or so script that sets up a database connection and issues a query.首先尝试编写一个重现问题的最小示例,即不使用 Zend 框架、Apache 等。只需一个 10 行左右的脚本来设置数据库连接并发出查询。

I found a temporary solution.我找到了一个临时解决方案。 This is ugly, but fits:这很丑陋,但适合:

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;
}

You'll need to replace $this->_config with a real connection array.您需要将 $this->_config 替换为真实的连接数组。

This script runs any SQL command which returns rows.此脚本运行任何返回行的 SQL 命令。 For now is the solution i'm taking.现在是我正在采取的解决方案。 If someone wishes to help me proactively i still have the sources.如果有人希望主动帮助我,我仍然有消息来源。 I'm also the guy who has the PHP seg-fault using PHPUnit with Zend (deterministically).我也是使用 PHPUnit 和 Zend(确定性地)出现 PHP 段故障的人。 I'm doing all this in my job, don't have the resources to test out of it.我在我的工作中做这一切,没有资源来测试它。 Thank you for your comprehension.感谢您的理解。

A suggestion here helped fixed my segmentation fault for a web service I was dealing with:这里的一个建议帮助修复了我正在处理的 web 服务的分段错误:

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

"The workaround is to set a value to the parameter 'date.timezone' in php.ini. For example: “解决方法是在 php.ini 中为参数 'date.timezone' 设置一个值。例如:

date.timezone = "America/New_York" The list of supported timezones is available here - www.php.net/manual/en/timezones.php" date.timezone = "America/New_York" 此处提供支持的时区列表 - www.php.net/manual/en/timezones.php"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM