2024 年 PHP Conference Japan

使用 PHP 和 DTrace

在支援 DTrace 動態追蹤的平台上,可以將 PHP 設定為使用 DTrace 靜態探針。

設定 PHP 以使用 DTrace 靜態探針

請參閱外部平台的特定文件以啟用作業系統的 DTrace 支援。例如,在 Oracle Linux 上啟動 UEK3 核心並執行

# modprobe fasttrap
# chmod 666 /dev/dtrace/helper

与其使用 chmod,您可以改用 ACL 套件規則來限制特定使用者存取裝置。

使用 --enable-dtrace 設定參數建置 PHP

# ./configure --enable-dtrace ...
# make
# make install

這會啟用核心 PHP 中的靜態探測點。任何提供自身探測點的 PHP 擴充功能都應作為共享擴充功能單獨建置。

核心 PHP 中的 DTrace 靜態探測點

以下靜態探測點可在 PHP 中使用
探測點名稱 探測點說明 探測點引數
request-startup 在請求啟動時觸發。 char *file, char *request_uri, char *request_method
request-shutdown 在請求關閉時觸發。 char *file, char *request_uri, char *request_method
compile-file-entry 在腳本編譯開始時觸發。 char *compile_file, char *compile_file_translated
compile-file-return 在腳本編譯完成時觸發。 char *compile_file, char *compile_file_translated
execute-entry 在要執行操作碼陣列時觸發。例如,它會在函式呼叫、引入和產生器恢復時觸發。 char *request_file, int lineno
execute-return 在執行操作碼陣列後觸發。 char *request_file, int lineno
function-entry 在 PHP 引擎進入 PHP 函式或方法呼叫時觸發。 char *function_name, char *request_file, int lineno, char *classname, char *scope
function-return 在 PHP 引擎從 PHP 函式或方法呼叫返回時觸發。 char *function_name, char *request_file, int lineno, char *classname, char *scope
exception-thrown 在拋出例外狀況時觸發。 char *classname
exception-caught 在攔截到例外狀況時觸發。 char *classname
error 在發生錯誤時觸發,無論 error_reporting 等級為何。 char *errormsg, char *request_file, int lineno

PHP 擴充功能也可能會有額外的靜態探測點。

列出 PHP 中的 DTrace 靜態探測點

要列出可用的探測點,請啟動 PHP 程序,然後執行

# dtrace -l

輸出結果類似於

   ID   PROVIDER            MODULE                          FUNCTION NAME
   [ . . . ]
    4   php15271               php               dtrace_compile_file compile-file-entry
    5   php15271               php               dtrace_compile_file compile-file-return
    6   php15271               php                        zend_error error
    7   php15271               php  ZEND_CATCH_SPEC_CONST_CV_HANDLER exception-caught
    8   php15271               php     zend_throw_exception_internal exception-thrown
    9   php15271               php                 dtrace_execute_ex execute-entry
   10   php15271               php           dtrace_execute_internal execute-entry
   11   php15271               php                 dtrace_execute_ex execute-return
   12   php15271               php           dtrace_execute_internal execute-return
   13   php15271               php                 dtrace_execute_ex function-entry
   14   php15271               php                 dtrace_execute_ex function-return
   15   php15271               php              php_request_shutdown request-shutdown
   16   php15271               php               php_request_startup request-startup

「提供者」欄位值包含 php 和目前正在執行的 PHP 程序的程序 ID。

如果 Apache 網頁伺服器正在執行,模組名稱可能是例如 libphp5.so,並且會有多個區塊的清單,每個正在執行的 Apache 程序一個。

「函式」欄位指的是 PHP 的內部 C 實作函式名稱,其中每個提供者所在的位置。

如果 PHP 程序未執行,則不會顯示任何 PHP 探測點。

使用 PHP 的 DTrace 範例

此範例顯示 DTrace D 腳本語言的基礎知識。

使用 DTrace 追蹤所有 PHP 靜態探測點的範例 #1 all_probes.d

#!/usr/sbin/dtrace -Zs

#pragma D option quiet

php*:::compile-file-entry
{
    printf("PHP compile-file-entry\n");
    printf("  compile_file              %s\n", copyinstr(arg0));
    printf("  compile_file_translated   %s\n", copyinstr(arg1));
}

php*:::compile-file-return
{
    printf("PHP compile-file-return\n");
    printf("  compile_file              %s\n", copyinstr(arg0));
    printf("  compile_file_translated   %s\n", copyinstr(arg1));
}

php*:::error
{
    printf("PHP error\n");
    printf("  errormsg                  %s\n", copyinstr(arg0));
    printf("  request_file              %s\n", copyinstr(arg1));
    printf("  lineno                    %d\n", (int)arg2);
}

php*:::exception-caught
{
    printf("PHP exception-caught\n");
    printf("  classname                 %s\n", copyinstr(arg0));
}

php*:::exception-thrown
{
    printf("PHP exception-thrown\n");
    printf("  classname                 %s\n", copyinstr(arg0));
}

php*:::execute-entry
{
    printf("PHP execute-entry\n");
    printf("  request_file              %s\n", copyinstr(arg0));
    printf("  lineno                    %d\n", (int)arg1);
}

php*:::execute-return
{
    printf("PHP execute-return\n");
    printf("  request_file              %s\n", copyinstr(arg0));
    printf("  lineno                    %d\n", (int)arg1);
}

php*:::function-entry
{
    printf("PHP function-entry\n");
    printf("  function_name             %s\n", copyinstr(arg0));
    printf("  request_file              %s\n", copyinstr(arg1));
    printf("  lineno                    %d\n", (int)arg2);
    printf("  classname                 %s\n", copyinstr(arg3));
    printf("  scope                     %s\n", copyinstr(arg4));
}

php*:::function-return
{
    printf("PHP function-return\n");
    printf("  function_name             %s\n", copyinstr(arg0));
    printf("  request_file              %s\n", copyinstr(arg1));
    printf("  lineno                    %d\n", (int)arg2);
    printf("  classname                 %s\n", copyinstr(arg3));
    printf("  scope                     %s\n", copyinstr(arg4));
}

php*:::request-shutdown
{
    printf("PHP request-shutdown\n");
    printf("  file                      %s\n", copyinstr(arg0));
    printf("  request_uri               %s\n", copyinstr(arg1));
    printf("  request_method            %s\n", copyinstr(arg2));
}

php*:::request-startup
{
    printf("PHP request-startup\n");
    printf("  file                      %s\n", copyinstr(arg0));
    printf("  request_uri               %s\n", copyinstr(arg1));
    printf("  request_method            %s\n", copyinstr(arg2));
}

此腳本使用 -Z 選項搭配 dtrace,允許在沒有 PHP 程序執行時執行。如果省略此選項,腳本將立即終止,因為它知道沒有要監控的探測點存在。

該腳本會在執行 PHP 腳本的整個過程中追蹤所有核心 PHP 靜態探測點。執行 D 腳本

# ./all_probes.d

執行 PHP 腳本或應用程式。監控 D 腳本將在每個探測點觸發時輸出其引數。

監控完成後,可以使用 CTRL+C 終止 D 腳本。

在多 CPU 的機器上,探針的順序可能看起來不是連續的。這取決於哪個 CPU 正在處理探針,以及執行緒如何在 CPU 之間遷移。顯示探針時間戳記將有助於減少混淆,例如

php*:::function-entry
{
      printf("%lld: PHP function-entry ", walltimestamp);
      [ . . .]
}

新增筆記

使用者提供的筆記

此頁面沒有使用者提供的筆記。
To Top