IMA5 2018/2019 P10

De Wiki de Projets IMA


Présentation générale

Contexte

Un système temps réel est un système informatique chargé de contrôler un dispositif physique dans son environnement, et ce à une vitesse adaptée à la vitesse d'évolution du dispositif. La spécificité principale d'un tel système est qu'il est aussi important de calculer le bon résultat que de le calculer au bon moment. Par exemple, dans le système de contrôle de vol d'un avion, il est essentiel que les calculs soient effectués suffisamment rapidement pour permettre une réaction à des perturbations extérieures (par exemple une bourrasque de vent) dans un laps de temps assurant la stabilité de l'avion. Les systèmes temps réel sont désormais présents dans de nombreux secteurs d'activités, tels que l'aéronautique, les centrales nucléaires, les chaînes de production d'usines ou encore la robotique mobile.

Problématique

Un système temps réel est en général programmé sous la forme d'un ensemble de tâches exécutées de manière concurrente. Le comportement d'un tel système dépend non seulement du code de chaque tâche, mais aussi de leurs interactions et des dates auxquelles elles sont exécutées. Le débuggage d'un tel système nécessite de pouvoir étudier en détail ces interactions et ces dates d'exécution.

Objectifs

Ce projet s'inscrit dans le cadre d'un projet de recherche à l'IRCICA. L'objectif est de mettre au point un outil de traces d'exécution, et de statistiques basées sur ces traces, pour l'aide au débuggage d'un système temps réel. L'exécution du système temps réel en question est basée sur l'API ptask, une sur-couche temps réel aux pthreads POSIX. L'outil de trace s'appuiera sur le mécanisme de traces lttng pour Linux. A l'aide du mécanisme de trace développé, on souhaite pouvoir obtenir des informations sur les préemptions subies par chaque tâche, le temps passé à exécuter chaque tâche, le nombre d'échéances manquées, etc.

Préparation du projet

Cahier des charges

Le projet consiste en deux étapes. Tout d'abord, il faudra étudier les mécanismes de trace lttng existants dans le noyau Linux (il n'est pas demandé d'étudier le code du noyau, juste les informations déjà fournies par lttng), ainsi que le code de l'API ptask, afin de déterminer le code d'instrumentation à ajouter à l'API ptask pour obtenir les traces voulues. Ensuite, il faudra développer un outil permettant d'exploiter les traces obtenues pour en extraire les informations décrivant le comportement temps réel (préemptions, temps d'exécution, etc).

Choix techniques : matériel et logiciel

Les outils nécessaire à la réalisation du projet sont :

  • L'outils de traces d'exécutions du kernel Linux, des applications utilisateur, et bibliothèques LTTng.
  • L'API ptask basée sur pthreads qui permet de gérer des taches temps réel périodique.

Liste des tâches à effectuer

  • Se documenter sur l'outils de traces LTTng.
  • Presenter l'outil à l'équipe de recherche.
  • Se documenter sur l'API ptask.
  • Savoir à quel point l'outils de trace peut être exploiter.
  • Implémenter l'API avec l'outil de trace.
  • Améliorer et optimiser les résultat du traçage.

Calendrier prévisionnel

Réalisation du Projet

Semaine 1 :

Durant la première semaine, le travail effectué était un travail de recherche et de documentation sur les traces d'executions sur Linux, et sur les outils de traces utilisés et leurs fonctionnement. Cette semaine à surtout servie à la compréhension du sujet, et à l'établissement d'un cahier de charges.

Outil de trace LTTng :

Introduction au Kernel Tracing et Profiling :

Le profilage du kernel sert à détecter ce qu'on appelle les "bottlenecks" de performance, -des points d'un système limitant les performances globales, et pouvant avoir un effet sur les temps de traitement et de réponse. Les bottlenecks peuvent être matériels et/ou logiciels-. Le profilage nous aide à déterminer où exactement dans un programme nous perdons de la performance. Les programmes spéciaux génèrent un profil -un résumé d'events- qui peut être utilisé pour déterminer quelles fonctions ont pris le plus de temps à exécuter. Ces programmes, cependant, n'aident pas à déterminer pourquoi le rendement a chuté.

Le traçage est le processus de collecte d'informations sur l'activité dans un système fonctionnel. Cela se fait à l'aide d'outils spéciaux qui enregistrent les événements du système, un peu comme la façon dont un magnétophone enregistre le son ambiant. Les programmes de traçage peuvent tracer simultanément les événements au niveau de l'application et de l'OS. L'information qu'ils recueillent peut être utile pour diagnostiquer de multiples problèmes de système.

Le traçage est parfois comparé au logging. Il y a certainement des similitudes entre les deux, mais il y a aussi des différences. Avec le traçage, des informations sont écrites sur les événements de bas niveau. Ils se comptent par centaines, voire par milliers. Avec le logging, des informations sont écrites sur les événements de niveau supérieur, qui sont beaucoup moins fréquents. Il s'agit notamment des utilisateurs qui se connectent au système, des erreurs d'application, des transactions dans la base de données, etc.

Tout comme les journaux, les données de traçage peuvent être lues telles quelles ; cependant, il est plus utile d'extraire des informations sur des applications spécifiques. Tous les programmes de traçage en sont capables. Le noyau Linux possède trois mécanismes principaux pour le traçage et le profilage du noyau :

  • tracepoints - un mécanisme qui fonctionne sur le code statique instrumenté.
  • kprobes - un mécanisme de traçage dynamique utilisé pour interrompre le code d'un noyau à n'importe quel moment, appeler son propre gestionnaire, et revenir après que toutes les opérations nécessaires ont été effectuées.
  • perf_events - une interface pour accéder à la PMU (Performance Monitoring Unit).

