debug_backtrace () из зарегистрированной функции выключения в PHP - PullRequest
22 голосов
/ 30 августа 2011

Пока я отвечал на этот вопрос , я обнаружил, что debug_backtrace() не выходит за пределы функции, зарегистрированной для register_shutdown_function(), при вызове из нее.

Это было упомянуто в этом комментарии для register_shutdown_function() в документах PHP, заявив:

Может возникнуть идея вызвать debug_backtrace или debug_print_backtrace из функции завершения работы, чтобы отследить, где произошла фатальная ошибка. К сожалению, эти функции не будут работать внутри функции отключения.

Объяснил немного подробнее, комментарии к этот ответ состояние:

не работает. Функция выключения происходит после того, как стек был размотан. Нет стековой информации для дампа.

Есть ли способ обойти это, заставляя PHP хранить трассировку стека, пока процесс не завершится полностью, или мы должны принять это как данность из-за внутренних функций PHP?

Ответы [ 5 ]

15 голосов
/ 30 августа 2011

Это очень дорогое решение.Я никогда не использовал register_tick_function() или tick, и я не уверен, работает ли он должным образом.

declare(ticks=1);

function tick_handler() {
    global $backtrace;
    $backtrace = debug_backtrace();
}
register_tick_function('tick_handler');



function shutdown() {
    global $backtrace;
    // do check if $backtrace contains a fatal error...
    var_dump($backtrace);
}
register_shutdown_function('shutdown');
9 голосов
/ 30 августа 2011

Есть ли способ обойти это, заставляя PHP хранить трассировку стека

Это довольно бессмысленно, когда вызывается зарегистрированная функция, все ваши определенные функции возвращены или очищенывниз из стека.

Если вам нужно знать, где находится ваш код, то вам нужно его кодировать.

4 голосов
/ 13 октября 2014

В XDebug добавлена ​​функция xdebug_get_function_stack().

Этот работает аналогично внутреннему PHP debug_backtrace(), но сохраняет трассировку даже в обработчике завершения работы.

Вы не получите точную точку выхода, только последняя выполненная функция перед завершением работы (вызвано вызовом или ошибкой die() / exit()).

Это, конечно, подходит только для среды разработки.

4 голосов
/ 30 августа 2011

По моему опыту, функция выключения запускается с чистого стека, и у него нет доступа к «оригинальному» стеку (так как он больше не существует).

К сожалению, нет никакого способачтобы сохранить этот оригинальный стек.

0 голосов
/ 21 января 2019

Внутри вашей зарегистрированной функции выключения вы можете получить обратную трассировку с помощью функции error_get_last .У меня работает в PHP7.

...