2011-07-20 8 views
6

he estado programando un sitio usando:PHP culpa seg programación

  1. Zend Framework 1.11.5 (completa MVC)
  2. PHP 5.3.6
  3. Apache 2.2.19
  4. CentOS 5.6 virtuozzo i686 en VPS
  5. cPanel WHM 11.30.1 (build 4)
  6. MySQL 5.1.56-log
  7. API Mysqli 5.1.56

De repente, haciendo unas pocas consultas "MOSTRAR CREAR MESA" a mysql, obtuve esto.

[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 

He intentado desactivar eaccelerator sin éxito

[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 

La línea problemática es la siguiente: $ fila = $ db-> fetchRow ("SHOW CREATE TABLE 222AFI") ;. Si regreso antes de que se ejecute, todo va bien. $ db es una instancia de Zend_Db_Adapter_Mysqli. La peor parte es que no es determinista. El programa puede pasar algunas veces y otras no. Normalmente NO pasará la línea sin bloquear php.

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

no he escrito a [email protected] porque no tengo la https://bugs.php.net/bugs-generating-backtrace.php. Puede ser tonto, pero intenté recompilar Apache con "--enable-debug", (este es un servidor de producción). Sin embargo, "PHP Apache Module: ejecute httpd -X, y acceda al script que bloquea PHP". Es la parte en la que no funciono. El servidor me dice que el puerto 80 ya está en uso.

¿Alguien me puede dar un consejo? Si estoy haciendo algo enojado, ¿al menos algunas otras opciones?

Puedo intentar recompilar Apache a la medianoche, pero sería genial saber que no romperé nada. Cómo ves esto es muy importante para mí.

EDITAR:

llegué a compilar PHP con --enable-debug. Esto es raro, no está fallando como lo haría normalmente. Es difícil, de 20 intentos tal vez uno se cuelga. Y si inicia apache con -X, es aún más difícil que falle php porque httpd tarda demasiado en responder.

Edit2:

Incluso si es después de 20 intentos, puedo hacerlo chocar si comienzo httpd sin bandera -X. Sin embargo, emulé un script que inicializa las variables $ _SERVER para hacer que Zend crea que se está llamando a través de un navegador. Cuando ejecuto este script con "php crash.php" muchas veces (como 50) todo va normal. Estoy empezando a creer que tiene algo que ver con los procesos reutilizados de php. Estoy corriendo Apache con mod_fcgi y:

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" 
+1

" el servidor me la dice el puerto 80 ya está siendo utilizado ". Mata el proceso 'httpd' existente primero. Esto significa detener el servicio Apache, si lo tiene configurado para ejecutarse como un servicio. –

+0

Y probablemente en este caso, el contenedor FCGI debe volcar la traza inversa. – hakre

+0

Supongo que hay una manera de excluir archivos de la caché/optcoded. ¿Por qué no hacer eso hasta que encuentre una solución más permanente? –

Respuesta

0

¿Se puede ejecutar un phpinfo() en el servidor y publicar el resultado de thread_safety? si su apache no es seguro para subprocesos, entonces php debe compilarse de la misma manera.

+0

Hola, gracias. PHP está compilado con la seguridad de subprocesos también deshabilitada. –

0

Primero intente escribir un ejemplo mínimo que reproduzca el problema, es decirno usando Zend framework, Apache, etc. Solo un script de 10 líneas o más que configura una conexión de base de datos y emite una consulta.

+0

La cuestión es que es bastante difícil sacar los errores de Zend MVC. Esta es la segunda vez que obtengo un seg-fault PHP de hacer cosas en él. Otro fue con PHPUnit dentro de MVC. Lamentablemente me he visto obligado a buscar soluciones sin resolver el problema real. –

0

Encontré una solución temporal. Esto es feo, pero se ajusta:

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

Tendrá que sustituir a $ this -> _ configuración con una matriz conexión real.

Este script ejecuta cualquier comando SQL que devuelve filas. Por ahora es la solución que estoy tomando. Si alguien desea ayudarme proactivamente, todavía tengo las fuentes. También soy el tipo que tiene el seg-fault de PHP usando PHPUnit con Zend (determinísticamente). Estoy haciendo todo esto en mi trabajo, no tengo los recursos para probarlo. Gracias por tu comprensión.

0

Una sugerencia aquí ayudó fijo mi fallo de segmentación para un servicio web que estaba tratando con:

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

"La solución consiste en establecer un valor para el parámetro 'date.timezone' en php.ini . Por ejemplo:

date.timezone = "América/New_York" la lista de zonas horarias compatible está disponible aquí - www.php.net/manual/en/timezones.php "

+1

¿Una solución para cada causa segfault? Yo no lo creo :( – symcbean

Cuestiones relacionadas