András Gyömrey
András Gyömrey

Reputation: 1829

PHP programming seg fault

I've been programming a site using:

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

Suddenly doing a few "SHOW CREATE TABLE" query to mysql, i got this.

[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 ");. If i return before it executes, everything goes fine. $db is instance of 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
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 [email protected] because i haven't the 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). However "PHP Apache Module: Run httpd -X, and access the script that crashes PHP" Is the part i don't get working. The server tells me the port 80 is already being used.

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. How you see this is very important to me.

EDIT:

I got to compile php with --enable-debug. This is weird, it is not crashing as it would normally do. It's hard, of 20 attempts maybe one crashes. And if start apache with -X, it's even harder to get php crashing because httpd takes too long to respond.

EDIT2:

Even if it's after 20 attempts, i can make it crash if i start httpd without -X flag. However i emulated a script which initializes $_SERVER variables to make Zend believe it's being called through a browser. When i execute this script with "php crash.php" many times (like 50) everything goes normal. I'm starting to believe it has something to do with php re-used processes. I'm running apache with mod_fcgi and:

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"

Upvotes: 6

Views: 4839

Answers (5)

Usman
Usman

Reputation: 156

A suggestion here helped fixed my segmentation fault for a web service I was dealing with:

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:

date.timezone = "America/New_York" The list of supported timezones is available here - www.php.net/manual/en/timezones.php"

Upvotes: 0

Andr&#225;s Gy&#246;mrey
Andr&#225;s Gy&#246;mrey

Reputation: 1829

please take a look at https://bugs.php.net/bug.php?id=55414, someone finally got with it. The partial solution is better implemented than mine.

Upvotes: 2

Andr&#225;s Gy&#246;mrey
Andr&#225;s Gy&#246;mrey

Reputation: 1829

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 script runs any SQL command which returns rows. 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). I'm doing all this in my job, don't have the resources to test out of it. Thank you for your comprehension.

Upvotes: 0

Roel
Roel

Reputation: 19622

First try writing a minimal example that reproduces the problem, i.e. not using Zend framework, Apache etc. Just a 10-line or so script that sets up a database connection and issues a query.

Upvotes: 0

marcelog
marcelog

Reputation: 7180

can you run a phpinfo() on the server and post the result for thread_safety? if your apache is not thread safe, then php should be compiled the same way.

Upvotes: 0

Related Questions