2011-12-01 61 views
2

PHP中是否有任何運行時堆棧跟蹤功能? (爲誰也寫Java,我的意思是jstack。)打印PHP在PHP外部運行調用堆棧

我有幾個PHP後臺進程,他們凍結了一段時間,在一些未知的行。我可以簡單地殺死它們並重新啓動,但不會阻止它再次發生。

是否有API能夠窺探堆棧並告訴?像JDK提供的jstack實用程序一樣?

回答

0

您在調試未知錯誤方面有幾個選項。

  • 第一種方法很簡單,但需要安裝PHP擴展。
  • 第二種方法提供了一種更加困難的動手方法,但如果您進入PHP解釋器的低級內部工作,這絕對是值得的。此外,這將需要Linux和PHP配置爲--enable-debug
  • 第三種,並且我個人認爲最簡單的方法不需要使用任何外部程序或添加的PHP擴展。

  1. Xdebug

    • 這是一個PHP擴展,你可以install並有可供任何網站/網頁。
    • 從網站功能的快速列表:在錯誤
      • 自動堆棧跟蹤
      • 功能呼叫記錄
      • 顯示功能,如增強的var_dump()輸出和代碼覆蓋信息。
    • 如果你看到自己需要調試你的腳本很多,這可能是最好的選擇。更漂亮的錯誤顯示在我的書中也是一個不錯的選擇。

  2. 使用gdb來運行崩潰的文件和分析回溯。

    • 這是與--enable-debug配置的中級到高級的方法,需要PHP,運行Apache一臺Linux機器,和強烈的願望/理解能力的軟件工作在一個較低級的方式。
    • 運行gdbApache
      gdb /usr/lib/httpd
    • 然後,你有兩個選擇:
      • 運行Apache作爲服務器,並通過瀏覽器加載該文件,爲正常:
        (gdb) run -X
        ...現在,在您的瀏覽器 - 訪問崩潰正常的頁面,然後切換回gdb(gdb) backtrace
        ......全回溯將被打印
      • 或者,使用gdb運行該腳本本身:
        (gdb) run /path/to/the/script.php
        (gdb) backtrace
        ......全回溯將被打印
    • 更多gdb信息,請查看quick-reference guide

  3. 創建custom error handler時拋出一個錯誤,打印堆棧跟蹤。

    • 就一定要趕所有錯誤,你可以捕捉錯誤,異常,和PHP的關機事件。
    • 要調試單個頁面,就像創建一個處理錯誤的函數一樣簡單,然後將該函數粘貼到您遇到問題的頁面頂部。更進一步,我有一個「錯誤處理」類,它在一個單獨的文件中,只要需要時包括它(下面的簡化版本)。您可以調整每種方法以適應您的顯示需求,甚至可以按錯誤編號處理錯誤!
    • 然後,要使用這個,只需將require('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')); 
?>