简体   繁体   English

从PHP外部打印PHP正在运行的调用堆栈

[英]Print PHP running call stack from outside the PHP

Is there any runtime stack trace feature in PHP, by a given PID of it? 通过给定的PID,PHP中是否有任何运行时堆栈跟踪功能? (For whom also write Java, I mean jstack.) (对于谁也写Java,我的意思是jstack。)

I got few PHP background process that they are freeze once a while on some unknown lines. 我没有几个PHP后台进程,它们在某些未知行上偶尔冻结一次。 I can simply kill them all and restart but that don't prevent it happen again. 我可以简单地杀死它们并重新启动,但这不能阻止它再次发生。

Is there a API able to spy the stack and tell? 是否有一个API可以监视堆栈并判断? like the jstack utility provided from JDK? 像JDK提供的jstack实用程序一样?

You have a few options in terms of debugging unknown errors. 在调试未知错误方面,您有一些选择。

  • The first method is easy, but requires a PHP extension to be installed. 第一种方法很简单,但是需要安装PHP扩展。
  • The second method offers a more difficult hands-on approach, but is definitely worth it if you're into the low-level inner-workings of the PHP interpreter. 第二种方法提供了更困难的动手方法,但是如果您不熟悉PHP解释器的底层内部工作,那么绝对值得。 Also, this will require linux and PHP to be configured with --enable-debug . 另外,这将要求Linux和PHP使用--enable-debug进行配置。
  • The third and, in my personal opinion the easiest, method doesn't require the use of any external programs or added PHP extensions. 我个人认为,第三个方法也是最简单的方法,不需要使用任何外部程序或添加的PHP扩展。

  1. Xdebug Xdebug的

    • This is a PHP extension you can install and have available for any site/page. 这是您可以安装的PHP扩展,可用于任何站点/页面。
    • A quick-list of features from the website: 网站功能的快速列表:
      • Automatic stack trace upon error 错误时自动跟踪堆栈
      • Function call logging 函数调用记录
      • Display features such as enhanced var_dump() output and code coverage information. 显示功能,例如增强的var_dump()输出和代码覆盖率信息。
    • If you see yourself needing to debug your scripts a lot, this one might be the best option. 如果您发现自己需要大量调试脚本,那么此脚本可能是最佳选择。 The prettier-display of errors is also a good thumbs-up in my book. 在我的书中,更漂亮地显示错误也很好。

  2. Use gdb to run the file that crashes and analyze the backtrace. 使用gdb运行崩溃的文件并分析回溯。

    • This is an intermediate-to-advanced approach that requires PHP to be configured with --enable-debug , a linux machine running Apache , and a strong desire/ability to understand the way software works on a lower-level. 这是一种中级到高级的方法,要求PHP配置--enable-debug (运行Apache的linux机器),并且强烈希望/能够理解PHP在较低级别上的工作方式。
    • Run gdb with Apache : 使用Apache运行gdb
      gdb /usr/lib/httpd
    • Then, you have two options.: 然后,您有两个选择:
      • Run apache as a server and load the file through a browser, as normal: 正常运行apache作为服务器并通过浏览器加载文件:
        (gdb) run -X
        ... now, in your browser - access the page that crashes as normal and switch back to gdb : (gdb) backtrace ...现在,在您的浏览器中-正常访问崩溃的页面,然后切换回gdb(gdb) backtrace
        ... the full backtrace will be printed ...将打印完整的回溯
      • Or, use gdb to run the script itself: 或者,使用gdb来运行脚本本身:
        (gdb) run /path/to/the/script.php
        (gdb) backtrace
        ... the full backtrace will be printed ...将打印完整的回溯
    • For more gdb info, check out the quick-reference guide . 有关更多gdb信息,请查看快速参考指南

  3. Create a custom error handler that prints the stack trace when an error is thrown. 创建一个自定义错误处理程序 ,该处理程序在引发错误时将打印堆栈跟踪。

    • To be sure to catch all errors, you can catch Errors, Exceptions, and PHP's Shutdown events. 为了确保捕获所有错误,您可以捕获Errors,Exceptions和PHP的Shutdown事件。
    • To debug a single page, it's as simple as creating a function to handle the error and then pasting that function into the top of the page you're having issues on. 要调试单个页面,就像创建一个处理错误的函数然后将其粘贴到遇到问题的页面顶部一样简单。 One step further, I have an "error handling" class that's in a separate file and just include it whenever needed (simplified-version below). 更进一步,我有一个“错误处理”类,该类位于单独的文件中,并在需要时就将其包括在内(以下为简化版本)。 You can tweak each method to suit your display needs, or even handle errors on a per-error-number basis! 您可以调整每种方法以适合您的显示需求,甚至可以按每个错误号处理错误!
    • Then, to use this, just add require('ErrorHandler.php'); 然后,要使用此功能,只需添加require('ErrorHandler.php'); to the top of your page and it should auto-register itself to handle any errors. 到页面顶部,它应该自动注册以处理任何错误。 Be sure to update the include-path to point to the actual file, of course. 当然,请确保将包含路径更新为指向实际文件。

ErrorHandler.php: ErrorHandler.php:

<?php
class ErrorHandler {
    public static function captureError($err_no, $message, $file, $line) {
        echo '<strong>Error (#' . $err_no . '):</strong> ' . $message . ' in ' . $file . ' on line #' . $line . '<br />';
        debug_print_backtrace();
    }

    public static function captureException($exception) {
        echo '<pre>' . print_r($exception, true) . '</pre>';
    }

    public static function captureShutdown() {
        if (($error = error_get_last()) !== null) {
            debug_print_backtrace();
        }
    }
}
set_error_handler(array('ErrorHandler', 'captureError'));
set_exception_handler(array('ErrorHandler', 'captureException'));
register_shutdown_function(array('ErrorHandler', 'captureShutdown'));
?>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM