------------------ ------------------ A réaliser par binôme. Le travail à réaliser est composé de quatre parties.



Documents pareils
Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Débogage de code* Mardi 13 décembre Romaric DAVID Université de Strasbourg - Direction Informatique Pôle HPC. hpc.unistra.

Cours Programmation Système

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

"! "#$ $ $ ""! %#& """! '& ( ")! )*+

SYSTÈME DE GESTION DE FICHIERS

FreeNAS Shere. Par THOREZ Nicolas

Conventions d écriture et outils de mise au point

SYSTÈME DE GESTION DE FICHIERS SGF - DISQUE

I. Introduction aux fonctions : les fonctions standards

Institut Supérieure Aux Etudes Technologiques De Nabeul. Département Informatique

Serveur Acronis Backup & Recovery 10 pour Linux. Update 5. Guide d'installation

TP réseaux 4 : Installation et configuration d'un serveur Web Apache

A -Systèmes de fichiers 1 - FAT vs NTFS

Certificat Informatique et internet Niveau 1 TD D1. Domaine 1 : Travailler dans un environnement numérique évolutif. 1. Généralités : Filière

LOGICIEL ALARM MONITORING

Le meilleur de l'open source dans votre cyber cafe

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

Éléments d'architecture des ordinateurs

Version 7.1_5.1. Release Notes

1. Introduction Création d'une macro autonome Exécuter la macro pas à pas Modifier une macro... 5

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

PARAGON Disk Wiper. Guide de l utilisateur. Paragon Technology GmbH, System Programmierung. Copyright Paragon Technology GmbH

ACTIVITÉ DE PROGRAMMATION

Plan global Outils de développement et compilation. Plan. Objectifs des outils présentés. IDE, GCC/Clang, ASAN, perf, valgrind, GDB.

La mémoire. Un ordinateur. L'octet. Le bit

Généralités sur le Langage Java et éléments syntaxiques.

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Activité 1 : Création et Clonage d'une première machine virtuelle Linux OpenSuSE.

Le générateur d'activités

Seagate Technology LLC S. De Anza Boulevard Cupertino, CA 95014, États-Unis

Laplink PCmover Express La façon la plus facile de transférer vers un nouveau PC Windows

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Principe. Technologies utilisées. 1. Linux et LVM. Les snapshots (instantannés) sous Linux et FreeBSD. Présentation de LVM. Organisation de LVM

Cours Langage C/C++ Programmation modulaire

PC Check & Tuning 2010 Optimisez et accélérez rapidement et simplement les performances de votre PC!

GESTION DES FICHIERS C/UNIX

Programmation système I Les entrées/sorties

NETWORK & SOFTWARE ENGINEERING MANUEL D UTILISATEUR. Logiciel TIJARA. NETWORK AND SOFTWARE ENGINEERING Manuel d'utilisateur "TIJARA" 1

ipra*cool v 1.08 guide de l utilisateur ipra*cool v.1-08 Guide de l'utilisateur ipra*cool v

Chapitre 2. Classes et objets

Algorithmique et Programmation, IMA

Retrospect 7.7 Addendum au Guide d'utilisation

Le langage C. Séance n 4

Programmation C++ (débutant)/instructions for, while et do...while

Tutoriel code::blocks

Interface PC Vivago Ultra. Pro. Guide d'utilisation

But de cette présentation

Virtualisation de Windows dans Ubuntu Linux

Documentation utilisateur, manuel utilisateur MagicSafe Linux. Vous pouvez télécharger la dernière version de ce document à l adresse suivante :

L informatique en BCPST

QUELQUES CONSEILS POUR LA MAINTENANCE DE VOTRE ORDINATEUR

progecad NLM Guide de l'utilisateur

GUIDE D INSTALLATION RAPIDE DEXH264

Algorithmique & Langage C IUT GEII S1. Notes de cours (première partie) cours_algo_lgc1.17.odp. Licence

Cloner un disque dur

Edutab. gestion centralisée de tablettes Android

WINDOWS NT 2000: Travaux Pratiques. -Boîtier partage d'imprimante- Michel Cabaré Janvier 2002 ver 1.0

Annexe : La Programmation Informatique

Analyse de performance, monitoring

Symantec Backup Exec Remote Media Agent for Linux Servers

Livre blanc Mesure des performances sous Windows Embedded Standard 7

Windows Front-End Installation Guide HOPEX V1R1 FR

Symantec Backup Exec 12.5 for Windows Servers. Guide d'installation rapide

Introduction au langage C

Unix/Linux I. 1 ere année DUT. Université marne la vallée

Initiation à la programmation en Python

Programmation système de commandes en C

Qlik Sense Cloud. Qlik Sense Copyright QlikTech International AB. Tous droits réservés.

Partie 7 : Gestion de la mémoire

LibreOffice Calc : introduction aux tableaux croisés dynamiques

