Nous avons vu ce qu’était un programme de type uProbe dans la première partie. Cela peut être ainsi un moyen de profiler un programme.
Le but de cet article est donc de regarder le temps que met une fonction d’un programme écrit en Rust à s’exécuter.
Cela permettra également de voir la différence avec un programme écrit en Go pour la récupération des points d’attache des programmes eBPF de type uProbe.
Je suppose que vous êtes déjà dans un environnement pour développer avec Aya et que vous avez installé bpftrace.
Si ce n’est pas le cas, vous pouvez utiliser le lab Killercoda :
Présentation du programme Rust pour tester les uProbes#
Calculer les décimales de 𝛑#
Avant de créer le programme eBPF, nous allons donc déjà récupérer un petit programme en Rust.
Pour que ça soit un peu plus inventif qu’un programme hello world, j’ai choisi un programme qui affiche une estimation du nombre 𝛑. En faisant varier le nombre de décimal, on peut facilement changer la durée d’exécution de la fonction.
Voici les commandes pour le récupérer et le compiler :
git clone https://github.com/littlejo/pi_digits_rust
cd pi_digits_rust
cargo build
Pour tester le binaire généré, on peut alors lancer la commande suivante :
./target/debug/pi_digits_pure_rust 10 #Pour avoir 10 décimales de Pi
Ce qui répond :
3.1415926536
On a bien 10 décimales.
Le but de cet article est de récupérer le temps que met la fonction dédiée au calcul des décimales de Pi (pi_times_10n_rounded()
).
Comment va-t-on procéder ?#
Pour cela nous allons utiliser :
- un programme de type uProbe pour mesurer le temps à l’arrivée de la fonction
- un programme de type uRetProbe pour mesurer le temps à la sortie de la fonction
Ainsi en soustrayant le temps d’entrée du temps de sortie, on va trouver la durée totale pour calculer les décimales de 𝛑.
Avant cela, il faut d’abord trouver le point d’attache pour ce programme écrit en Rust pour ces deux programmes eBPF.
Trouver le point d’attache#
Maintenant qu’on a créé et compilé le petit programme, il faut trouver comment déclencher le programme eBPF de type uProbe ou uRetProbe. Lorsqu’on utilise cargo generate
pour le repo aya, il faut répondre à deux questions : où se trouve le nom du binaire et quelle fonction observée. Voyons cela en détail.
Nom du binaire#
🤷 Target to attach the (u|uret)probe? (e.g libc):
Pour garantir la portabilité du programme eBPF, il faut répondre le chemin absolu du binaire. Par exemple je l’ai créé là : /home/cloud_user/pi_digits/target/debug/pi_digits_pure_rust
.
./pi_digits_pure_rust
)Nom de la fonction#
🤷 Function name to attach the (u|uret)probe? (e.g getaddrinfo):
Que faut-il répondre ?
On l’a déjà vu : on peut utiliser la commande bpftrace, par exemple :
bpftrace -l \
'uprobe:./pi_digits_pure_rust:*pi_times*'
On trouve alors :
uprobe:./pi_digits_pure_rust:pi_times_10n_rounded
La fonction est donc bien pi_times_10n_rounded
.
Astuces#
Si vous êtes attentifs, dans la deuxième partie, on avait vu que, par défaut, le compilateur Go :
- inlinait les fonctions et donc on ne pouvait pas les voir
- On a dû rajouter l’option de compilation
-l
pour empêcher cela
- On a dû rajouter l’option de compilation
- modifiait le nom de la fonction (
mangle
)- On a dû rajouter l’option de compilation
-N
pour empêcher cela
- On a dû rajouter l’option de compilation
Rappelons ce qu’est un inline (ici avec le compilateur Go) via un schéma :
Rust fait également cela par défaut. Mais ce n’est pas au niveau global que je l’ai fait mais pour la fonction en particulier.
J’ai ainsi dû rajouter deux attributs dans le code devant la fonction cible :
#[no_mangle]
#[inline(never)]
pub fn pi_times_10n_rounded(n: usize) -> num_bigint::BigInt {
//[...]
}
#[no_mangle]
: ne pas modifier le nom de la fonction#[inline(never)]
: ne jamais inliner la fonction
Maintenant qu’on a défini le point d’attache. Nous allons pouvoir commencer à créer nos deux programmes eBPF.
Récupérons le temps de lancement des programmes eBPF#
Commençons simple en créant les deux programmes eBPF et en récupérant juste leur temps de lancement.
Suite de l’article réservée aux membres premium ✨
L’article complet est accessible uniquement aux membres premium.
Devenir membre premium, c’est simple : il suffit de faire un petit don 💖
En échange, vous aurez pendant 1 an (offre early bird) :
- Accès à tous les articles complets dès leur publication
- Lecture anticipée avant la mise en ligne publique
- Participation au soutien de ce blog indépendant
- Accès exclusif à mes photos de vacances à Dubaï
Votre don permet de :
- Me rendre moins dépendant des grandes plateformes
- M’encourager à créer plus de contenu technique
- Lever le paywall plus rapidement pour tous