PHP 8.4.22 Released!

Utilisation de bpftrace avec les sondes statiques DTrace de PHP

Sur les distributions Linux dont le noyau supporte eBPF, l'utilitaire bpftrace peut s'attacher directement aux sondes USDT DTrace de PHP, sans nécessiter SystemTap.

Installation de bpftrace

Il faut installer bpftrace avec le gestionnaire de paquets de la distribution. Par exemple, sur Oracle Linux, RHEL ou Fedora :

# dnf install bpftrace
Ou, sur Debian ou Ubuntu :
# apt install bpftrace

Les exemples ci-dessous supposent que le binaire PHP cible est installé dans /usr/bin/php.

Les mêmes sondes USDT sont également exposées par les autres SAPI compilées à partir du même arbre de sources, donc la cible de la sonde peut aussi être le module Apache (libphp.so) ou le binaire du gestionnaire de processus FastCGI (php-fpm) ; il faut substituer le chemin approprié ou s'attacher par PID avec -p si nécessaire.

Il faut s'assurer que le binaire cible est compilé avec DTrace et que l'environnement est correctement configuré. Voir Configurer PHP pour les sondes statiques DTrace pour les détails.

Les sondes statiques de PHP peuvent être listées en utilisant bpftrace :

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

Ce qui affiche :

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

Exemple #1 all_probes.bt pour tracer toutes les sondes statiques de PHP avec 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));
}

Le script ci-dessus tracera tous les points de sonde statiques du cœur de PHP pendant toute la durée d'exécution d'un script PHP. bpftrace nécessite les privilèges root :

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

Pour tracer un processus PHP déjà en cours d'exécution (par exemple, un worker php-fpm ou un processus Apache chargeant libphp.so), il faut s'attacher par PID :

# bpftrace -p $PID all_probes.bt
Le chemin cible usdt: dans le script doit correspondre au binaire du processus en cours ; il faut ajuster usdt:/usr/bin/php au binaire php-fpm ou à libphp.so selon le cas.

add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top