DTrace : un outil intéressant de Solaris 10
Un
journal un peu trollesque sur
LinuxFr a attiré mon attention sur Solaris 10 et en particulier sur l'outil
DTrace. L'auteur du journal compare ça à un bête
strace. En fait, en y regardant de plus près, ce n'est pas du tout ça, et les gens de chez Sun ont une nouvelle fois fait un truc vraiment intéressant.
En résumé, il s'agit d'un système d'instrumentation dynamique. Ce système permet d'avoir des informations sur ce qui se passe aussi bien au niveau des applications utilisateur que du noyau. Ce qui est assez fort c'est que pour récupérer ces informations, il n'est pas nécessaire de recompiler ou même de relancer les applications ou le système : l'instrumentation est entièrement dynamique. En gros, si on trace une fonction, alors en entrée et en sortie de fonction, DTrace va remplacer une instruction de la fonction par un appel au système de traçage qui va faire ce qu'il a à faire puis éxécuter l'instruction qui a été remplacée.
En plus de cette instrumentation dynamique des fonctions, DTrace propose aussi de l'instrumentation statique, le traçage des locks, des appels systèmes mais aussi le profiling.
Comme le traçage génère souvent beaucoup d'informations, DTrace permet à l'utilisateur de décrire les évènements qu'il souhaite matcher et de donner les actions à réaliser lorsqu'un évènement est matché. Un exemple tout bête, sorti du papier :
syscall::read:entry
{
self->t = timestamp;
}
En gros, lorsque l'appel système
read va être appelé, le timestamp courant va être noté dans une variable locale au thread (tout ça est géré par DTrace). En sortie d'appel système, on pourra faire de même pour savoir combien de temps on a passé dans l'appel système
read. Sympathique quand même ?
Le langage en question est une sorte de C amélioré pour pouvoir faire plein de choses simplement comme l'aggrégation. Par exemple, il est possible de compter le nombre d'appels à un appel système donné, ou de compter le nombre d'appels système
write réalisés par une application en les classant par taille du buffer à écrire.... (Exemples issus également du papier).
Évidemment, tout ça est possible dans les applications utilisateur et dans le noyau, le passage de l'un à l'autre se faisant de manière complètement transparente. On peut donc avoir un graphe d'appel d'une fonction d'une application utilisateur qui va jusque dans le noyau, puis repasse dans l'espace utilisateur. (Voir le papier pour la démonstration).
Et enfin, il y a la spéculation. En gros, vous voulez récupérer des informations sur les appels à un appel système, mais seulement quand celui-ci foire (retourne -22 par exemple). Le problème c'est qu'au moment où l'on sait qu'il va retourner -22, l'appel système est terminé, et c'est trop tard pour sauvegarder des informations sur son déroulement. Par contre, si on sauvegarde le déroulement de tous les appels systèmes, on va avoir une énorme quantité de données. DTrace permet de sauvegarder les données dans un coin, puis une fois l'appel système terminé de décider si il faut ou non conserver les données de coté.
Bref, c'est vraiment intéressant tout ça. Le système est prévu pour être extensible et ne pas poser de problèmes de sécurité ou de corruption, de manière à ce qu'il soit utilisable dans un environnement de production.
Sources :