Usar bpftrace con las sondas estáticas DTrace de PHP
PHP Manual
PHP Manual»Rastreo dinámico de DTrace»Usar bpftrace con las sondas estáticas DTrace de PHP

En las distribuciones Linux con un núcleo que soporta eBPF, la utilidad bpftrace puede conectarse directamente a las sondas USDT de DTrace de PHP, sin necesidad de SystemTap.

Instalar bpftrace

Instale bpftrace utilizando el gestor de paquetes de la distribución. Por ejemplo, en Oracle Linux, RHEL o Fedora:

# dnf install bpftrace
O bien, en Debian o Ubuntu:
# apt install bpftrace

Los ejemplos siguientes asumen que el binario PHP objetivo está instalado en /usr/bin/php.

Las mismas sondas USDT también son expuestas por otros SAPIs construidos a partir del mismo árbol de fuentes, por lo que el objetivo de la sonda puede ser en su lugar el módulo de Apache (libphp.so) o el binario del FastCGI Process Manager (php-fpm); sustituya la ruta apropiada o conéctese por PID con -p según sea necesario.

Asegúrese de que el binario objetivo esté construido con DTrace y de que la variable de entorno esté configurada correctamente. Consulte Configurar PHP para las sondas estáticas de DTrace para más detalles.

Las sondas estáticas en PHP pueden ser listadas utilizando bpftrace:

# bpftrace -l 'usdt:/usr/bin/php:php:*'

Esto produce:

usdt:/usr/bin/php:php:compile__file__entry
usdt:/usr/bin/php:php:compile__file__return
usdt:/usr/bin/php:php:error
usdt:/usr/bin/php:php:exception__caught
usdt:/usr/bin/php:php:exception__thrown
usdt:/usr/bin/php:php:execute__entry
usdt:/usr/bin/php:php:execute__return
usdt:/usr/bin/php:php:function__entry
usdt:/usr/bin/php:php:function__return
usdt:/usr/bin/php:php:request__shutdown
usdt:/usr/bin/php:php:request__startup

Ejemplo #1 all_probes.bt para trazar todas las sondas estáticas PHP con bpftrace

#!/usr/bin/env bpftrace

usdt:/usr/bin/php:php:compile__file__entry
{
    printf("Probe compile__file__entry\n");
    printf("  compile_file %s\n", str(arg0));
    printf("  compile_file_translated %s\n", str(arg1));
}
usdt:/usr/bin/php:php:compile__file__return
{
    printf("Probe compile__file__return\n");
    printf("  compile_file %s\n", str(arg0));
    printf("  compile_file_translated %s\n", str(arg1));
}
usdt:/usr/bin/php:php:error
{
    printf("Probe error\n");
    printf("  errormsg %s\n", str(arg0));
    printf("  request_file %s\n", str(arg1));
    printf("  lineno %d\n", (int32)arg2);
}
usdt:/usr/bin/php:php:exception__caught
{
    printf("Probe exception__caught\n");
    printf("  classname %s\n", str(arg0));
}
usdt:/usr/bin/php:php:exception__thrown
{
    printf("Probe exception__thrown\n");
    printf("  classname %s\n", str(arg0));
}
usdt:/usr/bin/php:php:execute__entry
{
    printf("Probe execute__entry\n");
    printf("  request_file %s\n", str(arg0));
    printf("  lineno %d\n", (int32)arg1);
}
usdt:/usr/bin/php:php:execute__return
{
    printf("Probe execute__return\n");
    printf("  request_file %s\n", str(arg0));
    printf("  lineno %d\n", (int32)arg1);
}
usdt:/usr/bin/php:php:function__entry
{
    printf("Probe function__entry\n");
    printf("  function_name %s\n", str(arg0));
    printf("  request_file %s\n", str(arg1));
    printf("  lineno %d\n", (int32)arg2);
    printf("  classname %s\n", str(arg3));
    printf("  scope %s\n", str(arg4));
}
usdt:/usr/bin/php:php:function__return
{
    printf("Probe function__return\n");
    printf("  function_name %s\n", str(arg0));
    printf("  request_file %s\n", str(arg1));
    printf("  lineno %d\n", (int32)arg2);
    printf("  classname %s\n", str(arg3));
    printf("  scope %s\n", str(arg4));
}
usdt:/usr/bin/php:php:request__shutdown
{
    printf("Probe request__shutdown\n");
    printf("  file %s\n", str(arg0));
    printf("  request_uri %s\n", str(arg1));
    printf("  request_method %s\n", str(arg2));
}
usdt:/usr/bin/php:php:request__startup
{
    printf("Probe request__startup\n");
    printf("  file %s\n", str(arg0));
    printf("  request_uri %s\n", str(arg1));
    printf("  request_method %s\n", str(arg2));
}

El script anterior trazará todos los puntos de sondeo estáticos del núcleo de PHP durante toda la duración de la ejecución de un script PHP. bpftrace requiere privilegios de root:

# USE_ZEND_DTRACE=1 bpftrace -c '/usr/bin/php test.php' all_probes.bt

Para trazar un proceso PHP que ya está en ejecución (por ejemplo, un worker de php-fpm o un proceso Apache que carga libphp.so), conéctese por PID:

# bpftrace -p $PID all_probes.bt
La ruta del objetivo usdt: en el script debe coincidir con el binario del proceso en ejecución; ajuste usdt:/usr/bin/php al binario de php-fpm o a libphp.so según corresponda.

To Top