Introduction à LTTng :

Le traceur kernel "Linux Trace Toolkit : new generation" est un logiciel "toolkit" open source qui peut être utiliser pour tracer simultanément le noyau Linux, les applications utilisateur et les bibliothèques utilisateur. LTTng se compose de :

Lttng logo.png
  • Modules du noyau pour tracer le noyau Linux.
  • Bibliothèques partagées pour tracer les applications utilisateur écrites en C ou C++.
  • Packages Java pour tracer les applications Java qui utilisent java.util.logging ou Apache log4j 1.2.
  • Un package Python pour tracer les applications Python qui utilisent le package de logging standard.
  • Un module noyau pour tracer les scripts shell et autres applications utilisateur sans mécanisme d'instrumentation dédié.
  • Daemons et un outil en ligne de commande, lttng, pour contrôler les traceurs LTTng.

Entre autre, il peut effectuer les tâches suivantes :

  • Analyser les interactions interprocessus dans le système.
  • Analyser les interactions application-kernel dans l'espace utilisateur.
  • Mesurer le temps que le noyau passe à répondre aux demandes d'application.
  • Analyser le fonctionnement du système sous des charges de travail élevées.

L'histoire du logiciel a progressé et a conduit à ce qu'on tiens maintenant pour acquis -des applications logicielles complexes, nombreuses et interdépendantes fonctionnant en parallèle sur des systèmes d'exploitation sophistiqués comme Linux- les auteurs de tels composants, les développeurs de logiciels, ont commencé à ressentir le besoin naturel de disposer des outils qui assureraient la solidité et la bonne performance de leurs chefs-d'oeuvre. LTTng a longtemps été inclus dans la plupart des dépôts Linux officiels. Il est utilisé par des entreprises comme Google, Siemens et Boeing.

Historique :

En 1999, un employé d'IBM, "Karim Yaghmour", a commencé à travailler sur LTT (Linux Trace Toolkit). LTT a été construit sur l'idée suivante : instrumenter statiquement les fragments les plus importants du code du noyau et ainsi récupérer efficacement les informations sur les performances du système. Quelques années plus tard, cette idée a été reprise et développée par "Matthew Donahue" dans le cadre du projet LTTng (Linux Tracing Tool New Generation). LTTng a été publié pour la première fois en 2005.

Il y a une raison pour laquelle le titre du projet inclut le terme Nouvelle Génération : Donahue a beaucoup investi dans le développement des mécanismes de traçage et de profilage de Linux. Il a ajouté l'instrumentation statique pour les fonctions les plus importantes du noyau ; c'est ainsi que nous avons obtenu le mécanisme des marqueurs du noyau, dont l'amélioration a conduit au développement des points de trace. LTTng utilise activement les points de trace. C'est grâce à ce mécanisme qu'il est possible de tracer sans augmenter la charge du système. En 2009, Donahue a soutenu sa thèse sur le travail accompli.

Alternatives à LTTng :

En excluant les solutions propriétaires, il existe quelques traceurs logiciels concurrents pour Linux :

  • dtrace4linux est un portage de DTrace vers Linux de Sun Microsystems. L'outil dtrace interprète les scripts utilisateur et est responsable du chargement du code dans le noyau Linux pour une exécution ultérieure et la collecte des données de sortie.
  • ftrace est le traceur de fonction facto du noyau Linux. Son interface utilisateur est un ensemble de fichiers spéciaux dans sysfs.
  • perf est un outil d'analyse des performances pour Linux qui prend en charge les compteurs de performances matérielles, les tracepoints, ainsi que d'autres compteurs et types de sondes. L'utilitaire de contrôle de perf est l'outil perf en ligne de commande.
  • strace est un utilitaire en ligne de commande qui enregistre les appels système effectués par un processus utilisateur, ainsi que les signaux système et les changements d'état du processus. strace utilise ptrace pour remplir sa fonction.

La principale particularité de LTTng est qu'il produit des traces corrélées du noyau et de l'espace utilisateur, tout en réduisant au minimum les frais généraux parmi d'autres solutions. Il produit des fichiers de traces au format CTF, un format de fichier optimisé pour la production et l'analyse de données multi-gigaoctets. L'interface principale pour le contrôle de traçage est un outil en ligne de commande unique nommé lttng. Ce dernier peut créer plusieurs sessions de traçage, activer et désactiver les événements à la volée, filtrer efficacement les événements avec des expressions utilisateur personnalisées, démarrer et arrêter le traçage, et bien plus encore. LTTng peut enregistrer les traces sur le système de fichiers ou les envoyer sur le réseau, et les conserver totalement ou partiellement. Vous pouvez visualiser les traces une fois que le traçage devient inactif ou en temps réel.

Installation :

