 Mesdames et Messieurs et Autres, Raiku, ma contente de Traces of FreeBSD peut contenir des traces, des détrasses de FreeBSD. Désolé pour les petits problèmes, c'est un petit peu compliqué. J'ai pas vraiment de slide, ça c'est la seule diapo que j'ai, parce que je trouve que c'est plus intéressant de faire quelque chose d'interactif. Il y a une petite morceau de mon écran qu'on voit pas bien, donc on a dû improviser un peu. Mais bon, aujourd'hui je vais pouvoir parler de deux choses que j'adore, FreeBSD et des traces. Cette présentation ne dure que 30 minutes, donc je vais devoir parler un peu plus de détrasses et un peu moins de FreeBSD. Donc j'avais peut-être anticipé un petit peu plus, mais du coup j'ai dû raccourcir un peu. Et je vais aussi adapter le contenu pour que ça soit mieux dans la série de conférences sur Resilience. Alors qui dans cette salle a déjà utilisé des traces? Ok, un peu plus que j'aurais attendu, mais pas autant que j'aurais espéré. J'espère qu'à la fin de cette présentation vous direz tous, wow c'est un outil génial, il faut que je l'apprenne. Parce que moi personnellement ça a vraiment changé ma façon de débugger. Alors pour ceux d'entre vous qui ne connaissent pas des traces, laisse-moi vous vous introduire à ça. C'est un outil open source qui à la base a été créé sur Solaris, qui a été porté sur FreeBSD, NetBSD, OSX. Il y a aussi un portage sur Linux qui s'appelle Détrace pour Linux, ça a été porté sur QNX. Et il y a des gens de la communauté OpenBSD qui travaillent pour porter des traces sur leur système. On m'a dit qu'il y avait un portage pour Windows, je sais pas si c'est vraiment vrai, c'est assez cool. Parce que si c'est le cas, ça veut dire que c'est à peu près partout. La plupart d'entre vous doit connaître S-Trace, où il y a un outil très similaire sur FreeBSD qui s'appelle Truss. Et ce que font ces deux outils, c'est qu'ils peuvent s'attacher à un processus et regarder les appels systèmes que ce process est en train de faire. Si quelque chose se passe mal, ça permet de faire de l'introspection et de regarder à l'intérieur du programme, ce qui peut être utile dans plein de situations quand il y a des problèmes. C'est plutôt pratique, mais c'est un petit peu limité. Déjà, premièrement, ça ralentit énormément le processus qu'on est en train de débugger. Si vous avez quelque chose qui vous peut débugger et que grand, ça se passe à vitesse réelle, ça ne marchera pas. Un autre problème, c'est que ça attend à ne marcher que pour un seul processus à la fois. Et ça, c'est assez problématique parce qu'on a de plus en plus de systèmes très complexes dans lesquels on a beaucoup de couches. On va avoir des systèmes de fichiers virtuels, la mémoire virtuelle, le réseau, des bases de données, des processus qui parlent les uns aux autres. Et si vous utilisez un langage de programmation de plus haut niveau, vous êtes peut-être même un runtime pour ce langage. C'est comme un système d'opération au-dessus du système d'opération. Donc, quand quelque chose ne marche pas, il y a une complexité tellement importante qu'on arrive dans ce qu'on appelle en anglais le blame game, le jeu de se rocher la faute les uns les autres. C'est jamais votre faute, c'est toujours la faute de quelqu'un d'autre. Donc nous, ce qu'on veut pouvoir faire, pour éviter ça, c'est regarder le système comme un ensemble et regarder les données dans l'intégrité du système, ce qui permet de corréler ce qui se passe dans un point à un autre système pour mieux comprendre ce qui se passe quand quelque chose ne se passe pas comme prévu. Ce qu'on aimerait pouvoir faire, c'est regarder plusieurs processus. On veut aussi pouvoir les regarder en production. Comme on le sait tous, les problèmes se passent toujours en production, les problèmes intéressants au moins. Et du coup, pouvoir débuguer que dans un grand développement, c'est pas intéressant. Donc, pour pouvoir faire ça, pour pouvoir instrumentaliser le système de façon arbitraire, on a besoin d'avoir un nouveau langage de programmation qui permet d'exprimer, par exemple, regarde les données à cet endroit-là et dis-moi quand quelque chose se passe dessus. Donc, DETRAS vient avec son propre langage de programmation. C'est un peu un mélange de HAUK et de C. Ça s'apprend très facilement, ça prend bien facilement 20 minutes. Et une fois que vous avez appris un peu les bases, vous pouvez utiliser DETRAS. Alors, vous connaissez probablement HAUK qui permet d'analyser des grosses quantités de textes. DETRAS permet de faire un petit peu la même chose, mais pour analyser des systèmes. Ça peut être un petit peu perturbant, mais je vais vous montrer ce que je veux dire par là. Et, additionnellement, on ne veut pas ralentir le système. Donc, on va pouvoir faire différents types de debugging avec des questions de performance dedans. Donc, je vais préparer une petite démo ici. Quand on a eu quelques petits problèmes, je ne sais pas si c'est tout à fait lisible. Il faut que je le bouge un peu. Alors, je vais commencer par regarder une façon très naïve. Excusez-moi une seconde. Une façon très naïve d'authentifier un utilisateur. Il y a pas mal de problèmes avec ce code. Ce qu'on va faire, c'est qu'on va récupérer une chaîne de caractère en entrée, et on va la comparer à une chaîne de caractère secrète. Alors, je sais ce secret dans le code, il est en clair. C'est assez simple. Donc, d'un point de vue algorithmique, cette fonction de vérification est correcte. On récupère une chaîne de caractère, une autre chaîne de caractère, et on vous dit si il y a une erreur ou pas. Donc, ça, c'est plutôt facile. Si on regarde à comment marche la fonction string compare, ce que fait cette fonction, elle compare ces deux chaînes de caractère secrète. Caractère par caractère. Et quand cette fonction trouve la première paire de caractères qui est différente, elle s'arrête. Donc, de ça, on peut conclure quelque chose. Si cette fonction s'exécute en un temps très court, alors, ça veut dire qu'elle va se... terminer son exécution plus rapidement. Mais si on devine le mot de passe un petit peu mieux, cette fonction prendra un petit peu plus longtemps à s'exécuter. Et si on peut mesurer ce temps d'exécution, on peut extraire des informations de cet algorithme qui s'exécute. Donc, j'ai écrit ici un petit programme qui pilote le programme d'avant en Askel. Ce que fait ce programme, c'est qu'il y a des chaînes de caractère secrète. Et je vais utiliser des traces pour avoir des informations de timing. Donc, je commence ce programme driver qui tourne en arrière-plan. Là, vous ne pouvez pas voir ce que je tape. Ne vous inquiétez pas, tous ces scripts seront sur GitHub, donc vous pourrez les voir vous-même. Donc, maintenant, des traces nous affichent cette distribution. Si vous pourrez voir ce programme, vous pourriez voir que tout sauf d'a se comportent différemment. Si vous regardez de plus près, vous pouvez voir que la lettre d'a prend quelques nanosecondes de plus. Donc, on a mesuré à ce niveau de précision des nanosecondes. Et d'a est plus long que tous les autres. C'est un petit peu... Je sais que les gens ne font pas confiance quand je dis ça, mais bon. Alors, à partir de là, on peut juste taper un caractère. Et, bon, le script fasse tout et va supposer le caractère suivant. Alors, là, on s'est mis en place, et on a mis en place le caractère suivant. Donc, on a mis en place le caractère suivant, et on a mis en place le caractère suivant. Alors, là, avancer dommage qu'on ne puisse pas tout voir, parce que vous verrez que la distribution change complètement. C'est radicalement différent. Donc, là, on peut jouer à ça un petit moment. On peut avancer avec ça toutes les trois secondes notre script a refait un calcul à partir de la nouvelle distribution. Et là, vous pouvez probablement voir où est-ce qu'on se dirige. Et là, vous pouvez voir... Ça prend à peu près quelques trois secondes pour moi de deviner le caractère suivant. Et ça, ce n'est pas un problème qui est juste quelque chose qu'on n'a qu'en décomparation de chaîne de caractère. C'est quelque chose qui arrive dans à peu près tout, en particulier dès qu'on a des opérations cryptographiques. Quand on ne veut pas avoir d'informations qui peuvent liquer dans ce qu'on appelle des attaques de side-channel, des attaques à canaux parallèles. Donc, là, on peut utiliser des traces pour analyser le vrai binaire. Je ne l'ai pas modifié. Je n'ai pas inséré du code de debug. C'est du vrai code que je mettrai en production. Donc, ce qui est important avec ça, c'est qu'il y a certaines de ces attaques side-channel qui peuvent être introduites parfois par des optimisations du compilateur. Et quand vous insérez du code de debug quand vous êtes en train de développer, ça peut désactiver certaines de ces optimisations. Donc, ce que vous voulez faire en tant que développeur, c'est regarder le code réel qui est produit par votre compilateur. Donc, je vais vous montrer ce script que j'ai écrit pour ces analyses. Il y a trois choses intéressantes dans ce script. Vous ne comptez pas. C'est un des exemples les plus compliqués d'utilisation de détrasses qu'on peut faire. C'est juste pour vous inspirer. Détrasses peut vraiment vous permettre de tout faire. Il faut faire des choses vraiment très bizarres. Donc, ça, c'est un exemple vraiment compliqué, mais je vous en montrerai des plus simples après. Pour vous montrer comment on peut en arriver jusque-là. Il y a trois choses intéressantes dans ce code. La première, c'est quelque chose qu'on appelle une sonde. C'est un point d'instrumentation dans le système. Donc, quand certains événements se produisent dans le système, il y a des événements qui vont être déclenchés. Et dans un cas comme ça, la sonde, ça représente le moment où ces événements se déclenchent. La deuxième chose intéressante, c'est cette clause. Ça, c'est ce que la probe va exécuter, ce que la sonde va exécuter quand elle est déclenchée. Cette sonde ici est un petit peu plus intéressante. Elle ne dit quelque chose sur la structure interne d'une sonde comme celle-ci. Toutes les sondes sont identifiées de façon unique par un tuple de quatre éléments. Le premier, le premier élément de ce tuple, c'est ce qu'on appelle le provider, le fournisseur. Je vais en parler un petit peu plus tard. Le deuxième, c'est le module. Le troisième est la fonction. Et le dernier est le nom. Ces quatre éléments, ces quatre éléments du tuple, identifient une sonde de manière unique. La troisième chose qui est intéressante ici, c'est quelque chose dont malheureusement je ne vais pas avoir le temps de parler aujourd'hui, mais c'est ce qu'on appelle une aggregation. Cette ligne, juste cette ligne que vous voyez ici, est responsable de la tâche d'accumuler tous les résultats et de générer cette distribution que vous voyez à droite. Ça, c'est quelque chose qui est directement fourni par des traces. Vous avez pas grand-chose à faire vous-même. Si vous regardez ce script, il est vraiment très court. C'est quelques lignes de code. Mon premier prototype m'a pris environ cinq minutes. C'est vraiment très peu de travail de faire quelque chose avec ça. Donc c'est vraiment très utile d'avoir ça. Et si vous utilisez des traces, vous utiliserez ça énormément, ce genre de fonctionnalités qu'en fait du debugging de performance. Donc c'est vraiment cool d'avoir des fonctionnalités comme ça. Parlons un peu plus des fournisseurs. Ce sera peut-être un petit peu coupé ici. Vous ne pourrez peut-être pas tout voir. Donc je vais tricher un petit peu pour doubler ça. Parlons des fournisseurs, des providers. Alors il y en a quelques-uns. C'est pratique. J'en ai 27 ici. La liste des fournisseurs disponibles dépend du système d'exposition. Mais voilà, ça c'est ce que je peux voir maintenant. Il y en a d'autres qui peuvent être instantiés quand on en a besoin. Donc là j'en ai 27. Et on va regarder le fournisseur syscall, appel système, et le fournisseur xdb. Donc si le fournisseur syscall s'essuie qui sait comment instrumenter la table d'appel des syscalls. Ce n'est pas vraiment surprenant. Donc si vous regardez le fournisseur syscall, vous pouvez voir essentiellement chaque entrée ou retour d'un appel système disponible sur FreeBSD. Vous pouvez voir ici ce tuple à quatre éléments dont j'ai parlé. Vous pouvez voir syscall et le fournisseur, FreeBSD, le module, etc. Donc ça c'est tous les appels système qu'il y a sur mon système d'exposition. L'autre fournisseur dont je veux parler, c'est celui-ci qu'on appelle FBT. C'est assez pour Function Boundary Tracer, trois soeurs de limite de fonction. Et ça c'est assez impressionnant. Ce que ça vous permet de faire c'est de tracer l'exécution de n'importe quelle fonction dans le kernel. On peut regarder comment se comportent les fonctions au moment où elles sont appelées pour toutes les fonctions. Donc pour vous montrer ça, j'ai écrit un script très simple. Si vous regardez en haut, c'est un des plus simples. C'est vraiment un des exemples les plus simples que vous pouvez faire sur des traces. Donc ici ce que je vais faire c'est que je vais instrumenter l'appel système M-Map. Si vous savez pas ce que fait M-Map, c'est très simple. Ça vous permet essentiellement de prendre un fichier et de le mapper en mémoire à une adresse donnée dans votre espace d'adressage. Très utile, très commun. Donc quand on entre dans cet appel système, on va mettre la variable follow à 1. Ce que self ici veut dire, c'est une sorte de variable locale dans le thread d'exécution. Donc on va la mettre à 1 pour le thread qu'on est en train d'inspecter. Et ensuite, on va faire quelque chose qui a l'air un petit peu effrayant. On va instrumenter tout le kernel. Chaque fonction, chaque appel de fonction, chaque retour de fonction dans le kernel. Donc ça c'est ce qu'on appelle un prédicat. C'est un truc un peu à la haute ici. Ce qui est un prédicat qui permet de faire, c'est que quand ce prédicat s'évalue à quelque chose de vrai, la sonde va être exécutée. Donc quand follow est vrai, là on va émettre des données. Donc là on fait rien parce que c'est juste un exemple pour vous montrer comment on arrive là. Ensuite, quand on retourne de cet appel système M-App, on va remettre la variable follow à 0. Comme ça on arrête de suivre les appels dans le kernel. Et ensuite on va terminer l'exécution. Donc laissez-moi exécuter ça. Ça prend quelques secondes et boom. Donc là vous pouvez voir, il y a une petite pause. C'était quand des traces déchargeaient l'instrumentation du kernel. Et là on peut voir tous les appels de fonction qui se sont passés à l'intérieur de l'appel système M-Map. C'est un petit peu dur à lire donc laisse-moi passer ce flag ici. Et là on peut voir un graphe bien indenté, facile à lire. Et là vous pouvez dire, je n'aime pas trop ça. Vous injectez du code dans mon kernel, ça a l'air dangereux. Et ouais, mais laissez-moi vous montrer un truc que je trouve vraiment intéressant. Donc là je ne vais pas rentrer là-dedans en profondeur. Donc ça c'est le bytecode. Quand vous avez un script des traces et il est compilé, faire du bytecode. Et ce bytecode est inséré dans le kernel. Dans le kernel on a une machine virtuelle qui interprète ce bytecode. Donc si vous écrivez un script qui pour une raison quelconque a fait quelque chose de mauvais dans le kernel, à l'autre autre mémoire, prendre trop de temps. Cette machine virtuelle peut dire, stop, on arrête tout, et annuler tous les changements qui ont été faits dans le kernel. Et ça c'est assez pratique, c'est pas une idée nouvelle. Si vous utilisez par exemple TCP dump, ça fait à peu près la même chose. Il y a aussi un compilateur de bytecode. Ce type de bytecode, ça s'appelle BPF pour Berkeley Packet Filter. Donc c'est pas une idée nouvelle. Tout ce que je vous ai montré jusqu'à présent, c'est que je peux voir quand il y a un appel de fonction qui se produit. C'est pas beaucoup d'informations. Donc je vais augmenter un petit peu les informations que je récupère de système dans mon exemple. Alors, regardons le kernel. Il faut que je redémarre. Il a fallu que je redémarre la machine. Là j'ai perdu un peu des choses que j'ai préparées. Mais bon, regardons cette fonction VMFault. Ça c'est le code source du système de production que je fais tourner là maintenant. C'est FreeBSD. Et dans cette fonction VMFault, vous vous rappelez de VMMap, l'appel de système dont je parlais. Lui peut mapper un fichier dans votre espace d'adressage. Et il n'a pas nécessairement besoin de charger le fichier entier. Ce qui va se passer, c'est que quand on accède une page en mémoire, donc une page, ça fait 4 kHz ici sur mon système, quand du code va accéder à une page en mémoire qui n'a pas été chargée, qui n'a pas encore été chargée, ça génère ce qu'on appelle une page fault. Et le résultat, c'est que ça appelle cette fonction. Donc ce qu'on peut voir ici, c'est qu'il y a des arguments qui sont passés. Ça c'est l'adresse qui a provoqué cette violation. Ça c'est le type de violation. Et ça c'est les flags. Je vais vous montrer un petit peu ce que ça fait pour que ça soit plus compréhensible. Donc vous pouvez voir ici que ce type c'est un pointeur. Et ça c'est une grosse structure. Et ce qu'on voudrait, c'est pouvoir regarder ce qu'il y a dans cette structure. Et je vais simplement... comment je fais ça... Ok, donc ça c'est mon script. Ok, donc voilà. Je vais essayer de rendre ça plus lisible. Bon, regardez pas trop ce code ici. C'est juste du code pour rendre les choses un petit peu plus lisibles. Mais voilà, c'est ici que se passe la partie intéressante. Ce que je fais ici, c'est que j'enstrue cette fonction vmFault. De manière à ce que quand on entre dedans, on va pouvoir avoir des informations que des traces nous donnent gratuitement. Donc ça c'est l'exact name, le nom de l'exécutable qui produit cette pageFault. Ça c'est le PID, le identifiant de processeur. Et ça, ça nous permet de lire les arguments de la fonction. Donc arg1, arg2, arg3, c'est juste des entières, rien de très... rien de très exotique. Et nous, on veut regarder ce qu'il y a dans cette structure. Et là, je vais utiliser un array args qui est un petit peu spécial. Parce qu'il contient des informations de typage sur les arguments de la fonction. Donc moi, quand j'exécute ce code, donc là j'ai une référence Aspointer avec une étoile pour le déréferencer. Et si j'exécute juste ce programme, et peut-être voilà, je lance un processus. Et voilà, ça c'est des structures qui sont dans le carnel. Et je peux regarder ce qu'il y a à l'intérieur. Donc des traces nous laissent regarder à l'intérieur des structures en mémoire pendant que le système s'exécute. C'est extrêmement puissant. Et ici vous pouvez voir tous ces champs. Vous pouvez les manipuler, cet array args, comme vous manipuleriez n'importe quelle autre variable. Je peux faire avec ça comme si j'étais en C. Donc ça c'est plutôt cool. Il y a quelque chose qui s'appelle aussi CTF, c'est pas capture de flag. C'est Compact C Tracing Format, le format de trace compact. Donc ça c'est quelque chose qui est utilisé sur un frib SD. Il y a un segment dans le carnel où ces informations de typage sont stockées. Je sais pas si c'est similaire à Dwarf, mais voilà, c'est ce qu'utilise le carnel. Alors, en plus de monde, pourquoi est-ce que je regardais la gloire virtuelle ? Il n'y a pas de bug là-dedans, c'est quelque chose de safe. Sauf qu'il y en a. Est-ce que vous vous rappelez de Dirty Cow ? Dirty Cow, c'était une vulnérabilité vraiment dangereuse dans le carnel Linux. C'était via un problème dans la gestion de la gloire virtuelle. Ça, ça vous permettait d'écrire dans des fichiers auxquels vous n'aviez pas accès en tant qu'utilisateur. Vous pouvez réécrire un binaire avec le bit s'utiliser. Je ne veux pas dire que les développeurs carnelles Linux ont fait malfait les choses. Je veux dire que c'est quelque chose de très difficile à faire. La première fois qu'on a trouvé un problème dans, c'était en 2005. Et en 2016, c'est revenu. Mais on l'a fixé, on l'a résolu. Et puis c'est revenu en 2017, cette année, avec une variante qu'on appelait Huge Dirty Cow. Donc ça, c'est des problèmes qui sont là-dedans depuis plus de dix ans. C'est extrêmement difficile de débugger ça. Et ça, moi je trouve ça vraiment intéressant. Et avoir des outils comme des traces, pardon, pour moi c'est presque la sécurité par l'obscurité. C'est ne pas voir les problèmes. Et les gens qui développaient des exploits de failles sur des systèmes qui ont des traces disaient c'est vraiment pratique de développer avec ça. Parce qu'il y a vraiment cet outil super cool. Alors, c'est quelque chose de vraiment cool. Parce qu'un exploit, c'est une preuve que la faille fonctionne. Donc sortir un exploit rapidement, c'est une façon de te montrer que le problème est un vrai problème. Ça arrive souvent quand on trouve des vulnérabilités dans du code que les gens disent, ah, mais non, c'est pas une vraie vulnérabilité, c'est pas exploitable, etc. Donc si vous arrivez à faire un exploit, par exemple, parce que vous avez un script de traces qui vous permet de montrer qu'il y a vraiment ce problème et qu'il est vraiment exploitable, là les gens vous prennent au sérieux. Donc tout ce que je vous ai montré jusqu'à présent, c'était très lié aux appels de fonction. Et on voudrait avoir un petit peu plus de sémortique là-dedans. On voudrait peut-être créer un script qui inspecte des protocoles. Par exemple TCP ou UDP, des choses comme ça. Vous ne voulez pas avoir besoin de savoir quelle fonction précisément dans le kernel décode les paquets ou gère la stack TCP IP. Donc des traces à ce qu'on appelle les fournisseurs, les providers statiques. Donc ce que vous voyez ici, chacun d'entre eux a une page de man, de manuel. Il y a de la documentation, c'est cool. Et vous pouvez voir qu'il y a un fournisseur IO, si vous voulez regarder par exemple aux entrées sorties du disque, un pour regarder la stack IPv4 et pv6. Celui-ci, Sked, il est sympa, ça vous donne information à propos de votre script de l'heure. Vous savez ce que vous faites votre script de l'heure, on peut voir certaines choses. Par exemple, regardez quand est-ce que les priorités changent. Si vous avez déjà vu des phénomènes comme ça, d'un version de priorité, vous pouvez voir ça en direct avec des traces. C'est intéressant de pouvoir juste regarder comment est-ce que votre sked de l'heure décide de ne pas donner la priorité à vos processus, etc. Donc, j'ai plus beaucoup de temps là, mais je veux juste vous montrer rapidement un petit truc. Donc tout ça, c'est des choses côté kernel. Est-ce qu'on peut faire ça aussi pour user space ? Évidemment, on peut. Donc, il y a un fournisseur que j'ai pas montré avant, qui était pourtant dans un script que j'utilisais pour montrer les attaques de timing, et c'est le fournisseur PID. Celui-ci génère des sondes à l'admande, puisque un processus peut avoir beaucoup de sondes. Je vais vous montrer pourquoi. Je vais vous montrer un programme très simple. Ce qui ne fait qu'une seule chose, c'est quitter avec un code d'erreur mis sur succès. Et donc, quand j'exécute ça, je peux récupérer l'ID du processus quand j'exécute TRUE. Et ça, c'est tout ce qui se passe quand j'exécute ce programme. Et là, vous pouvez voir que c'est un petit peu plus, il y a un peu plus de détails qu'avec le fournisseur FBT. Puisque là, on peut voir chaque exécution dans la fonction. On peut aussi voir... Donc là, c'était pour le binaire TRUE. On peut aussi voir à l'intérieur d'une libraire répartagée. Et là, on peut voir qu'il y a beaucoup de code C qui est chargé quand on exécute TRUE. La dernière chose que je vais vous montrer, parce que ça a quand même pris une semaine entière de ma vie, j'utilise beaucoup de Askel et les gens sous... Les gens sous... Les gens sous... Les gens sous... Les gens sous... Les gens sous MacOS utilisent aussi des traces et ils ont un support pour des traces dans GHC, le compilateur Glasgow pour Askel. Et ils sont des sondes pour analyser ce qui se passe à l'intérieur du runtime Askel sur leur système. Alors moi je me disais mais j'ai des traces et j'utilise Askel, pourquoi ça marche pas sur un FreeBSD. Et après un petit peu de batailles pendant plusieurs jours entre des MacFile et Linker, ça marche. Si vous clenez le repository de GHC sur FreeBSD, vous récupérez toutes ces choses cool que je vais vous montrer maintenant. Donc ça c'est un programme pas très intéressant. Ils se contentent de lancer 32 traits de léger et de les... de les scheduler pour faire des trucs. Et avec des traces, ce que je peux faire ici, c'est intéressant. Je peux aussi utiliser des jokers dans mes filtres et dans mes sondes. Et voilà ce qui se passe à l'intérieur de GHC. On peut voir la garbage collection. Et avec ça on peut écrire plein de scripts très utiles parce qu'ils peuvent prendre en compte ce qui se passe dans le runtime du langage. Donc des choses comme ça, ça existe probablement pour Python. Je ne l'utilise pas celui-là mais je sais que ça existe aussi pour Node.js et pour d'autres langages. Et quelque chose d'intéressant c'est que par exemple si vous exécutez du JavaScript dans Firefox, des traces à un provider pour tracer le JavaScript qui s'exécute dans votre navigateur. Donc après tout ce que j'ai montré, ça peut peut-être vous donner des idées intéressantes. Donc voilà, c'est à peu près tout. Je vais devoir conclure parce qu'on a pu avoir de temps pour les questions et vous en avez peut-être. Donc voilà, merci beaucoup. Merci Raiko. Malheureusement, nous n'avons plus de temps. On a quand même 2 minutes parce qu'on est comme c'est trop bientôt tard. Donc s'il y a des questions très rapides, par exemple de l'Internet, le signal en chaine me dit qu'il y en a une. Écoudons-là. Donc la question, c'est quel changement sont nécessaires pour effectuer sur le kernel de l'OS pour supporter d'itrace ? Alors, c'est beaucoup de boulot. C'est pas quelque chose qu'on fait sur un week-end. La personne qui a commencé à bosser là-dessus sur FreeBSD, malheureusement, n'est plus avec nous. Mais je crois que ça prie au moins 2 ans pour mettre tout ça en place. Parce que vous avez des choses intégrées comme par exemple ce fournisseur CTF dont j'ai parlé qui a dû être construit spécialement pour FreeBSD. Et puis après, il y a plein d'autres couches du kernel donc c'est vraiment beaucoup de boulot. Mais ça, comme était déjà porté sur beaucoup de systèmes d'utilisation c'est même disponible sur Linux maintenant. J'espère que ça répond la question. Eh bien, il n'y a plus de questions. Je vais donc dire merci à Raiko. Vous pouvez le trouver ici dans la salle sur des questions ou alors sur Twitter.