Utiliser PHP et DTrace

PHP peut être configuré avec les sondes statiques DTrace sur les plateformes qui supportent le traçage dynamique DTrace.

Configurer PHP pour les sondes statiques de DTrace

Référez-vous à la documentation spécifique de la plateforme externe pour activer le support de DTrace du système d'exploitation DTrace. Par exemple, sur Oracle Linux démarrez un noyau UEK3 et faites :

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

Au lieu d'utiliser chmod, vous pouvez utiliser une règle de paquetage ACL pour limiter l'accès au périphérique à un utilisateur spécifique.

Construire PHP avec le paramètre de configuration --enable-dtrace:

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

Cela permet d'activer les sondes statiques dans le cœur de PHP. Toutes les extensions PHP qui fournissent leurs propres sondes doivent être construites séparément en tant qu'extensions partagées.

Sondes statiques DTrace dans le cœur de PHP

Les sondes statiques suivantes sont disponibles dans PHP
Nom de la sondeDescription de la sondeArguments de la sonde
request-startupSe déclenche lorsqu'une requête démarre.char *file, char *request_uri, char *request_method
request-shutdownSe déclenche lorsqu'une requête s'arrête.char *file, char *request_uri, char *request_method
compile-file-entrySe déclenche lorsque la compilation d'un script commence.char *compile_file, char *compile_file_translated
compile-file-returnSe déclenche lorsque la compilation d'un script se termine.char *compile_file, char *compile_file_translated
execute-entrySe déclenche lorsqu'un tableau d'opcodes doit être exécuté. Par exemple, il se déclenche lors d'appels de fonction, d'inclusions et de reprises de générateur.char *request_file, int lineno
execute-returnSe déclenche après l'exécution d'un tableau d'opcodes.char *request_file, int lineno
function-entrySe déclenche lorsque le moteur de PHP entre dans une fonction PHP ou un appel de méthode.char *function_name, char *request_file, int lineno, char *classname, char *scope
function-returnSe déclenche lorsque le moteur PHP revient d'une fonction PHP ou d'un appel de méthode.char *function_name, char *request_file, int lineno, char *classname, char *scope
exception-thrownSe déclenche lorsqu'une exception est émise.char *classname
exception-caughtSe déclenche lorsqu'une exception est attrapée.char *classname
errorSe déclenche lorsqu'une erreur survient, quel que soit le niveau de error_reporting.char *errormsg, char *request_file, int lineno

Les extensions PHP peuvent également disposer de sondes statiques supplémentaires.

Liste des sondes statiques DTrace de PHP

Pour lister les sondes disponibles, démarrez un processus PHP puis exécutez :

 # dtrace -l 

Le résultat sera similaire à celui qui suit :

 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 

Les valeurs de la colonne Provider sont php et l'identifiant du processus PHP en cours d'exécution.

Si le serveur web Apache est en cours d'exécution, le nom du module peut être, par exemple, libphp5.so, et il y aurait plusieurs blocs de listes, un par processus Apache en cours d'exécution.

La colonne Fonction fait référence à l'implémentation interne en C de PHP, où chaque fournisseur est situé.

Si un processus PHP n'est pas en cours d'exécution, aucune sonde PHP ne sera affichée.

DTrace avec un exemple PHP

Cet exemple montre les bases du langage de script DTrace D.

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

Ce script utilise l'option -Z de dtrace, ce qui lui permet d'être exécuté lorsqu'il n'y aucun processus PHP en cours d'execution. Si cette option était omise, le script se terminerait immédiatement parce qu'il sait qu'aucune des sondes à surveiller n'existe.

Le script trace tous les points de sonde statiques de PHP pendant la durée d'un script PHP en cours d'exécution. Exécutez le script D :

 # ./all_probes.d 

Exécutez un script ou une application PHP. Le script D de surveillance affichera les arguments de chaque sonde au fur et à mesure qu'elle se déclenche.

Lorsque la surveillance est terminée, le script D peut être interrompu par une commande CTRL+C

Sur les machines multi-CPU, l'ordre des sondes peut ne pas être séquentiel. Cela dépend du CPU qui a traité les sondes, et de la façon dont les threads migrent d'un CPU à l'autre. L'affichage des horodatages des sondes permet de réduire la confusion, par exemple :

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