来自PHP中已注册的关闭函数的debug_backtrace()

Dan*_*ugg 23 php stack-trace debug-backtrace shutdown-hook

在修补这个问题的答案的同时,我发现当从内部调用时,debug_backtrace()不会超出注册的函数register_shutdown_function().

这是中提到此评论为register_shutdown_function()在PHP文档,指出:

您可以从关闭函数内部调用debug_backtrace或debug_print_backtrace,以跟踪致命错误发生的位置.不幸的是,这些功能在关机功能中不起作用.

更详细地解释一下,对这个答案状态的评论:

不行.堆栈取消后会发生关闭功能.没有要转储的堆栈信息.

有没有办法绕过这个,迫使PHP保持堆栈跟踪直到进程完全终止,或者我们应该接受它作为给定由于PHP内部?

pow*_*tac 15

这是一个非常昂贵的解决方案.我从未使用过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');
Run Code Online (Sandbox Code Playgroud)

  • 谢谢@powtac - 很棒的解决方案,但它不起作用.我当然知道你要去哪里.我愚弄了一下,但还没有成功. (2认同)
  • 正在搜索相同的内容并找到了这个 - https://gist.github.com/rmbl/5780995。不过没试。注意`declare(ticks=1);`在最后 (2认同)

sym*_*ean 9

有没有办法绕过这个,迫使PHP保持堆栈跟踪

这是无意义的,当调用注册函数时,所有已定义的函数都已从堆栈中返回或清除.

如果您需要知道代码退出的位置,那么您需要检测代码.

  • 谢谢@symcbean - 鉴于给定执行中的所有其他函数都已返回,当然,我们已经回到了全局范围; 但是,从堆栈中清除不完整函数调用的部分(*给出`exit`在嵌套调用*的某个任意深度调用)是我发现的不幸,而不是没有意义的.我从不使用`exit`来执行控制,喜欢异常来处理我的错误逻辑; 这更多的是学术探究,而不是现实世界.尽管如此,我认为应该保留堆栈直到完全杀死进程. (3认同)

Pis*_*3.0 5

根据我的经验,关闭函数从一个干净的堆栈开始,它无法访问“原始”堆栈(因为那时它不再存在)。

不幸的是,没有办法保存原始堆栈。


ouj*_*sky 5

在XDebug扩展中,有一个xdebug_get_function_stack()函数。

这与 PHP 的 internal 类似debug_backtrace(),但即使在关闭处理程序中也能保持跟踪。

但是,您不会获得确切的退出点,只有在关闭发生之前最后执行的函数(由die()/exit()调用或错误触发)。

这当然只适用于开发环境。