使用 PHP 和 DTrace

PHP 可以使用 DTrace 静态探针配置,适用于支持 DTrace 动态跟踪的平台。

配置 PHP 以使用 DTrace 静态探针

请参考外部平台特定文档以了解如何启用操作系统 DTrace 支持。例如,在 Oracle Linux 上,启动一个 UEK3 内核并执行以下操作

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

您可以使用 ACL 包规则来限制特定用户的设备访问权限,而不是使用 chmod

使用 --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

Provider 列值包含 php 和当前正在运行的 PHP 进程的进程 ID。

如果 Apache Web 服务器正在运行,模块名称可能是 libphp5.so,并且会有多个列表块,每个正在运行的 Apache 进程一个。

Function 列指的是 PHP 内部 C 实现函数名称,每个提供者都位于其中。

如果 PHP 进程未运行,则不会显示任何 PHP 探针。

PHP 示例中的 DTrace

此示例演示了 DTrace D 脚本语言的基础知识。

示例 #1 all_probes.d 用于使用 DTrace 跟踪所有 PHP 静态探针

#!/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