Concept de machine virtuelle

CARPE. Documentation Informatique S E T R A. Version Août CARPE (Documentation Informatique) 1

1. Qu'est-ce que SQL? La maintenance des bases de données Les manipulations des bases de données... 5

Installation d un poste i. Partage et Portage & permissions NTFS

MEDIAplus elearning. version 6.6

Création d'un site dynamique en PHP avec Dreamweaver et MySQL

Guide de fonctions du téléphone du système SCI Norstar

Les GPO 2012 server R2 (appliqués à Terminal Serveur Edition)

Programmation C. Apprendre à développer des programmes simples dans le langage C

Service Déposant: Procédure d installation. Page 1. Service déposant. Procédure d installation Version 2.3

Le système GNU/Linux IUP NTIC /11/05

Sauvegarde et restauration d'un système d'exploitation Clonezilla

l'ordinateur les bases

1 Prise en main des machines

3IS - Système d'exploitation linux - Programmation système

LA mémoire principale est le lieu où se trouvent les programmes et les

Messages d'erreurs. Redémarrez votre PC en cliquant sur Démarrer, en sélectionnant ensuite Arrêter puis en cochant Redémarrer

GESTION DES BONS DE COMMANDE

Utilisation et création de la clé USB OSCAR

Service client LSC 1

Eclipse atelier Java

Publipostage avec Open Office Writer et Open Office Calc

1) Installation de Dev-C++ Téléchargez le fichier devcpp4990setup.exe dans un répertoire de votre PC, puis double-cliquez dessus :

Sauvegarde des données du scribe sur disque USB

Guide de référence rapide sur la messagerie vocale d'avaya Distributed Office

DOCUMENTATION VISUALISATION UNIT

Cours de Système : Gestion de Fichiers

Transcription:

------------------ ROJET RCHITECTURE ------------------ Titre : OUTILS POUR LE DIAGNOSTIC SUR UN SYSTÈME LINUX A réaliser par binôme. Le travail à réaliser est composé de quatre parties. Une machine virtuelle Ubuntu avec tous les outils dont vous avez besoin est fournie. Il est conseillé de travailler avec cette machine virtuelle et d'utiliser VirtualBox by Oracle (http://www.virtualbox.org) sur Mac/Windows/Linux pour la lancer. ARECAR nsary www.marecaransary.shost.ca Projet réalisé par ALI ASIC, DIRIL NOEL, MARECAR ANSARY tous étudiant en informatique.

