PHP programming seg fault
Asked Answered
C

5

6

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"
Coworker answered 20/7, 2011 at 22:54 Comment(7)
"The server tells me the port 80 is already being used." Kill the existing httpd process first. This means stopping the Apache service, if you have it configured to run as a service.Truong
And probably in this case, the FCGI wrapper must dump the backtrace.Importunacy
I assume there is a way to exclude files from being cached/optcoded. Why not do that until you find a more permanent solution?Sikora
belongs on serverfault.com: Q&A for system administratorsDelicatessen
Do you recommend me to publish this question there?Warrior
So i decided to move my question to serverfault.com/questions/292509/…. Thank you for your feedback and support.Warrior
Honestly, make a backup and change your hosting provider :)Northernmost
C
2

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.

Coworker answered 16/8, 2011 at 16:6 Comment(0)
F
0

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.

Fording answered 21/7, 2011 at 13:37 Comment(1)
Hi, thanks. PHP is compiled with thread safety disabled as well.Warrior
U
0

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.

Uranology answered 21/7, 2011 at 13:41 Comment(1)
The thing is it's pretty hard to get the errors out of Zend MVC. This is the second time i get a PHP seg-fault from doing things in it. Another one was with PHPUnit inside MVC. Sadly i've been forced to look at workarounds without solving the real problem.Warrior
C
0

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.

Coworker answered 25/7, 2011 at 18:21 Comment(0)
B
0

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"

Barrelhouse answered 17/8, 2011 at 14:48 Comment(1)
One solution to every segfault cause? I don't think so :(Participation

© 2022 - 2024 — McMap. All rights reserved.