## Usar PHP y DTrace

PHP puede ser configurado con las sondas estáticas DTrace en las plataformas que soportan el rastreo dinámico DTrace.

### Configurar PHP para las sondas estáticas de DTrace

Consulte la documentación específica de la plataforma externa para habilitar el soporte de DTrace del sistema operativo. Por ejemplo, en Oracle Linux inicie un núcleo UEK3 y haga:

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

En lugar de usar `chmod`, puede usar una regla de paquetado ACL para limitar el acceso al dispositivo a un usuario específico.

Construir PHP con el parámetro de configuración `--enable-dtrace`:

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

Esto hace que las sondas estáticas estén disponibles en el núcleo de PHP. Todas las extensiones PHP que proporcionen sus propias sondas deben ser construidas por separado como extensiones compartidas.

Para habilitar las sondas, definir la variable de entorno USE_ZEND_DTRACE=1 a los procesos PHP objetivo.

### Sondas estáticas DTrace en el núcleo de PHP

Las siguientes sondas estáticas están disponibles en PHP
Nombre de la sonda | Descripción de la sonda | Argumentos de la sonda
--- | --- | ---
`request-startup` | Se dispara cuando una petición comienza. | char *file, char *request_uri, char *request_method
`request-shutdown` | Se dispara cuando una petición se detiene. | char *file, char *request_uri, char *request_method
`compile-file-entry` | Se dispara cuando comienza la compilación de un script. | char *compile_file, char *compile_file_translated
`compile-file-return` | Se dispara cuando termina la compilación de un script. | char *compile_file, char *compile_file_translated
`execute-entry` | Se dispara cuando un array de opcodes debe ser ejecutado. Por ejemplo, se dispara en llamadas de función, inclusiones y reanudaciones de generador. | char *request_file, int lineno
`execute-return` | Se dispara después de la ejecución de un array de opcodes. | char *request_file, int lineno
`function-entry` | Se dispara cuando el motor de PHP entra en una función PHP o una llamada de método. | char *function_name, char *request_file, int lineno, char *classname, char *scope
`function-return` | Se dispara cuando el motor PHP regresa de una función PHP o una llamada de método. | char *function_name, char *request_file, int lineno, char *classname, char *scope
`exception-thrown` | Se dispara cuando se lanza una excepción. | char *classname
`exception-caught` | Se dispara cuando se captura una excepción. | char *classname
`error` | Se dispara cuando ocurre un error, independientemente del nivel de error_reporting. | char *errormsg, char *request_file, int lineno

Las extensiones PHP también pueden disponer de sondas estáticas adicionales.

### Lista de sondas estáticas DTrace de PHP

Para listar las sondas disponibles, inicie un proceso PHP y luego ejecute:

    # dtrace -l

El resultado será similar al siguiente:

       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

Los valores de la columna Provider son `php` y el identificador del proceso PHP en ejecución.

Si el servidor web Apache está en ejecución, el nombre del módulo podría ser, por ejemplo, libphp5.so, y habría varios bloques de listas, uno por cada proceso Apache en ejecución.

La columna Función hace referencia a la implementación interna en C de PHP, donde se encuentra cada proveedor.

Si no hay un proceso PHP en ejecución, no se mostrará ninguna sonda PHP.

### DTrace con un ejemplo PHP

Este ejemplo muestra los fundamentos del lenguaje de script DTrace D.

Ejemplo #1 all_probes.d para trazar todas las sondas estáticas PHP con DTrace

    #!/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));
    }

Este script utiliza la opción `-Z` de dtrace, lo que le permite ejecutarse cuando no hay ningún proceso PHP en ejecución. Si se omitiera esta opción, el script terminaría inmediatamente porque sabe que ninguna de las sondas a monitorear existe.

El script traza todos los puntos de sondeo estáticos de PHP durante la duración de un script PHP en ejecución. Ejecute el script D:

    # ./all_probes.d

Ejecute un script o una aplicación PHP. El script D de monitoreo mostrará los argumentos de cada sonda a medida que se dispare.

Cuando el monitoreo haya terminado, el script D puede ser interrumpido con un ``CTRL`+`C``

En máquinas multi-CPU, el orden de las sondas puede no ser secuencial. Esto depende del CPU que ha procesado las sondas, y de cómo los hilos migran de un CPU a otro. La visualización de los timestamps de las sondas permite reducir la confusión, por ejemplo :

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

### Ver también

- OCI8 y el rastreo dinámico DTrace

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open