Стабилизируем PHP на бою — что и почему «роняет» веб-сервер

    Вы отвечаете за стабильность работы веб-проекта на PHP. Нагрузка постоянно растет, добавляются фичи, клиенты довольны. В один прекрасный день начинают появляться загадочные ошибки…

    Ошибки серверного софта


    … которые программисты не знают как исправить, т.к. «ломается» серверный софт, например связка apache-PHP — а клиент получает в ответ на запрос страницу о регламентных работах. Веб-разработчик часто не обладает глубокими знаниями в программировании на C в unix/linux, а сисадмин нередко, к сожалению, глубже bash в систему не погружается. Настоящий хардкор :-)

    Нестабильная работа серверных скриптов


    Нередко, определенные страницы веб-проекта начинают сходить с ума. Например выполняться по 15 минут и выяснить, чем же они занимаются, непросто. В прошлом посте на данную тему я описал одну из методик определения, чем занимается PHP-скрипт на боевом сервере, но чувствуется, что нужен более мощный инструмент.

    На практике я часто встречаю проекты, которые сталкиваются с подобным классом ошибок «серверного софта», и в команде не всегда знают, что делать. В логе apache часто появляются сообщения о нарушении сегментации (segmentation fault), клиенты получают страницу об ошибке, а веб-разработчик с сисадмином ломают себе голову, играются с разными версиями PHP/apache/прекомпилятора, собирают PHP из исходников с разными опциями снова и снова, пишут о багах, а им доказывают, что это баги не PHP, а их кода и так до бесконечности…

    В статье я хочу рассказать как можно просто и быстро найти причину, почему PHP рассыпался на боевом сервере и устранить ее — не погружаясь в прекрасный мир системного программирования на C для unix :-) От вас потребуется желание и одна чашечка кофе.



    Смотрим в лог ошибок веб-сервера


    Если в логе ошибок apache вы видите что-то подобное, то статья для вас:
    [Mon Oct 01 12:32:09 2012] [notice] child pid 27120 exit signal Segmentation fault (11)


    В данном случае бесполезно искать подробную информацию в логе ошибок PHP — ведь грохнулся сам процесс, а не скрипт. Если заранее не сделать на nginx симпатичную страничку о регламентных работах, то клиенты увидят аскетичную ошибку «50*».

    Хочется дать кому-нибудь в морду, но кому? :-) Чтобы отвлечься от деструктивных решений, вспомним теорию.

    Что такое «signal»? Это, можно сказать, средство, которое операционная система использует, чтобы сказать процессу, что он, например, не прав :-) Берет и, нарушая законы математики, делит на… 0, или насильственными действиями вызывает переполнение стека. В данном случае мы видим сигнал с номером 11 и названием «SIGSEGV». Список сигналов можно посмотреть, выполнив «kill -l»:
    ...
    11) SIGSEGV
    ...


    Некоторые сигналы, например SIGSEGV — нельзя перехватить, поэтому ваш процесс apache-PHP будет безжалостно убит ядром без суда и следствия. Оказывается именно его перехватить — можно, но нужно лезть в исходники :-)

    А за что убили то?


    Теперь найдем причину, за что же убили процесс apache-PHP? Для этого нужно настроить создание дампа памяти процесса в момент убийства :-) или coredump. Да, да — до сих пор используется устаревший лет эдак на 50 термин, означающий сохранение данных с магнитных сердечников. Как только в следующий раз процесс будет убит операционной системой, будет ядром создан файл — место и его название можно настроить. Если вы в консоли, просто наберите «man 5 core».

    Например, можно складывать файлы в папочку так:
    echo "/tmp/httpd-core.%p" > /proc/sys/kernel/core_pattern

    Если ничего не задать, система создаст файл с именем «core.#process_number#» в рабочей директории процесса.

    Только проследите, чтобы процесс apache-PHP имел туда право записи.

    Это еще не всё. По-умолчанию, скорее всего, в вашей системе отключена генерация coredump-файлов. Ее можно включить, вставив в начало скрипта запуска веб-сервера строку:
    ulimit -с unlimited
    или, чтобы сделать настройку постоянной, отредактировать файлик "/etc/security/limits.conf". Туда можно вставить:
    apache - core -1

    Подробности по формату файла — " man limits.conf".

    Однако, пока я для apache не настроил папку для coredump-файлов, ничего не работало ("/etc/httpd/conf/httpd.conf"):
    CoreDumpDirectory /tmp


    Теперь перезапускаем апач:
    service httpd restart


    Тестируем. Вручную убьем процесс:
    ps aux | grep httpd

    kill -11 12345

    Смотрим в "/var/log/httpd/error_log":
    [Mon Oct 01 16:12:08 2012] [notice] child pid 22596 exit signal Segmentation fault (11), possible coredump in /tmp


    В "/tmp" теперь найдем файлик с названием типа "/tmp/httpd-core.22596"

    Вы научились получать дамп памяти убитого процесса. Теперь ждем, когда процесс будет убит естественным образом.

    На месте преступления — толкуем coredump


    Важно знать, что если PHP собрана без отладочных символов (ключик --enable-debug, -g для gcc при компиляции) — мы потеряем много полезной информации. Однако, если вы собрали PHP из исходников даже без этой опции, и исходники лежат рядом — этого может хватить для анализа.
    Еще есть очень распространенное заблуждение, что отладочная сборка влияет на производительность и потребляемую процессом память (memory footprint). Не влияет, а лишь увеличивается размер исполняемого файла. Поэтому, если не сможете разобраться в причине ошибки без отладочной сборки — попросите сисадмина собрать модуль PHP с отладочными символами.

    Чем открыть coredump? Конечно старой и «очень доброй» утилитой — gdb, изначально написанной верховным апостолом движения бесплатного свободного программного обеспечения Ричардом Столманом.
    Разобраться, как работает отладчик, не займет много времени. Можно за пару часиков поглотить один из самых занимательных учебников, а можно попросить это сделать сисадмина ;-)

    Обычно открывают coredump так:
    gdb путь_к_выполняемому_файлу_веб-сервера путь_к_coredump

    Все уважающие себя разработчики на C в unix конечно умеют пользоваться этим отладчиком, делают это, наверное, каждый день, но, к сожалению, их может не быть в вашей команде. И есть еще одно неприятное НО…

    Отладка PHP в gdb — черная магия


    Дело в том, что скомпилированный в байткод скрипт PHP это… не совсем программа на C ;-) Нужно, правда совсем немного,
    разобраться во внутренностях движка Zend — и вы все поймете довольно быстро. А именно — нужно найти в трейсе последний вызов функции execute, перейти в этот frame стека и исследовать локальные переменные (op_array), а также заглянуть в глобальные переменные движка Zend:
    (gdb) frame 3
    #3  0x080f1cc4 in execute (op_array=0x816c670) at ./zend_execute.c:1605
    (gdb) print (char *)(executor_globals.function_state_ptr->function)->common.function_name
    $14 = 0x80fa6fa "pg_result_error"
    (gdb) print (char *)executor_globals.active_op_array->function_name
    $15 = 0x816cfc4 "result_error"
    (gdb) print (char *)executor_globals.active_op_array->filename
    $16 = 0x816afbc "/home/yohgaki/php/DEV/segfault.php"
    


    В op_array можно запутаться, поэтому полезна команда просмотра типа этой структуры:
    (gdb) ptype op_array
    type = struct _zend_op_array {
        zend_uchar type;
        char *function_name;
        zend_class_entry *scope;
        zend_uint fn_flags;
        union _zend_function *prototype;
        zend_uint num_args;
        zend_uint required_num_args;
        zend_arg_info *arg_info;
        zend_bool pass_rest_by_reference;
        unsigned char return_reference;
        zend_uint *refcount;
        zend_op *opcodes;
        zend_uint last;
        zend_uint size;
        zend_compiled_variable *vars;
        int last_var;
        int size_var;
        zend_uint T;
        zend_brk_cont_element *brk_cont_array;
        zend_uint last_brk_cont;
        zend_uint current_brk_cont;
        zend_try_catch_element *try_catch_array;
        int last_try_catch;
        HashTable *static_variables;
        zend_op *start_op;
        int backpatch_count;
        zend_bool done_pass_two;
        zend_bool uses_this;
        char *filename;
        zend_uint line_start;
        zend_uint line_end;
        char *doc_comment;
        zend_uint doc_comment_len;
        void *reserved[4];
    } *
    


    Процесс отладки заключается в хождении между фреймами стека («frame N»), переходе в каждый вызов функции «execute» и исследовании ее локальных аргументов («print name», «ptype name»). Чем меньше номер фрейма, тем вы глубже. Иногда полезно зайти в гости в экстеншн PHP и посмотреть, где произошла ошибка и почему (хотя бы попытаться понять причину).

    (gdb) frame #номер#
    (gdb) print op_array.function_name
    $1 = 0x2aaab7ca0c10 "myFunction"
    (gdb) print op_array.filename
    $2 = 0x2aaab7ca0c20 "/var/www/file.php"
    


    И так далее…

    Если вы поперхнулись кофе :-), то просто запомните, что переходя между фреймами стека вызовов с помощью команды «frame #N#», можно смотреть всего определенные элементы этой структуры — и вы точно сможете установить в каком файле PHP была вызвана функция PHP, какую функцию она вызвала и т.п. — и доберетесь до причины «Segmentation Fault» или другой ошибки, убившей процесс. И объясните программистам — в чем причина и ее поправят! Быстро и, надо быть оптимистами — навсегда.

    Распространенные причины ошибок


    Начните просматривать coredump-файлы (или поручите это сисадмину) и вы довольно быстро научитесь классифицировать ошибки по группам:
    1) Проблемы в расширениях PHP. В этом случае либо отключите расширение, либо попробуйте поиграть его настройками. Вы точно знаете, что проблема в нем, дело за малым.
    2) Проблема с рекурсией, стеком. Вы можете наступить на ошибку, при которой функция библиотеки, например, pcre, входит в рекурсию и вызывает себя тысяч двадцать раз. Можно либо настроить параметры библиотеки или, если лень, добавить процессу побольше стека ("/etc/init.d/httpd"):

    ulimit -s «ставим значение больше»

    А текущее значение можно посмотреть командой: «ulimit -a» (man ulimit, далее ищем «ulimit»).
    3) Проблемы в ядре PHP — тут нужно писать разработчикам PHP :-)

    В общем, круг причин ошибки будет серьезно сокращен. Что нам и нужно.

    Отладка запущенного процесса


    Это еще не все. Если вы не можете получить coredump — можно подключиться к запущенному процессу и погулять по нему. Пока вы внутри процесса, его выполнение приостанавливается («ps aux | grep apache | grep 'T '» — он будет в состоянии трейсинга). Когда покинете его — он снова продолжит выполняться. Подключиться можно так:
    gdb -p ид_процесса

    Итоги


    В статье мы научились «правильно готовить» ошибки серверного софта, делать отладочные сборки apache-PHP, создавать coredump-файлы и правильно их толковать, используя символьный отладчик. Еще мы узнали, что из coredump-файла можно найти конкретный файл PHP и функцию, вызвавшую ошибку.

    Теперь можно составить чеклист для менеджера для борьбы с загадочными серверными ошибками, в которых не могут разобраться ни веб-разработчики, ни сисадмины:

    1. Включить сбор coredump-файлов на сервере (сисадмин)
    2. При необходимости пересобрать apache-PHP с отладочными символами (сисадмин)
    3. С помощью gdb (выходные на его изучение) исследовать причину появления ошибки (сисадмин с веб-разработчиком)
    4. Принять меры по ее устранению или снижению частоты появления: поменять настройки, обновить софт, написать в багтрекер, отключить расширение PHP и т.п.


    В заключение приглашаю всех на наш облачный сервис Битрикс24, в котором мы эффективно используем все описанные в статье технологии.

    Всем удачи и стабильной работы веб-проектов!
    1С-Битрикс
    73,00
    Компания
    Поделиться публикацией

    Комментарии 72

      +6
      А картинки очевидно для заманухи? Работает — к PHP отношения не имею, но пост проглядел)
        +6
        Картинки — чтобы с ума не сойти, читая жесткий хардкор из смести юникса, С, gdb и терминов начала эпохи компьютеризации :-)
          +6
          В таком случае, голые тётеньки смотрелись бы лучше :)
            +1
            Хорошая идея, Миш :-) В следующей статейке сделаю иллюстрации в стиле легкой мотивирующей на кодинг эротики :-)
            0
            Факт, но и отвлекали бы больше :)
            0
            Сначала подумал, что это песец, но, наскольку уж я не разбираюсь в зоологии — это лисы :)
          +2
          Я думаю эти знания пригодятся и другим программистам python, java, erlang etc.
          +4
          Дорога ложка к обеду. Как раз кстати.
            +3
            Да я сам сколько мучился, раньше постоянно тряс сисадминов в поисках причины. Оказалось проще самому было разобраться и решить проблему раз и навсегда.
            +3
            Для меня всегда этот сегфол был черным ящиком. Теперь хоть стало понятно, что с этим делать :) И, кстати, это мне кажется или с каждой статьей стиль изложения все оттачивается? :)

            Респект!
              +1
              Спасибо. Очень полезно. В закладки однозначно.
                +1
                apache для PHP? А php-fpm Вы пробовали?
                  +4
                  Ну конечно пробовали. Битрикс24 работает на php-fpm. Но…
                  1) Не всем подходит php-fpm по, назовем помягче, историческим причинам
                  2) Некоторым нужны модуля апача, которых нет в нгинксе.

                  И конечно php-fpm тоже сегфолтится, правда можно настроить его так, чтобы он релоадил упавший процесс. Да, клиенты почти этого не замечают, но причину ошибки то нужно найти? Для этого и статейка.
                    0
                    Да, клиенты почти этого не замечают

                    Да-да и вообще ни разу не бывает заходя в свою CRM для работы видя интересные сообщения, что либо аккаунта такого нет, либо ничего не работает.
                      0
                      А вы пишите в саппорт? Да, иногда случаются проблемы у амазона или со стабильностью MySQL, постоянно решаем их. С PHP обычно все тихо — работает хорошо.
                        0
                        Ну разок как-то весь день ничего не работало решил написать, только чтобы написать нужно авторизоваться, а при авторизации типа логина не найдено. По телефону по выходным — выходные, так что у вас там весело) Давно уже съехали сами и никому не советуем.
                          0
                          Не было такого, чтобы весь день ничего не работало, вы что — ~500 тестов в nagios берегут стабильность системы. С авторизацией — был баг, поправили.
                    +3
                    Для php-fpm проблем не меньше, он так же легко уходит в сегфолт, например, при дефолтных конфигах и рекурсивных регулярках (#([a-z])+# к примеру). Я бы сказал 50/50, уходя от монстроидального apache с его порой причудливыми конфигами (в более чем распространенных дистрах) к php-fpm ведет к проблеме его правильного приготовления, т.к. увы число системных администраторов способных на это пока остается в меньшенстве.
                      0
                      Вы сейчас про регулярки где? При дефолтных конфигах чего? Какой проблеме правильного приготовления?
                      Непонятно.
                      Регулярки в конфигах вебсервера? Или регулярки где-то в коде php? Как тут тогда конфиги php привязаны? Как там можно неправильно приготовить, параметров в конфиге чуть менее 10.
                        +1
                        Я говорю про дефолтные конфиги непосредственно PHP, что при стандартном stack size в 8-10M и дефолтном pcre.recursion_limit в 100000 в сегфолт от подобных регулярок в КОДЕ php уходит одинаково хорошо как php-fpm так и php в виде модуля к apache. Неправильно приготовить php-fpm можно скорее не конфигами самого php-fpm (как вы правильно подметили о количестве параметров) а настройками php, к примеру не отключить user_ini.filename или cgi.fix_pathinfo или еще не одним параметр специфичный и важный непосредственно в контексте php-fpm.
                    +1
                    Это все очень полезно большинству разработчиков и за это большое спасибо,
                    но соль всей темы: просто не используйте Apache, и будет меньше проблем.
                      +1
                      Отличная статья, а проблемы к сожалению будут как с apache так и без него.
                        0
                        см коммент ниже…
                          +3
                          ни кто не говорит обратное, а как дебажить корки, должен знать каждый разработчик. За что еще раз спасибо автору.
                          +3
                          Не используем и сегфолтится. Вот перечень мест где:
                          1) Падают периодически все прекомпиляторы пхп: apc, eaccelerator, xcache и, что удивительно! zend optimizer+.
                          2) pcre — по идиотски падает при нехватке ресурсов
                          3) Экстеншены некоторые при определенных конфигурационных параметрах
                          • НЛО прилетело и опубликовало эту надпись здесь
                              +1
                              Есть еще zend optimizer+. Это настоящий прекомпилятор байткода, и вроде быстрее немного eaccelerator. Но тоже падает иногда, да так красиво, что приходится делать на баше автомат релоада апача.
                            +1
                            Не спорю, Apache — «немного» устарел. Но все же, баги есть в каждом приложении, и желательно знать что делать, когда все плохо =)
                            +4
                            Из всего моего более чем 10 летнего опыта разработки на PHP, сегфолты ловит только в самописных расширениях и однажды поймал в php_memcached о чем была статья на Хабре. После Гугления оказалось, что ситуация была не редкая.
                              +1
                              А при внедрении платформы 1С-Битрикс у крупных клиентов типа eldorado.ru, euroset.ru и других — по причине большого числа PHP-файлов и кода разной сложности бывают нарушения сегментации при высокой нагрузке. И с ними нужно бороться. Раньше я помню падал прекомпилятор при освобождении указателя в движке зенда: efree(), сейчас круг причин стал пошире — приходится разбираться.
                                +4
                                Хотел написать практически то же самое, слово в слово. Причём на тех проектах, которые я писал, нагрузка была намного больше, чем на упомянутый автором Эльдорадо — счётчик рамблера на их сайте говорит, что там всего миллион просмотров страниц за день.

                                Мне кажется, авторам надо поискать ошибки где-то в корне своего Битрикса.
                                  0
                                  Проблема в том, что код битрикса вылизан разработчиками достаточно хорошо, ребята очень опытные. А вот сказки начинаются уже с самим прекомпилятором PHP и его модулями или между PHP и апачем. Одна проблема есть, до сих пор спорим откуда она возникает:
                                  1) Иногда, между nginx и apache внезапно скапливается тысячи незакрытых TCP-соединений
                                  2) Спрашивал у Игоря Сысовева где может быть баг, предполагает что в линуксе :-)

                                    +3
                                    Какое отношение PHP имеет к соединениям между апачем и нжинксом?
                                    Ещё раз повторюсь, за годы разработки нагруженных систем на PHP я сегфолты встречал исключительно в самописных модулях.
                                    Правда мы никогда не занимались сексуальными извращениями и использовали только PHP из репозиториев Debian.
                                      0
                                      Не имеет отношения, а баг проявляется. ПХП и apc, апач и нгинкс из репозиториев, centos — тоже. На дебиане тоже такое ловили, кстати.
                                        +1
                                        так а почему только на битриксе проявляется?
                                +2
                                Пример бы ещё более полный.
                                  +1
                                  Да хотел вставить последнюю сессию отладки, но там много данных конфиденциальных было. Как поймаю сегфолт несекьюрный, выложу обязательно.
                                  +2
                                  Отличная статья! Большое спасибо, Саш :)

                                  От себя добавлю, что в 95% процентах случаев на моей практике segfault есть следствие кривых расширений PHP и может быть отловлен их поэтапным включением/выключением. Ещё 4,9999 процента — это кривая сборка исходников. Оставшиеся случаи — это как раз поле деятельности gdb :)
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                      +1
                                      В точку! Не однократно вижу целые группы разработчиков, которые не в состоянии ответить нужен ли им какой либо php-модуль и приходтся открывать список функций и шерстить сорцы, а между тем их зоопарк это потенциальные баги, уязвимости и т.д. и т.п.
                                        +1
                                        Да, да. У проекта должна быть спецификация, составленная девелоперами, какие экстеншены пхп им нужны.
                                          +1
                                          выкинуть все ненужное нах. и работать будет лучше ;)
                                          • НЛО прилетело и опубликовало эту надпись здесь
                                              0
                                              Мы идем к тому, чтобы выкинуть php. Совсем не выкинешь, но многое.
                                              Вот чейнджлог и он пугает слегка. Одни сегфолты и критикалс.
                                                0
                                                В настоящее время, я работаю в проекте, где выкинули почти весь РНР, сделали, как модуль Апача (еще до меня).
                                                Архитектура стала не лучше, недостаток: привязка к конкретной ветки апача (1.3). В скорости формирования страницы выиграли не много (раза в три-четыре), хотя на потоке 6-10М простмотров — это экономит железа раза в два-три.
                                                Но в результате мы получили монолитный модуль. Сейчас часть логики выносим на отдельные удаленые сервисы в ввиде демонов.
                                                Если бы я был архитектором и начал проект заново, то сделал бы несколько scgi приложений, каждый на свою небольшую задачу и разруливал роутинг по url через nginx. Код значительно упростился бы и работал бы быстрее.

                                              +1
                                              опыт = сын ошибок трудных, еще со времен Пушкина
                                            +1
                                            У нас обычно php обвязан полезными тулзами на проектах:
                                            1) xhprof
                                            2) pinba
                                            3) мунин отрисовывает графики из пинбы
                                            4) nagios на критичные сервисы
                                            5) в php-fpm конечно используем режим бэктрейса медленных запросов и перегруз процесса при сегфолте

                                            Если просто установить пхп и ничего более — как в темноте идешь :-)
                                            –1
                                            Профилирование? New Relic? Не, никогда не слышал.
                                            Как вы боритесь с причинами впадания PCRE в рекурсию? Функциональное тестирование, 3-4 странных тяжелых вброса и вы бы увидели проблему. Не поможет? Интеграционное тестирование точно покажет проблемы в PCRE.
                                            Тестировать нужно, а не бороться с проблемами на боевом сервере, когда уже поздно. Непрерывная интеграция — наше все.
                                              +4
                                              Я так тоже раньше думал, что прочитав пару книжек Фаулера про непрерывную интеграцию надо все покрывать модульными тестами и ходить на работу программиста/админа без памперсов. Ошибался. Тесты все никогда не выявят, т.к. все покрыть тестами нереально — т.к. некоторые вещи не тестируются модульно :-)

                                              В этом облаке вероятностной надежности остается обливаться прохладным душем по утрам и носить памперс. С годами — привыкаешь. У вас будет CI, 100% покрытые юнитами, куча интеграционных тестов, а на бою чик и линус умрет по kernelpanic из-за дохлого драйвера — и клиенты вас утром изнасилуют в твиттере :-) Все нужно уметь — и тесты писать, и корки толковать на бою.
                                                –2
                                                Однако вы этого не упомянули. А зачастую можно избежать дебага просто прогнав get всех страниц сайта на IS.
                                                Хороший врач должен уметь увидеть болезнь до того как она перейдет в фатальную стадию. Патологоанатомы умеют «толковать корки», и людей они спасают, но post factum и уже других.
                                                100% покрытие кода тестами — фанатизм. Я вовсе не предлагают все-все-все тестировать. Однако профилирование — в крайней степени необходимая штука. Настройка профилирования — тривиальная задача, а результаты оно дает в первый же день после ввода в эксплуатацию.
                                                Я, наверное, уже написал свое последнее приложение в котором нет тестов и профилирования. Испытывают от этого чувство уверенности. Надеюсь патологоанатомом мне придется работать все меньше и меньше.
                                              +1
                                              Спасибо огромное за статью!
                                              Здоровья вам и плюсов в карму побольше :)
                                                +2
                                                Кстати, для популярных бинарных дистрибутивов вовсе не обязательно «просить админа», чтобы сделал дебаговскую сборку. Покуда там обычно либо уже есть пакеты с суффиксом -dbg (их создаёт мэйнтейнер), либо сборочная фабрика автоматом кладёт нужное на отдельный сервер. (например, ddebs.ubuntu.com в случае убунты).
                                                  +1
                                                  Да, да. Спасибо что добавили про это.
                                                  0
                                                  SIGSEGV можно перехватить. Нельзя перехватить только SIGKILL и SIGSTOP.
                                                  Но лисята милые :)
                                                    0
                                                    Спасибо, поправил. Забыл :-)
                                                    +2
                                                    Для удобства сбора крэшей от других программ можно указать ядру где именно создавать дампы памяти, чтобы не рыскать по файловой системе в их поиске.
                                                    Например, указать в sysctl.conf:
                                                    kernel.core_pattern = /tmp/core/core-%e-%s-%u-%g-%p-%t
                                                      0
                                                      сделайте правильные тэги к посту!
                                                        0
                                                        сделал
                                                          0
                                                          Какой-то опять фейл… Зачем точка на конце «веб-разработки»? И куда пропал собственно PHP? Также наверное не помешло бы упоминание coredump и gdb.
                                                      0
                                                      во внутренности op_array не обязательно лезть чтобы получить PHP-шный бэктрэйс.
                                                      достаточно положить себе в $HOME файл .gdbinit из дистрибутива PHP и в GDB после этого появится команда dump_bt.
                                                      Выполнять так:
                                                      (gdb) dump_bt executor_globals.current_execute_data
                                                      [0xf5625a20] strlen() /home/local/dev/php/5_3/run-tests.php:1067
                                                      [0xf561b3a8] system_with_timeout() /home/local/dev/php/5_3/run-tests.php:1651
                                                      [0xf561ad18] run_test() /home/local/dev/php/5_3/run-tests.php:1103
                                                      [0xf5616080] run_all_tests() /home/local/dev/php/5_3/run-tests.php:909

                                                      другое дело, что иногда он и является прямым ответом на вопрос «что случилосб», а иногда даже его наличие никак не помогает.

                                                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                      Самое читаемое