Partie 1 : tester les performances du disque 1.1 L'outil bonnie++ Il s'agit d'un utilitaire qui effectue des tests de performance de votre système de fichiers. Dans un système de fichiers, on y écrit et on y lit. Ces opérations peuvent être effectuées de manière séquentielle, octet par octet ou par blocs de tailles fixes. On peut aussi être amené à lire (dans un fichier) de manière aléatoire, par exemple on lisant le premier octet puis le 1000ème puis le 50ème etc. Ces différentes donnent d'accès impactent sur les performances que l'on peut obtenir c est à dire sur le nombre de kb/s que l'on peut attendre. On observe généralement que les méthodes séquentielles sont plus performantes (en terme de kb/s) que les accès aléatoires par exemple. Nous allons vous demander d'observer, grâce à bonnie++, des performances du système de fichiers, et selon différents schémas d'accès.. Exemple d'un test bonnie++ #./bonnie++ -u root Using uid:0, gid:0. Writing with putc()...done Writing intelligently...done Rewriting...done Reading with getc()...done Reading intelligently...done start 'em...done...done...done... Create files in sequential order...done. Stat files in sequential order...done. Delete files in sequential order...done. Create files in random order...done. Stat files in random order...done. Delete files in random order...done. Version 1.03d ------Sequential Output------ --Sequential Input- --Random- -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks Machine Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP /sec %CP localhost 300M 6000 40 5913 9 4213 10 10407 86 20664 20 1078 13 ------Sequential Create------ --------Random Create-------- -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete files /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP /sec %CP 16 10 93 +++++ +++ 74 63 17 90 +++++ +++ 27 58 localhost,300m,6000,40,5913,9,4213,10,10407,86,20664,20,1078.1,13,16,10,93,+++++,+++,74,63,1 7,90,+++++,+++,27,58 La dernière ligne est au format CSV (c'est un format pour tableurs comme Exel ou Calc de Libreoffice)

Questions Quelle est la taille du fichier qui a été utilisée dans le précédent exemple? (Hint : lire la page du manuel de bonnie++) D'après la page de manuel de bonnie++, on remarque que la taille du fichier du précédent exemple est de 300Mo. Lancer la commande précédente dans votre machine virtuelle Ubuntu. c) Interpréter la dernière ligne de l'exemple précédent i.e. les résultats expérimentaux du point b) (à quoi correspondent les valeurs obtenues) La dernière ligne est au format CSV (c'est un format pour tableurs comme Exel ou Calc de Libreoffice). La dernière ligne nous donne des informations sur la vitesse de lecture (en K/sec) et du pourcentage du processus utilisé pour chaque sortie (input/output). 3000M Correspond à la taille du fichier utilisé pour le test Ecriture du fichier 6000 Par caractère, Bonnie a enregistré une vitesse de sortie de 80 K /seconde. 40 Ce travail a consommé 99% du temps du CPU. Lecture du fichier 5913 Par caractère, Bonnie a enregistré une vitesse d'entrée de 549 k/s 9 Ce travail a consommé 99% du temps du CPU Processus de recherche 4213 Le processus de recherche aléatoire à durée 15397 sec 10 Ce processus a utilisé 228% du temps du CPU Files 16 Le système indique la présence de 16 fichiers (ou pas) Création séquentielle La création séquentielle a duré 13788 sec et a demandé 81% du temps du CPU 17575 C est le temps que le système a pris lors de la suppression des fichiers et cela a demandé 75% du temps du CPU Création aléatoire 13780 La création séquentielle a duré 13788 sec et a demandé 81% du temps du CPU 17684 C est le temps que le système a pris lors de la suppression des fichiers et cela a demandé 75% du temps du CPU

Les résultats suivant sont autres que les temps de latences pour chacun des processus. d) Relancer un test pour évaluer les performances du répertoire /tmp Qu'observez-vous? bonnie++ -d tmp -u root -s300 -r2 Normalement votre HOME directory correspond à un disque qui est sur le réseau et /tmp un répertoire qui est physiquement attaché à votre machine. Nous devrions obtenir des performances différentes car généralement, accéder à un disque réseau coûte "plus cher" qu'accéder à une partition locale. e) Montez une clé USB (attention, cela peut être technique de rendre visible cette clé à la machine virtuelle) et refaite un test pour évaluer les performances de la clé USB. On peut voir que les résultats au niveau des différentes vitesses enregistrées sont beaucoup moins bons puisque le test a été effectué sur une clé USB qui n'appartient donc pas physiquement à la machine. En revanche on peut voir que le travail du CPU est moins important que sur les précédents tests. f) Faites une synthèse de tous les résultats expérimentaux. On peut apercevoir que les tests sur le HOME directory et sur le répertoire /tmp ont des résultats qui sont assez proche mais diffèrent, cependant le test sur la clef USB présente des résultats bien plus faibles.

1.2 L'outil sysstat On veut comparer les résultats expérimentaux fournis par bonnie++ avec ceux qui sont fournis par les outils Sysstat (http://sebastien.godard.pagesperso-orange.fr/documentation.html). Sysstat est en faîte un ensemble de programmes qui permet non seulement de récupérer de l'information sur les performances des disques mais aussi sur les performances du processeur, de la mémoire, du réseau. Avant toute chose, faites un man iostat et un man pidstat qui sont les deux outils étudiés. a) Première expérimentation : L'outil sysstat a)./iostat (PASS1)./bonnie++ -u root./iostat (PASS2) Meilleur rapidité d ecriture et de lecture que sur PASS1 les 2 valeurs en correspojndent pas b)./pidstat -d

./bonnie++ -u root

./pidstat -d On observe que lors de notre deuxième lancement de pidstat les différents processus prennent plus de RAM

