Я программировал сайт, используя:
Проблема началась здесь https://stackoverflow.com/questions/6769515/php-programming-seg-fault. Короче говоря, 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
О расширениях. Когда я компилирую php с флагом «--enable-debug», мне нужно отключить эту строку:
zend_extension="/usr/local/IonCube/ioncube_loader_lin_5.3.so"
В противном случае сервер не принимает запросы, и я получаю сообщение «Соединение с сервером было сброшено». Возможно, мне придется отключить eaccelerator по той же причине. Я до сих пор не понимаю, почему apache запускает его несколько раз, а некоторые нет:
extension="eaccelerator.so"
В любом случае, после того, как я запустил httpd, ошибки сегментации могут возникать случайным образом. Если я не компилирую php с флагом "--enable-debug", я могу ДЕТЕРМИНИСТИЧНО получить сбой php:
<?php
class Admin_DbController extends Controller_BaseController
{
public function updateSqlDefinitionsAction()
{
$db = Zend_Registry::get('db');
$row = $db->fetchRow("SHOW CREATE TABLE 222AFI");
}
}
?>
НО, если я компилирую php с флагом «--enable-debug», очень сложно получить эту ошибку. Я должен добавить немного сложности, чтобы он рухнул. Мне нужно выполнить много параллельных запросов в течение нескольких секунд, чтобы получить сбой:
<?php
class Admin_DbController extends Controller_BaseController
{
public function updateSqlDefinitionsAction()
{
$db = Zend_Registry::get('db');
$tableList = $db->listTables();
foreach ($tableList as $tableName){
$row = $db->fetchRow("SHOW CREATE TABLE " . $db->quoteIdentifier($tableName));
file_put_contents(
DB_DEFINITIONS_PATH . '/' . $tableName . '.sql',
$row['Create Table'] . ';'
);
}
}
}
?>
Обратите внимание, что это тот же сценарий, но он создает DDL для всех таблиц в базе данных, а не для одной. Кажется, что если php сильно загружен (с расширениями, и я делаю много параллельных запросов), это когда я получаю php сбой.
О запуске httpd с "-X": я пробовал. Дело в том, что уже сейчас сложно вызвать сбой php с помощью --enable-debug. С параметром «-X» (который включает только один дочерний процесс) я не могу выполнять параллельные запросы. Итак, я не смог создать правильную трассировку отладки: https://bugs.php.net/bugs-generating-backtrace.php
У меня конкретный вопрос: что мне делать, чтобы получить ядро?
root@GWT4 [~]# httpd -V
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"
Получение дампа ядра требует установки "размера файла ядра" rlimit
на что-то ненулевое для процесса (ов), из которого вы хотите получить дампы ядра. Учитывая, что вы используете PHP в FCGI, вам наплевать на сам Apache, это не вызывает сбоев; вы хотите иметь скрипт для запуска ulimit -c unlimited
затем запустите свой сервер FCGI.
Мне нравится иметь отдельный рабочий раздел для ядер, поэтому, если они станут немного большими или непослушными, они не вызовут проблем с заполнением диска где-либо еще - установите /proc/sys/kernel/core_pattern
к чему-то вроде /var/cores/%e-%p.core
.
Не уверен, поможет ли это в этом случае, но я установил только одного дочернего элемента, нашел PID, а затем отладил его с помощью strace
strace -p PID
Нашел временное решение. Это некрасиво, но подходит:
публичная функция 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 -> _ config на реальный массив соединений.
Этот сценарий запускает любую команду SQL, которая возвращает строки. На данный момент это решение, которое я принимаю. Если кто-то захочет помочь мне проактивно, у меня все еще есть источники. Я также парень, у которого есть ошибка сегментации PHP, использующая PHPUnit с Zend (детерминированно). Я делаю все это в своей работе, у меня нет ресурсов, чтобы проверить это. Спасибо за ваше понимание.
Вы должны использовать ioncube_loader и eaccelerator? Что касается eaccelerator, их поддержка 5.3.x была в лучшем случае нестабильной, и большинство пользователей версии 5.3 полагаются на APC (который также будет лучше работать через FCGI).
Если вы должны использовать eaccelerator, выполняете ли вы «make distclean», а затем их постоянные инструкции INSTALL (дважды проверяя, что загружаемый вами phpize предназначен для версии 5.3.6, а не для каких-то остатков от предыдущей установки)? Я подозреваю, что в этом и есть весь источник ваших coredump, и что Apache вовсе не виноват.