LTTng est un ensemble de composants logiciels qui interagissent pour instrumenter le noyau Linux et les applications utilisateur, et pour contrôler le traçage (démarrer et arrêter le traçage, activer et désactiver les règles d'événements, et le reste). Ces composants sont regroupés dans les packages suivants :

  • LTTng-tool : Bibliothèques et interface en ligne de commande pour contrôler le traçage.
  • LTTng-modules : Modules du noyau Linux pour instrumenter et tracer le noyau.
  • LTTng-UST : Bibliothèques et paquets Java/Python pour instrumenter et tracer les applications utilisateur.

Pour installer LTTng, se referer à la documentation LTTng.

Conceptes de bases :

Du point de vue de l'utilisateur, le système LTTng est construit sur quelques concepts, ou objets, sur lesquels lttng command-line tool fonctionne en envoyant des commandes à la session deamon. Comprendre comment ces objets sont liés les uns aux autres est essentiel pour maîtriser l'outil. Les concepts de base sont :

Lttng concept.png
1. Session de trace
Une session de traçage est un dialogue dynamique entre l'utilisateur et la session deamon. La commande lttng create permet de créer une session de traçage, et chaque session a :
  • son propre nom.
  • ses propre fichiers de trace.
  • son propre état d'activité (démarré ou arrêté).
  • son propre mode (local, streaming réseau, snapshot ou en direct).
  • ses propres channels qui ont leurs propres règles d'événements.
Ces attributs et objets sont complètement isolés entre les différentes sessions de traçabilité.
Une session de traçage est analogue à une session de guichet automatique : les opérations qu'on effectue sur le système bancaire via le guichet automatique ne modifient pas les données des autres utilisateurs du même système. Dans le cas d'un distributeur automatique de billets, une session dure aussi longtemps que la carte bancaire est à l'intérieur. Dans le cas de LTTng, une session de traçage dure de la commande lttng create à la commande lttng destroy.
LTTng peut envoyer les données de trace générées à différents endroits. Le mode session de traçage dicte où l'envoyer. Les modes suivants sont disponibles dans LTTng 2.10 :
  • Mode local : LTTng écrit les traces dans le système de fichiers de la machine tracée (système cible).
  • Mode streaming réseau : LTTng envoie les traces sur le réseau à un démon relais fonctionnant sur un système distant.
  • Mode snapshot : LTTng n'écrit pas les traces par défaut. Au lieu de cela, LTTng peut prendre un snapshot, c'est-à-dire une copie des tampons de traçage actuels, et de l'écrire dans le système de fichiers de la cible ou de l'envoyer sur le réseau à un démon de relais fonctionnant sur un système distant.
  • Mode temps réel : Ce mode est similaire au mode de diffusion en continu sur le réseau, mais un visualiseur de trace en direct peut se connecter au démon relais distant pour visualiser les enregistrements d'événements lorsque LTTng les génère par les traceurs.
2. Domain de trace.
Un domain de traçage est un espace pour les sources d'événements. Un domaine de traçage a ses propres propriétés et caractéristiques. Il y a actuellement cinq domaines de traçage disponibles :
  • noyau Linux
  • espace utilisateur
  • java.util.logging (JUL)
  • log4j
  • Python
On peut spécifier un domaine de traçage lors de l'utilisation de certaines commandes pour éviter toute ambiguïté. Par exemple, puisque tous les domaines supportent les tracepoints nommés comme sources d'événements (points d'instrumentation que vous insérez manuellement dans le code source), vous devez spécifier un domaine de traçage lors de la création d'une règle d'événement car tous les domaines de traçage peuvent avoir des tracepoints avec les mêmes noms.
Il est également possible de créer des canaux dans les domaines de traçage du noyau Linux et de l'espace utilisateur. Les autres domaines de traçage ont un seul canal par défaut.
3. Channel et ring buffer.
Un channel est un objet responsable d'un ensemble de buffers circulaires. Chaque buffer circulaire est divisé en plusieurs sous-buffers. Lorsqu'un traceur LTTng émet un événement, il peut l'enregistrer dans un ou plusieurs sous-buffers. Les attributs d'un channel déterminent ce qu'il faut faire lorsqu'il n'y a plus de place pour un nouvel enregistrement d'événement parce que tous les sous-buffers sont pleins.
Un channel est toujours associé à un domaine de traçage. Et possède également des règles d'événement.
Un channel possède au moins un buffer circulaire par CPU. LTTng enregistre toujours un événement dans le buffer circulaire associé au CPU sur laquelle il s'est produit. Deux schémas de mise en mémoire buffer sont disponibles lorsque un channel est créé dans le domaine de traçage de l'espace utilisateur :
  • Mise en mémoire par utilisateur : affectez un jeu de buffers circulaires -un par processeur- partagé par tous les processus instrumentés de chaque utilisateur Unix.
  • Mise en mémoire par processus : affectez un jeu de buffers circulaires - un par processeur - à chaque processus instrumenté.
Le domaine de traçage du noyau Linux n'a qu'un seul schéma de tamponnage disponible qui consiste à allouer un seul jeu de buffer circulaires pour l'ensemble du système. Ce schéma est similaire à l'option par utilisateur, mais avec un seul utilisateur global qui exécute le noyau.
Lorsqu'un événement se produit, LTTng l'enregistre dans un sous-buffer spécifique du buffer circulaire d'un channel spécifique. Quand il n'y a plus de place dans un sous-buffer, le traceur le marque comme consommable et un autre sous-buffer vide commence à recevoir les enregistrements d'événements suivants. Un deamon consommateur finit par consommer le sous-buffer marqué. Par défaut, les modules LTTng et LTTng-UST sont des traceurs non bloquants : lorsqu'aucun sous-buffer vide n'est disponible, il est acceptable de perdre des enregistrements d'événements alors que l'alternative serait de causer des retards importants dans l'exécution de l'application instrumentée. Mais à partir de LTTng 2.10, le traceur d'espace utilisateur LTTng, LTTng-UST, supporte un mode de blocage. Ce qui veut dire que lorsqu'il s'agit de perdre des enregistrements d'événements parce qu'aucun sous-buffer vide n'est disponible, ou parce que le délai de blocage est atteint, le mode de perte d'événement du channel détermine ce qu'il faut faire. Les modes de perte d'événement disponibles sont :
  • Mode discard : lâchez les enregistrements d'événements les plus récents jusqu'à ce que le traceur libère un sous-buffer. (c'est le seul mode disponible lorsque un délai de blocage est spécifié.)
  • Mode overwrite : effacez le sous-buffers contenant les enregistrements d'événements les plus anciens et commencez à y écrire les enregistrements d'événements les plus récents.
Lorsque un channel est créé, le nombre de sous-buffers et leur taille peut être définit. La temporisation de commutation est aussi un attribut configurable important d'un channel. A l'expiration de la temporisation de commutation, un changement de sous-buffer' se produit.
4. Points d'instrumentation, règles d event, event, enregistrement d' event.
Une règle d'événement est un ensemble de conditions qui doivent toutes être remplies pour que LTTng puisse enregistrer un événement.
Les conditions sont crées lors de la création de la règle d'événement.
Et une règle d'événement doit toujours être attaché au canal lorsque qu'il est crée.
Lorsqu'un événement passe les conditions d'une règle d'événement, LTTng l'enregistre dans l'un des sous-tampons du canal attaché.
Les conditions disponibles, à partir de LTTng 2.10, sont :
  • La règle d'événement est activée.
  • Le type du point d'instrumentation.
  • Le nom du point d'instrumentation.
  • Le niveau du log du point d'instrumentation.
  • Les champs du playload de l'événement satisfont une expression de filtre.


Semaine 2 :

Le travail de la deuxième semaine est de se documenter sur les outils d'instrumentation et de contrôle de LTTng, puis de tester l'outil avec ses deux mode de fonctionnement : user-app et kernel. L'objectif de cette semaine est de connaitre le fonctionnement de LTTng et de se familiariser avec l'outil, tout en commençant à réfléchir à l'aspect temps-réel du système.

Instrumentation de LTTng :

Composants :

L'écosystème LTTng est composé de plusieurs composantes, qui interagissent avec les applications utilisateur, avec le kernel Linux, puis avec l'utilisateur. Le projet LTTng intègre :

  • LTTng-tools : Bibliothèques et interface en ligne de commande pour contrôler les sessions de traçage.
  • LTTng-UST : Bibliothèques et paquets Java/Python pour tracer les applications utilisateur.
  • LTTng-modules : Modules du noyau Linux pour tracer le noyau.
Lttng components.png
1. Interface en ligne de commande pour le contrôle du traçage
L'outil en ligne de commande lttng est l'interface utilisateur standard pour contrôler les sessions de traçage LTTng. Il fait partie des LTTng-tools, et est lié à liblttng-ctl pour communiquer avec un ou plusieurs session-deamons dans les coulisses.
lttng <GENERAL OPTIONS> <COMMAND> <COMMAND OPTIONS>
2. Bibliothèque pour le contrôle du traçage
La bibliothèque de contrôle LTTng, liblttng-ctl, est utilisée pour communiquer avec le session-deamon en utilisant une API C qui cache les détails du protocole sous-jacent. La bibliothèque fait partie de LTTng-tools. Pour l'utiliser en C ou C++, il suffit d'inclure son en-tête "master" :
#include <lttng/lttng.h>
Certains objets sont référencés par leur nom (chaîne C), comme les sessions de traçage, mais la plupart d'entre eux nécessitent de créer un handle en utilisant lttng_create_handle().
3. Bibliothèque de traçage pour l'espace utilisateur
La bibliothèque de traçage de l'espace utilisateur, liblttng-ust, est le traceur d'espace utilisateur LTTng. Il reçoit des commandes d'un session-deamon, par exemple pour activer et désactiver des points d'instrumentation spécifiques, et écrit des enregistrements d'événements dans des buffers circulaires partagés avec un consumer-deamon. liblttng-ust fait partie de LTTng-UST.
Les fichiers d'en-tête C publics sont installés à côté de liblttng-ust pour instrumenter toute application C ou C++. Et les agents LTTng-UST, qui sont des paquets Java et Python réguliers, utilisent leur propre bibliothèque fournissant des points de trace qui est liée à liblttng-ust. (les agents Java et Python ne seront pas utilisé et donc pas abordé en details)
4. Modules LTTng pour le kernel
Les modules du noyau LTTng sont un ensemble de modules du noyau Linux qui implémentent le traceur du noyau du projet LTTng. Les modules du noyau LTTng font partie de LTTng-modules. Ils incluent :
  • Un ensemble de modules probe (sonde) : Chaque module s'attache à un sous-système spécifique du noyau Linux à l'aide de ses points d'instruments tracepoint. Il existe également des modules à attacher aux points d'entrée et de retour des fonctions d'appel système Linux.
  • Modules ring buffer : Une implémentation de buffer circulaire est fournie sous forme de modules noyau. Le traceur de noyau LTTng écrit dans le buffer circulaire, et un consumer-deamon lit dans le buffer circulaire.
  • Le module kernel tracer LTTng.
  • Le module kernel logger LTTng : Le module logger LTTng implémente le fichier /proc/lttng-logger spécial afin que tout exécutable puisse générer des événements LTTng en ouvrant et écrivant dans ce fichier.
5. Session deamon
Le session-deamon est un démon responsable de la gestion des sessions de traçage et du contrôle des différents composants de LTTng. Le démon de session fait partie de LTTng-tools. Il envoie des demandes de contrôle à (et reçoit des réponses de contrôle de) :
  • La bibliothèque de traçage de l'espace utilisateur : Toute instance de la bibliothèque de traçage de l'espace utilisateur s'enregistre d'abord à un démon de session. Ensuite, le démon de session peut envoyer des requêtes à cette instance, telles que :
    • Obtenez la liste des points de trace.
    • Partager une règle d'événement pour que la bibliothèque de traçage de l'espace utilisateur puisse activer ou désactiver les points trace.
    • Partagez les attributs de canal et les emplacements de tampon circulaire.
Le démon de session et la bibliothèque de traçage de l'espace utilisateur utilisent une socket du domaine Unix pour leur communication.
  • Les agents de traçage de l'espace utilisateur : Toute instance d'un agent de traçage de l'espace utilisateur s'enregistre d'abord à un démon de session. Ensuite, le démon de session peut envoyer des requêtes à cette instance, telles que :
    • Obtenez la liste de loggers.
    • Activer ou désactiver un logger spécifique.
Le démon de session et l'agent de traçage de l'espace utilisateur utilisent une connexion TCP pour leur communication.
  • Le traceur du noyau.
  • Le démon de "consommation".

Le daemon de session envoie des demandes au consumer-deamon pour lui indiquer où envoyer les flux de données de trace, entre autres informations.

  • Le démon relais.
Le démon de session reçoit les commandes de la bibliothèque de contrôle de traçage.
Le démon de session racine charge les modules appropriés du noyau LTTng au démarrage. Il génère également un démon consommateur dès qu'une règle d'événement est créée.
Chaque utilisateur Unix peut avoir sa propre instance de démon de session. Les sessions de traçage gérées par différents démons de session sont totalement indépendantes.
Le démon de session de l'utilisateur root est le seul qui est autorisé à contrôler le traceur du noyau LTTng, et son démon consommateur engendré est le seul qui est autorisé à consommer les données de trace du traceur du noyau LTTng.
6. Consumer deamon
Le démon consommateur, lttng-consumerd, est un démon qui partage des buffers avec les applications utilisateur ou avec les modules du noyau LTTng pour collecter les données de trace et les envoyer à un emplacement (sur disque ou à un démon relais sur le réseau). Le démon consommateur fait partie de LTTng-tools.Il n'est jamais lancé manuellement, mais est toujours généré par un démon de session dès qu'une règle d'événement est créée (avant de commencer le traçage). Lorsque son démon de session propriétaire est tué, le démon consommateur quitte également parce qu'il s'agit du processus enfant du démon de session.
Il y a jusqu'à deux démons consommateurs en cours d'exécution par utilisateur Unix, alors qu'un seul démon de session peut être exécuté par utilisateur. En effet, chaque processus peut être 32 bits ou 64 bits : si le système cible exécute un mélange de processus 32 bits et 64 bits, il est plus efficace de disposer de démons consommateurs 32 bits et 64 bits séparés. L'utilisateur root est une exception : il peut avoir jusqu'à trois démons consommateurs en cours d'exécution : 32 bits et 64 bits pour ses applications utilisateur, et une autre instance réservée à la collecte des données de trace du noyau.

Instrumentation :

Plusieurs méthodes permettent d'instrumenter un logiciel de traçage LTTng. Le plus simple est de placer manuellement les points d'instrumentation, appelés tracepoints, dans le code source du logiciel. Il est également possible d'ajouter dynamiquement des points d'instrumentation dans le domaine du traçage du noyau Linux. Pour un système temps-réel, il faudra également tracer le noyau Linux, et notamment les appelles système qui gèrent les Threads. Dans ce cas, les besoins en instrumentation sont déjà couverts en majorité par les points de trace intégrés du noyau Linux de LTTng. Pour instrumenter une application utilisateur, il faudra utiliser la bibliothèque lttng-ust, en suivant les étapes :

1. Créer les fichiers sources d'un package fournisseur tracepoint
Lttng provider.png
Un fournisseur de points de trace (ou tracepoints provider) est un ensemble de fonctions compilées qui fournissent des points de trace à une application, le type de point d'instrumentation supporté par LTTng-UST. Ces fonctions peuvent émettre des événements avec des champs définis par l'utilisateur et sérialiser ces événements en tant qu'enregistrements d'événements dans un ou plusieurs sous-tampons de canaux LTTng-UST. La macro tracepoint(), que vous insérez dans le code source d'une application utilisateur, appelle ces fonctions.
Un package fournisseur tracepoint est un fichier objet (.o) ou une bibliothèque partagée (.so) qui contient un ou plusieurs fournisseurs tracepoint. Ses fichiers sources sont :
  • Un ou plusieurs en-tête(s) de fournisseur tracepoint (.h).
  • Une source d'emballage fournisseur de tracepoint (.c).
Un package fournisseur tracepoint est lié dynamiquement avec liblttng-ust, le traceur d'espace utilisateur LTTng, au moment de l'exécution.
2. Construire et lier un package fournisseur de tracepoint et une application
Une fois un ou plusieurs fichiers d'en-tête de fournisseur de tracepoint et un fichier source de paquet de fournisseur de tracepoint prêts, il faut créer le paquet de fournisseur de tracepoint en compilant son fichier source. A partir de là, plusieurs choix de construction et d'exécution sont possibles.
  1. L'application instrumentée est liée statiquement à l'objet package du fournisseur tracepoint :
    1. Compilez le fichier source du paquet fournisseur tracepoint : gcc -I. -c tpp.c
    2. Dans app.c, avant d'inclure tpp.h, ajouter : #definir TRACEPOINT_DEFINE
    3. Compiler le fichier source de l'application : gcc -c app.c
    4. Créer l'application : gcc -o app.app.o app.tpp.o -llttng-ust -ldl
    5. Lancer l'application : ./app
  2. L'application instrumentée est liée statiquement au fichier d'archive du package du fournisseur tracepoint :
    1. Compiler le fichier source du paquet fournisseur tracepoint comme pour 1
    2. Créer le fichier d'archive du package du fournisseur tracepoint : ar rcs tpp.a tpp.tpp.o
    3. Construire et exécuter l'application instrumentée 'comme pour 1.
  3. L'application instrumentée est liée à l'objet partagé du package fournisseur tracepoint :
    1. Compiler le fichier source du paquet fournisseur tracepoint : gcc -I. -fpic -c tpp.c
    2. Créer l'objet partagé du package fournisseur tracepoint : gcc -shared -o libtpp.so tpp.o -llttng-ust -ldl
    3. Ajouter # define et compiler l'application comme pour 1
    4. Construire l'application : gcc -o app app.o -ldl -L. -ltpp
    5. Exécuter l'application comme pour 1
  4. L'objet partagé du package fournisseur tracepoint est préchargé avant le démarrage de l'application instrumentée.
    1. Compiler et créer le paquet fournisseur tracepoint comme pour 3
    2. Dans app.c, avant d'inclure tpp.h, ajouter #definir TRACEPOINT_DEFINE et #define TRACEPOINT_PROBE_DYNAMIC_LINKAGE
    3. Compiler le fichier source de l'application comme pour 1
    4. Créer l'application : gcc -o app.app.o -ldl
    5. Précharger l'objet partagé du package fournisseur tracepoint et démarrez l'application : LD_PRELOAD=./libtpp.so.so./app
Pour plus de détails, se référer à la documentation.

Dans le cas d'un système temps réel, l'application instrumentée peut appeler des fork(2), clone(2), ou rfork(2), sans appel système exec(3). il est possible de précharger l'objet partagé liblttng-ust-fork.so lorsque l'application est lancée. De même, Le paquet LTTng-UST fournit quelques aides sous la forme d'objets partagés préchargeables qui appellent automatiquement les fonctions et les appels du système de l'instrument. Les objets partagés de l'assistant se trouvent normalement dans /usr/lib<code>, ou dans <code>/usr/local/lib, si LTTng-UST est construit à partir des sources, ils sont probablement situés. Les assistants de traçage de l'espace utilisateur installés dans LTTng-UST 2.10 sont :

  • liblttng-ust-libc-wrapper.so : Bibliothèque C standard pour la gestion de mémoire et traçage des fonctions de threads POSIX.
  • liblttng-ust-cyg-profile.so : Suivi de l'entrée et de la sortie des fonctions.
  • liblttng-ust-dl.so : Traçage dynamique de l'éditeur de liens.

Pour utiliser une aide de traçage de l'espace utilisateur avec n'importe quelle application utilisateur, il faut précharger l'objet partagé de l'assistant lorsque vous démarrez l'application :

 LD_PRELOAD=liblttng-ust-libc-wrapper.so my-app

Test de traçage :

Après l'installation de LTTng, pour tester l'outil, on peut prendre par exemple :

Dans le domaine utilisateur :

  • hello-tp.h :
#undef TRACEPOINT_PROVIDER
#define TRACEPOINT_PROVIDER the_provider

#undef TRACEPOINT_INCLUDE
#define TRACEPOINT_INCLUDE "./hello-tp.h"

#if !defined(_HELLO_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
#define _HELLO_TP_H

#include <lttng/tracepoint.h>

TRACEPOINT_EVENT(
    the_provider,
    the_tracepoint,
    TP_ARGS(
        int, nombre,
        char*, string
    ),
    TP_FIELDS(
        ctf_string(champ1, string)
        ctf_integer(int, champ2, nombre)
    )
)

#endif /* _HELLO_TP_H */
#include <lttng/tracepoint-event.h>
  • hello-tp.c :
#define TRACEPOINT_CREATE_PROBES
#define TRACEPOINT_DEFINE

#include "hello-tp.h"
  • hello.c :
#include <stdio.h>
#include "hello-tp.h"

int main(int argc, char *argv[])
{
    getchar();
    tracepoint(the_provider, the_tracepoint, 23, "hello");
    return 0;
}

Pour cet premier example l'application hello serra liée statiquement au provider hello_tp et sera construite comme suit :

Lttng tracing process.png

Dans le domaine noyau :

Les événements : appels système et tracepoints sont prédéfini dans la liste des événement du noyau, il faut juste activer les événement utils au projet.

Résultats des tests pour le temps-réel :

  • Les tests ont aussi portés sur le traçage dans les deux domaines en parallèle. La documentation technique ne présente aucune contre indication à cette utilisation. Mais, lorsqu'une session est créée, un démon de session est également crée, et le démon de session du noyau et différent de celui de l'espace utilisateur. Il faudra donc utiliser le root session daemon lors de la creation de la session pour ne pas avoir deux traçages indépendants.
  • L'API qui gère les taches temps-réel est basée sur la bibliothèque pthread. Après l'ajout d'un thread dans hello.c et le traçage de ce dernier avec une démon du noyau, on peut remarqué que le noyau ne différencie pas entre les appels système de processus et ceux des threads. Effectivement, le noyau nous donne ce que l'on appelle parfois des processus légers, qui sont une généralisation des concepts de processus et de threads, et peuvent être utilisés pour les mettre en œuvre. Linux a un appel système appelé clone qui est utilisé pour créer de nouveaux processus légers. Lorsque un clone, on peut fournir divers flags avec, qui indiquent ce qui sera partagé entre le nouveau processus et le processus existant. Les threads utilisent le clone pour créer des processus qui partagent leur espace d'adressage, des fichiers ouverts, des gestionnaires de signaux...


Semaine 3 :

L'objectif de cette semaine et d'étudier les outils de visionnage des traces, puis de ce se familiariser avec avec l'API ptask. Ce travail représente la fin de la première tache : la documentation sur LTTng, et le début de la troisième tache : documentation sur ptask.

Control de trace de LTTng :

Une fois qu'une application ou un noyau Linux est instrumenté pour le traçage LTTng, le traçage peut être effectuer avec un outil en ligne de commande lttng, pour contrôler les démons et traceurs LTTng.

Créer une session démon :

Chaque utilisateur Unix doit avoir son propre démon de session en cours d'exécution pour tracer les applications utilisateur. Le démon de session que l'utilisateur root lance est le seul autorisé à contrôler le traceur du noyau LTTng. Les utilisateurs qui font partie du groupe de traçage peuvent contrôler le démon de session racine.

lttng-sessiond --daemonize

Pour arrêter un démon de session, il faut utiliser kill(1) sur son ID de processus (signal TERM standard).

Créer et détruire une session de trace :

Presque toutes les opérations de contrôle LTTng se déroulent dans le cadre d'une session de traçage, qui est le dialogue entre le démon de session et l'utilisateur.

lttng create my-session --output=/tmp/some-directory

LTTng ajoute la date de création au nom de la session de traçage créée. Il écrit les traces d'une session de traçage dans $LTTNG_HOME/lttng-trace/name par défaut, où name est le nom de la session de traçage (avec la variable d'environnement LTTNG_HOME par défaut est $HOME si elle n'est pas définie). Il existe également des commandes lttng qui opèrent sur la session courante :

  • list
  • add-context
  • destroy
  • disable-channel
  • disable-event
  • enable-channel
  • enable-event
  • load
  • regenerate
  • save
  • snapshot
  • start
  • stop
  • track
  • untrack
  • view

À la fin de la session traçage, on peut la détruire. Cette opération libère les ressources que la session de traçage doit détruire ; elle ne détruit pas les données de traçage que LTTng a écrites pour cette session de traçage.

lttng destroy

Liste des points d'instrumentation :

Le démon de session peut interroger les applications utilisateur en cours d'exécution et le noyau Linux pour obtenir une liste des points d'instrumentation disponibles. Pour le domaine de traçage du noyau Linux, ce sont des points de trace et des appels système. Pour le domaine de traçage de l'espace utilisateur, ce sont des points de trace. Pour les autres domaines de traçage, ce sont des noms de loggers.

lttng list --userspace
lttng list --kernel --syscall

Créer et activer des événements :

Une fois la session de traçage créer, vous pouvez créer des règles d'événement avec la commande lttng-enable-event(1). Les options de condition disponibles sont :

  • Au lieu d'utiliser le type d'instrumentation tracepoint par défaut, on peut :
    1. --syscall
    2. --probe=ADDR
    3. --function=ADDR
  • Liste des noms de niveau d'enregistrement disponibles :
    1. --loglevel=LEVEL
    2. --loglevel-only=LEVEL
  • --exclude=EXCLUSIONS
  • --filter=EXPR

Une règle d'événement est attachée à un canal lors de la création. Si le canal n'est pas spécifié avec l'option --channel, et si la règle d'événement à créer est la première dans son domaine de traçage pour une session de traçage donnée, alors LTTng crée un canal par défaut. Ce canal par défaut est réutilisé dans les invocations ultérieures de la commande lttng-enable-event(1) pour le même domaine de traçage. Pour plus de details : lttng-enable-event(1). Exemple :

lttng enable-event --kernel sched_switch --filter='$ctx.tid == 1988 || $ctx.tid == 1534'

Statut d'une session de trace :

Pour obtenir l'état de la session de traçage en cours, c'est-à-dire ses paramètres, ses canaux, ses règles d'événement et leurs attributs :

lttng list my-session

Créer un canal :

Une fois que une session de traçage est créer, il est possible de créer un canal avec la commande lttng-enable-channel(1). LTTng crée automatiquement un canal par défaut lorsque, pour un domaine de traçage donné, aucun canal n'existe et que la règle du premier événement est créer. Ce canal par défaut est nommé canal0 et ses attributs sont définis à des valeurs par défauts. Pour avoir un canal avec d'autres attribue il faut ajouter des options en ligne de commande lors de la création du canal :

  • --overwrite
  • --buffers-pid
  • --num-subbuf=COUNT
  • --subbuf-size=SIZE
  • --tracefile-size=SIZE
  • --tracefile-count=COUNT
  • --switch-timer=PERIODUS
  • --read-timer=PERIODUS
  • --blocking-timeout=TIMEOUTUS
  • --output=TYPE

Créer un contexte :

Les champs d'enregistrement d'événements dans les fichiers de trace fournissent des informations importantes sur les événements qui se sont produits précédemment, mais parfois un contexte externe peut aider à résoudre un problème plus rapidement. Exemples de zones de contexte :

  • L'ID du processus, l'ID du thread, le nom du processus et la priorité du processus du thread dans lequel l'événement se produit.
  • Le nom d'hôte du système sur lequel l'événement se produit.
  • Les valeurs actuelles de nombreux compteurs de performances possibles en utilisant perf, par exemple :
    • Cycles CPU, cycles bloqués, cycles inactifs et autres types de cycles.
    • Le cache manquant.
    • Instructions de branchement, manques et chargements.
    • Erreur du CPU.

Pour obtenir la liste complète des champs de contexte disponibles, se référer à la commande lttng add-context --list. Certains champs de contexte sont réservés à un domaine de traçage spécifique (noyau Linux ou espace utilisateur).

API ptask :

Ptask est une bibliothèque C pour le développement rapide de tâches périodiques et apériodiques en temps réel sous Linux. L'API est une surcouche de la bibliothèque Pthread dans le but de simplifier la création de threads avec des paramètres de timing typiques, comme les périodes et les délais. Les fonctions Ptask permettent aux programmeurs de rapidement :

  • créer des tâches périodiques et apériodiques ;
  • préciser les contraintes temporelles telles que les périodes et les délais relatifs ;
  • surveiller les dates limites manquées ;
  • surveiller les temps d'exécution moyens et les temps d'exécution dans le pire des cas ;
  • activer des tâches avec des décalages spécifiques ;
  • gérer les groupes de travail ;
  • gérer les changements de mode.

Types :

Les nouveaux types suivants sont définis dans la bibliothèque ptask :

  • ptime : c'est le type utilisé pour les variables temporelles. C'est fondamentalement un raccourci pour un entier long.
  • tspec : ce type est utilisé pour spécifier une heure précise, et il est utilisé par la bibliothèque pour la représentation interne de l'heure. C'est un raccourci pour struct timespec.
  • tpars : ce type de structure est utilisé pour stocker tous les paramètres de la tâche et il est initialisé à la création de la tâche.
  • ptask : ce type est utilisé pour définir le code de tâche. C'est un raccourci pour le vide.

Fonctions système :

void ptask_init(int scheduler, int schedtype, int protocol);

Initialise la bibliothèque ptask, réinitialise l'heure système, définit l'ordonnanceur pour toutes les tâches et le protocole d'accès aux ressources pour tous les sémaphores.

ptime ptask_gettime(int unit);

Renvoie l'heure actuelle (à partir de l'heure de début du système) dans l'unité spécifiée, qui peut être SEC, MILLI, MICRO, ou NANO.

int ptask_getnumcores();

Renvoie le nombre de cœurs disponibles dans le système.

L'API contient également d'autre fonctions qui permettent de créer une tâche, l'activer, attendre une période... mais également des fonctions qui permettent de gérer les paramètres de chaque tâche, tel que la période, la deadline, la priorité... Pour plus de détail se référer à la documentation ptask.


Semaine 4 :

Durant cette semaine, le travail effectuer était l'instrumentation d'une fonction de l'API ptask pour avoir quelque informations sur une tâche périodique. Le but de cela est d'essayer d'adapter LTTng à l'API.

Visualiser une trace :

Format CTF :

Le Common Trace Format (CTF) est un format de trace binaire conçu pour être très rapide à écrire sans compromettre une grande flexibilité. Il permet de générer nativement des traces à partir de n'importe quelle application ou système C/C++. Avec CTF, tous les en-têtes, contextes et champs d'événements écrits dans des fichiers binaires sont décrits à l'aide d'un langage déclaratif de type C personnalisé appelé Trace Stream Description Language (TSDL). TSDL permet de décrire de nombreuses mises en page de flux de traces binaires grâce à la large gamme de types de champs disponibles au CTF. Babeltrace est l'implémentation de référence du Common Trace Format. Il s'agit d'une application de conversion de trace / bibliothèque qui est capable de lire et d'écrire CTF, en supportant presque toutes ses fonctionnalités spécifiées. Babeltrace est également livré avec des liaisons Python 3 pour faciliter l'ouverture d'une trace CTF et l'itération de ses événements en quelques secondes.

Outils :

Babeltrace logo.png
Babeltrace :

Le projet Babeltrace fournit des bibliothèques de lecture et d'écriture de traces, ainsi qu'un convertisseur de traces. Des plugins peuvent être créés pour n'importe quel format de trace afin de permettre sa conversion de/vers un autre format de trace. Le principal format à convertir est le Common Trace Format (CTF). Le format d'entrée par défaut de la commande babeltrace est CTF, et son format de sortie par défaut est un journal texte lisible par l'utilisateur.

Trace compass logo.png
Trace Compass :

Trace Compass est un outil Java permettant de visualiser et d'analyser tout type de logs ou de traces. Son but est de fournir des vues, des graphiques, des métriques, etc. pour aider à extraire des informations utiles des traces, d'une manière plus conviviale et informative que les grandes décharges de texte.

Tâche périodique dans ptask :

Ptask periodic task.png

Documents Rendus

Rapport intermédiaire  : Fichier:Rapport1 P10.pdf.

Rapport final  : Fichier:Rapport P10.pdf.

Slide soutenance finale : Fichier:Pres P10.pdf.

Sources

Le 19/09/2018 :

Le 01/10/2018 :

Le 11/10/2018 :

Le 23/01/2018 :

pas encore :