Partie 2 : débogage avec ddd Un débogueur (ou débogueur, de l'anglais debugger) est un logiciel qui aide un développeur à analyser les bugs d'un programme. Pour cela, il permet d'exécuter le programme pas-à-pas, d'afficher la valeur des variables à tout moment, de mettre en place des points d'arrêt sur des conditions ou sur des lignes du programme... Les outils installés dans votre machine virtuelle Ubuntu sond ddd (outil graphique), gdb et lldb (outils en mode texte). On lance ddd en tapant ddd sous le prompt Linux. Le programme C que l'on va tracer doit avoir été compilé avec l'option -g (g comme debugging), sinon il ne sera pas possible de travailler avec ces outils. La grande majorité des débogueurs offrent des fonctionnalités similaires à celles qui suivent : a) Outils pour stopper (mettre en pause) l'exécution du programme o commande d'arrêt manuel : le programmeur peut décider à tout moment de stopper l'exécution o point d'arrêt : placé à un endroit spécifique du programme (généralement dans le code source), il indique au débogueur d'arrêter l'exécution lorsqu'elle atteindra cet endroit o point d'arrêt conditionné : comme le point d'arrêt, mais avec une condition supplémentaire (comme le nombre de passages sur ce point d'arrêt par exemple) o point d'observation (watch) : permet d'arrêter l'exécution du programme sur la condition de la modification d'une variable b) Outils pour piloter l'exécution du programme o pas-à-pas : exécution instruction par instruction o pas-à-pas sommaire : une instruction est exécutée, dans le programme principal, à chaque fois que le programmeur le demande o pas-à-pas détaillé : comme le pas-à-pas sommaire, sauf que le pas-à-pas entre aussi dans les fonctions o avec cadencement : à intervalles périodiques, une instruction est exécutée (cela permet de ralentir l'exécution du programme afin qu'elle puisse être suivie de près par l'œil humain) o redémarrage de la fonction courante (drop frame) : abandon de l'exécution actuelle de la fonction courante et démarrage d'une nouvelle exécution de la fonction courante o retour en arrière : revenir à l'instruction précédente, en retrouvant l'état précédent (fonctionnalité assez rare) c) Outils pour observer l'état du programme o observation d'une variable o observation d'une zone mémoire o observation d'un registre du microprocesseur o observation de la pile d'appel (backtrace) o observation du code source avec point d'exécution actuel o observation du code assembleur (sauf langage interprété) avec point d'exécution actuel o trace : permet d'observer des informations en différé, sans stopper l'exécution du programme En outre, le débogueur permet généralement de modifier l'état du programme, lorsque son exécution est stoppée : o modification d'un registre o modification d'une variable o modification d'une zone mémoire Votre travail : nous allons travailler sur le code source td09.c qui est dans le répertoire M2101.

Questions : Ce programme comporte des erreurs. Essayez de les repérez, ne les corrigez pas. Le but de ce programme est de remplir un tableau avec des valeurs, puis de faire des modifications de ces valeurs (multiplier par deux, puis ajouter 1). Check list : o Compilez le programme, et exécutez-le avec le débogueur ddd. Le listing du programme doit s'afficher. o Commencez, avant de faire tourner le programme par insérer un point d'arrêt au début du main, un point d'arrêt dans la toute première boucle, un point d'arrêt dans la fonction fact.

o Faites afficher la fenêtre de données de ddd. En faisant un clic droit, faites afficher toutes les variables du programme. Que se passe-t-il si on essaye d'afficher NUM? NUM a été déffinie au début du programme et doit retourner 6. Or dans ce cas ce n es pas cela! Que remarque-t-on quand on essaye d'afficher la variable i de la fonction fact?

La valeur de i retourner depend de l'endroit ou on demande de l'afficher. o Remarquez la différence d'affichage entre b et c. À quoi cela peut-il être dû?

L un est un tableau mais un tableau est un pointeur. L autre est uniquement un pointeur. o Dans un terminal, testez le programme. Vérifiez qu'il ne fonctionne pas. Il ne fonctionne pas o Commencez l'exécution du programme (bouton run ou menu équivalent). Après le premier arrêt, utilisez le bouton step pour avancer pas à pas dans le programme. Regardez évoluer peu à peu les valeurs des variables. Que remarque-t-on sur la valeur affichée de i lorsqu'on rentre dans l'évaluation de la fonction fact? Le i du main est stoppé et le i de la fonction débute à 12 puis et puis problème dans la boucle de la fonction. (i=n au lieu de i<=n). o Quelle est la première erreur? Corrigez-là, recompilez (de l'intérieur du débogueur, avec le bouton make).

Les entiers du main sont à l extérieur. Dans fact et dans sa boucle il est mis i=n or c est tant que i<=n. o Refaites une exécution pas-à-pas. Vérifiez que la fonction renvoie maintenant la bonne valeur. Que constate-t-on dans l'affichage du tableau b? Trouvez la deuxième erreur. La valeur ne change pas o Faites afficher en partant de la zone de données le contenu pointé par c. Quelle est la troisième erreur? Corrigez-la. «*c=b;» o Quelle est l'adresse du premier élément du tableau b? o Surveillez pas-à-pas l'exécution de la deuxième boucle du programme (qui multiplie par 2). Que remarque-t-on sur le tableau b? Expliquez. A compelter c[i] va prendre la valeur d elle-même multiplié par 2 tant que i est inférieur à 6.

o Il serait plus simple de faire afficher c comme un tableau de 6 éléments. Utilisez la syntaxe donnée dans le cours pour le faire. Vérifiez que les valeurs sont changées aussi bien dans c que dans b. o La dernière boucle utilise l'arithmétique des pointeurs : un pointeur (c) change de valeur et pointe tour à tour. Elle comporte une erreur. Trouvez-la et corrigez-la o Est-il correct d'affecter une valeur à *d? Pourquoi? Bonus Pour celles et ceux qui veulent aller plus loin... o Réécrivez le programme précédent en faisant de b non pas un tableau statique, mais un tableau alloué dynamiquement. N'oubliez pas de libérer l'espace mémoire à la fin du tableau. o Est-il possible de lire dans ce tableau après avoir libéré la mémoire? o Après avoir libéré la mémoire (à la fin du programme), créez un nouveau tableau d'entiers (de taille similaire mais pas identique). Que constate-t-on?

Partie 3 : tester les performances du processeur Performance Application Programming Interface (PAPI) est une interface portable (sous la forme d'une librairie) vers les compteurs de performance des processeurs. Un compteur de performance est un dispositif matériel (du silicium) dédié à l'observation de certains évènements de très bas niveau (internes au processeur). Il peut s'agir du nombre d'instructions réellement exécutées, du nombre de défaut de caches... L'intérêt des compteurs de performance est d'être une méthode d'observation non intrusive parce qu'elle est assurée au niveau matérielle et pas au niveau logiciel. Certains processeurs font de l'exécution spéculative c est à dire que pour exécuter une conditionnelle ils choisissent d'exécuter la branche pour laquelle la condition est vérifiée... Mais quand le processeur détecte que la condition est fausse en réalité, alors le processeur arrête l'instruction précédente pour exécuter la branche pour laquelle la condition est fausse. Ainsi, toute instruction qui commence... n'aboutit pas forcément. Les compteurs de performance permettent d'observer ce phénomène. Le monitoring de certains évènements permet de corréler la structure du code c est à dire d'estimer l'efficacité de la mise en correspondance de ce code avec l'architecture. Le fichier que l'on étudie est le fichier papi.c qui se trouve dans le répertoire M2101. Votre travail : a) Faites un commentaire de cet exemple de base qui montre comment utiliser l'interface de haut niveau de PAPI Cet exemple nous permet de se familiariser avec les fonctions de PAPI comme par exemple s'arrêter sur un ensemble d'évènement ou encore compter et lire les instructions ainsi que les cycles lors de ces évènements. -Au départ (l 37) déclaration et initialisation de notre ensemble d'évènements, La première fonction utilisée (l 53 : PAPI_library_init) initialise la bibliothèque et compare le numéro de version du fichier d'entête à la version de la bibliothèque, Si les 2 numéros ne sont pas compatibles la variable retval stock la trace du numéro et nous nous retrouvons donc avec une erreur dans le programme -Ensuite la seconde fonction PAPI_num_counters renvoie la longueur maximale du tableau de valeurs pour les fonctions de haut niveau. Cette valeur équivaut au nombre de compteurs de performances gérer par le système. -Si le programme ne retourne pas d erreur pendant la lecture de l'évènement alors il lit le nombre d'instructions exécutées et de cycles utilisés pour l'évènement sélectionné (ici l'addition (l 89)) grâce à une autre fonction qui est PAPI_read_counters) -Ensuite le programme lance la fonction PAPI_accum_counters (l 102) qui permet d'accumuler les valeurs des compteurs avec les valeurs dans le tableau, avant de réinitialiser ces compteurs. -Pour finir, le programme lance la fonction PAPI_stop_counters (l 114) qui permet de lire puis arrêter les compteurs. Dans notre cas le programme lit le nombre d'instructions exécutées et le nombre de cycles utilisés pour des multiplications.

b) Quels sont les résultats? gcc -Wall papi.c -lpapi &&./sorti.out Que signifient-ils? Le lancement du programme nous permet de savoir que le système possède 5 compteurs de performances. Pour le premier évènement (additions), le programme a enregistré 53130 instructions executées, et 95541 cycles utilisés. c) Faites une série d'expériences en modifiant la valeur de la constante THRESHOLD, par exemple en doublant la valeur de celle-ci à chaque fois. Est-ce que les valeurs des compteurs de performance doublent à chaque fois? Non Pourquoi? Dans la consigne il est dit : «Certains processeurs font de l'exécution spéculative c est à dire que pour exécuter une conditionnelle ils choisissent d'exécuter la branche pour laquelle la condition est vérifiée... Mais quand le processeur détecte que la condition est fausse en réalité, alors le processeur arrête l'instruction précédente pour exécuter la branche pour laquelle la condition est fausse. Ainsi, toute instruction qui commence... n'aboutit pas forcément. Les compteurs de performance permettent d'observer ce phénomène.» d) Pour les binômes les plus avancés (question bonus), modifiez le code de papi.c pour observer les défauts de cache sur le cache L1. (Voir avec votre enseignant pour des explications complémentaires si besoin). Refaites les questions a) b) c). Performance Application Programming Interface (PAPI) est une interface de programmation portable (sous la forme d'une bibliothèque logicielle) permettant d'accéder aux compteurs matériels spécifiques aux microprocesseurs modernes. PAPI est utilisé pour collecter des informations de bas niveau (telles que le nombre d'opérations en virgule flottantes FLOPS par seconde, le nombre de cache misses durant l'exécution d'un code, etc..). PAPI est interfacé avec les systèmes d'exploitation de type UNIX. La bibliothèque PAPI est actuellement capable d'accéder les compteurs matériel de la plupart des processeurs modernes. La liste des processeurs non reconnu ne cesse de diminuer.

Partie 4 : surveiller les appels système avec strace strace est un outil de débogage sous Linux pour surveiller les appels système utilisés par un programme, et tous les signaux qu'il reçoit. L'utilisation la plus courante est de lancer un programme en utilisant strace, qui affiche une liste des appels système faits par le programme. Par exemple, utiliser strace peut révéler que le programme tente d'accéder à un fichier qui n'existe pas ou qui ne peut pas être lu. Une autre utilisation est d'utiliser l'option -p pour le rattacher à un programme lancé. C'est utile lorsqu'un programme ne répond plus, et peut révéler, par exemple, que le processus est bloqué car il attend de faire une connexion réseau. Comme strace ne détaille que les appels système, il ne peut pas être utilisé comme un débogueur de code, tel que Gdb. Il reste cependant plus simple à utiliser qu'un débogueur de code, et est un outil extrêmement utile pour les administrateurs système. Exemples concrets d'utilisation : > strace -Ff -tt <program> <arguments> 2>&1 tee strace-<program>.log qui va vous permettre de générer un fichier de log à partir duquel vous pourrez faire une analyse. > strace -Ff -tt -p <PID> 2>&1 tee strace-<program>.log qui va vous permettre de tracer un PID (process identifier) particulier. Votre travail : Compilez le programme suivant : #include <stdio.h> void main() { printf("hi\n"); }

Utiliser strace pour Lister tous les appels systèmes faits par votre programme. On tape sur le terminal : strace Ff tt test test est le nom de notre exécutable Quel est l'appel Système qui revient le plus? Pouvez-vous expliquer en quoi consiste cet appel Système (attention, c'est dur!)? L'appel système qui apparaît le plus souvent est mmap2(). Il permet d'établir une projection en mémoire des fichiers ou périphériques. Il est donc utilisé pour l'allocation de mémoire. Cet appel système sert juste a allouer un espace mémoire. Mmap 1 : Établir/supprimer une projection en mémoire (map/unmap) des fichiers ou des périphériques. L'appel système mmap2() réalise la même opération que mmap sauf que l'argument final spécifie un décalage dans le fichier en unité de 4096 octets plutôt qu'en octets comme cela est fait par mmap.

Compilez le programme suivant : #include <stdio.h> #include <unistd.h> void main() { int i; for(i=0;i<12;i++){ printf("hello there!\n"); sleep(1); printf("goodbye\n"); } } --Video--

Trouver l'option de strace qui va vous permettre d'observer le temps passé dans chaque appel système. Lancer strace avec cette option sur votre exemple et dites quel est l'appel Système qui prend le plus de temps -c : compte le temps, les appels et les erreurs pour chaque appelles système. -r : Sa permet d avoir pour chaque appel système le temps qu il a passé. On appelle cela en anglais le timestamp relatif. -T :temps passé pour chaque appels système. L'option qui permet d'observer le temps passé sur chaque appel est «-T». Soit celui qui prend le plus de temps est nanosleep. asc95@test:~/workspace $ gcc -Wall test.c -o t3 test.c:4:6: warning: return type of main is not int [-Wmain] void main () ^ asc95@test:~/workspace $ strace -T./t3

execve("./t3", ["./t3"], [/* 70 vars */]) = 0 <0.000323> brk(0) = 0x1b1b000 <0.000036> access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) <0.000063> mmap(null, 8192, PROT_READ PROT_WRITE, MAP_PRIVATE MAP_ANONYMOUS, -1, 0) = 0x7f0c5e7f9000 <0.000031> access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) <0.000048> open("~/.c9/local/lib/tls/x86_64/libc.so.6", O_RDONLY O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000074> open("~/.c9/local/lib/tls/libc.so.6", O_RDONLY O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000056> open("~/.c9/local/lib/x86_64/libc.so.6", O_RDONLY O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000068> open("~/.c9/local/lib/libc.so.6", O_RDONLY O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000055> open("/etc/ld.so.cache", O_RDONLY O_CLOEXEC) = 3 <0.000057> fstat(3, {st_mode=s_ifreg 0644, st_size=59193,...}) = 0 <0.000041> mmap(null, 59193, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f0c5e7ea000 <0.000040> close(3) = 0 <0.000044> access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) <0.000054> open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY O_CLOEXEC) = 3 <0.000059> read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\37\2\0\0\0\0\0"..., 832) = 832 <0.000046> fstat(3, {st_mode=s_ifreg 0755, st_size=1845024,...}) = 0 <0.000040> mmap(null, 3953344, PROT_READ PROT_EXEC, MAP_PRIVATE MAP_DENYWRITE, 3, 0) = 0x7f0c5e213000 <0.000043> mprotect(0x7f0c5e3ce000, 2097152, PROT_NONE) = 0 <0.000043> mmap(0x7f0c5e5ce000, 24576, PROT_READ PROT_WRITE, MAP_PRIVATE MAP_FIXED MAP_DENYWRITE, 3, 0x1bb000) = 0x7f0c5e5ce000 <0.000055> mmap(0x7f0c5e5d4000, 17088, PROT_READ PROT_WRITE, MAP_PRIVATE MAP_FIXED MAP_ANONYMOUS, -1, 0) = 0x7f0c5e5d4000 <0.000058> close(3) = 0 <0.000171> mmap(null, 4096, PROT_READ PROT_WRITE, MAP_PRIVATE MAP_ANONYMOUS, -1, 0) = 0x7f0c5e7e9000 <0.000068> mmap(null, 8192, PROT_READ PROT_WRITE, MAP_PRIVATE MAP_ANONYMOUS, -1, 0) = 0x7f0c5e7e7000 <0.000037> arch_prctl(arch_set_fs, 0x7f0c5e7e7740) = 0 <0.000034> mprotect(0x7f0c5e5ce000, 16384, PROT_READ) = 0 <0.000041> mprotect(0x600000, 4096, PROT_READ) = 0 <0.000013> mprotect(0x7f0c5e7fb000, 4096, PROT_READ) = 0 <0.000049> munmap(0x7f0c5e7ea000, 59193) = 0 <0.000049> fstat(1, {st_mode=s_ifchr 0620, st_rdev=makedev(136, 1),...}) = 0 <0.000040> mmap(null, 4096, PROT_READ PROT_WRITE, MAP_PRIVATE MAP_ANONYMOUS, -1, 0) = 0x7f0c5e7f8000 <0.000038> write(1, "Hello there\n", 12Hello there ) = 12 <0.000049> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000034> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000028> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000026> nanosleep({1, 0}, 0x7fffcc311f70) = 0 <1.000168> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000065> write(1, "Hello there\n", 12Hello there ) = 12 <0.000044> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000032> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000051> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000037> nanosleep({1, 0}, 0x7fffcc311f70) = 0 <1.000110> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000046> write(1, "Hello there\n", 12Hello there ) = 12 <0.000044> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000033> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000036> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000038> nanosleep({1, 0}, 0x7fffcc311f70) = 0 <1.000146> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000036> write(1, "Hello there\n", 12Hello there ) = 12 <0.000040> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000021> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000032> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000053> nanosleep({1, 0}, 0x7fffcc311f70) = 0 <1.000173> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000059> write(1, "Hello there\n", 12Hello there

) = 12 <0.000021> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000025> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000032> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000044> nanosleep({1, 0}, 0x7fffcc311f70) = 0 <1.000170> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000046> write(1, "Hello there\n", 12Hello there ) = 12 <0.000038> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000051> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000060> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000061> nanosleep({1, 0}, 0x7fffcc311f70) = 0 <1.000102> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000050> write(1, "Hello there\n", 12Hello there ) = 12 <0.000039> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000024> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000039> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000030> nanosleep({1, 0}, 0x7fffcc311f70) = 0 <1.000159> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000507> write(1, "Hello there\n", 12Hello there ) = 12 <0.000036> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000048> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000148> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000084> nanosleep({1, 0}, 0x7fffcc311f70) = 0 <1.000169> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000066> write(1, "Hello there\n", 12Hello there ) = 12 <0.000045> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000031> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000029> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000039> nanosleep({1, 0}, 0x7fffcc311f70) = 0 <1.000156> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000059> write(1, "Hello there\n", 12Hello there ) = 12 <0.000019> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000025> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000074> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000080> nanosleep({1, 0}, 0x7fffcc311f70) = 0 <1.000134> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000025> write(1, "Hello there\n", 12Hello there ) = 12 <0.000012> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000006> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000076> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000009> nanosleep({1, 0}, 0x7fffcc311f70) = 0 <1.000124> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000045> write(1, "Hello there\n", 12Hello there ) = 12 <0.000057> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000054> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000067> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000045> nanosleep({1, 0}, 0x7fffcc311f70) = 0 <1.000162> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000049> exit_group(9) =? +++ exited with 9 +++ asc95@test:~/workspace $

Expliquer L'appel système qui prend le plus de temps est «nanosleep». Car le «sleep» va mettre en pause le processus tandis que les autres appels systèmes sont exécutés à une vitesse non perçu par l Homme. Même question avec le programme : #include <stdio.h> #include <unistd.h> void main() { int i=0; do { printf("hello there!\n"); sleep(1); printf("goodbye\n"); } while(i>12); } asc95@test:~/workspace $ strace -T./t3 execve("./t3", ["./t3"], [/* 70 vars */]) = 0 <0.000287> brk(0) = 0x22dc000 <0.000011> access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) <0.000029> mmap(null, 8192, PROT_READ PROT_WRITE, MAP_PRIVATE MAP_ANONYMOUS, -1, 0) = 0x7f91d047c000 <0.000011> access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) <0.000028> open("~/.c9/local/lib/tls/x86_64/libc.so.6", O_RDONLY O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000017>

open("~/.c9/local/lib/tls/libc.so.6", O_RDONLY O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000012> open("~/.c9/local/lib/x86_64/libc.so.6", O_RDONLY O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000015> open("~/.c9/local/lib/libc.so.6", O_RDONLY O_CLOEXEC) = -1 ENOENT (No such file or directory) <0.000013> open("/etc/ld.so.cache", O_RDONLY O_CLOEXEC) = 3 <0.000045> fstat(3, {st_mode=s_ifreg 0644, st_size=59193,...}) = 0 <0.000015> mmap(null, 59193, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f91d046d000 <0.000013> close(3) = 0 <0.000009> access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) <0.000029> open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY O_CLOEXEC) = 3 <0.000036> read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\37\2\0\0\0\0\0"..., 832) = 832 <0.000012> fstat(3, {st_mode=s_ifreg 0755, st_size=1845024,...}) = 0 <0.000017> mmap(null, 3953344, PROT_READ PROT_EXEC, MAP_PRIVATE MAP_DENYWRITE, 3, 0) = 0x7f91cfe96000 <0.000016> mprotect(0x7f91d0051000, 2097152, PROT_NONE) = 0 <0.000018> mmap(0x7f91d0251000, 24576, PROT_READ PROT_WRITE, MAP_PRIVATE MAP_FIXED MAP_DENYWRITE, 3, 0x1bb000) = 0x7f91d0251000 <0.000022> mmap(0x7f91d0257000, 17088, PROT_READ PROT_WRITE, MAP_PRIVATE MAP_FIXED MAP_ANONYMOUS, -1, 0) = 0x7f91d0257000 <0.000021> close(3) = 0 <0.000009> mmap(null, 4096, PROT_READ PROT_WRITE, MAP_PRIVATE MAP_ANONYMOUS, -1, 0) = 0x7f91d046c000 <0.000013> mmap(null, 8192, PROT_READ PROT_WRITE, MAP_PRIVATE MAP_ANONYMOUS, -1, 0) = 0x7f91d046a000 <0.000010> arch_prctl(arch_set_fs, 0x7f91d046a740) = 0 <0.000011> mprotect(0x7f91d0251000, 16384, PROT_READ) = 0 <0.000022> mprotect(0x600000, 4096, PROT_READ) = 0 <0.000068> mprotect(0x7f91d047e000, 4096, PROT_READ) = 0 <0.000103> munmap(0x7f91d046d000, 59193) = 0 <0.000129> fstat(1, {st_mode=s_ifchr 0620, st_rdev=makedev(136, 1),...}) = 0 <0.000034> mmap(null, 4096, PROT_READ PROT_WRITE, MAP_PRIVATE MAP_ANONYMOUS, -1, 0) = 0x7f91d047b000 <0.000050> write(1, "Hello there\n", 12Hello there ) = 12 <0.000046> rt_sigprocmask(sig_block, [CHLD], [], 8) = 0 <0.000032> rt_sigaction(sigchld, NULL, {SIG_DFL, [], 0}, 8) = 0 <0.000075> rt_sigprocmask(sig_setmask, [], NULL, 8) = 0 <0.000008> nanosleep({1, 0}, 0x7fffd269a570) = 0 <1.000123> write(1, "Goodbye!\n", 9Goodbye! ) = 9 <0.000040> exit_group(9) =? +++ exited with 9 +++ asc95@test:~/workspace $

C est toujours nanosleep Même raisonnement que pour le programme précédent Dernier exercice : Nous voulons visualiser avec l'outil Linux totem le film playfilm.avi - Pour cela je lance la commande : > strace -o totem.txt totem playfilm.avi En examinant le fichier totem.txt, faites un diagnostic de ce qui s'est passé. On a plus de 3 millions de lignes! > Brk(0)=0x99ab000 > access()=-1!!!! > mmap2() =0xb76f000 > access()=-1!!!! > open est toujours à 3 > fatat64()=0 > mmap2()=0xb76f000 > close(3)=0 > access()=-1!!!! > open est toujours à 3 > read()=512 >

On a tenté d ouvrir un fichier vidéo et movie maker c est lancé. Sauf que le fichier.avi n existe pas. Quelles sont les lignes de ce fichier qui vous permettent de faire le diagnostic? Le début Strace Strace est un utilitaire permettant de tracer/suivre les appels systèmes. Les appels systèmes sont les interfaces fondamentales entre les applications et le noyau. Généralement, ils ne sont pas appelés directement, mais via des wrappers de la glibc. Par exemples : fstat, mmap, open, close,... En utilisant Strace, on peut intercepter ces appels systèmes pour un processus ou une commande donnée. Strace est donc un outil puissant de dépannage pour tous les administrateurs et utilisateurs Unix/Linux.