From 83980486c36dfe73bd7d63a78279525e2cedd46b Mon Sep 17 00:00:00 2001 From: haller Date: Fri, 8 Oct 2004 10:50:44 +0000 Subject: Ajout d'une documentation sur les outils de développement --- d/dev/tools/Makefile | 10 ++ d/dev/tools/tools.txt | 353 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 363 insertions(+) create mode 100644 d/dev/tools/Makefile create mode 100644 d/dev/tools/tools.txt (limited to 'd/dev/tools') diff --git a/d/dev/tools/Makefile b/d/dev/tools/Makefile new file mode 100644 index 0000000..95ac718 --- /dev/null +++ b/d/dev/tools/Makefile @@ -0,0 +1,10 @@ +DOC = tools.html + +doc: $(DOC) + +%.html: %.txt + aft $< + test -r $<-TOC && aft $< || true + +clean: + rm -f $(DOC) *.txt-TOC *.bak *~ diff --git a/d/dev/tools/tools.txt b/d/dev/tools/tools.txt new file mode 100644 index 0000000..e266d16 --- /dev/null +++ b/d/dev/tools/tools.txt @@ -0,0 +1,353 @@ +*Title: Outils utiles pour coder +*Author: Nicolas Haller + +*TOC + +* Introduction + +Pour coder au Robot et en général, il existe certain outils, certain sont +indispensable. Je vais ici montrer comment fonctionne quelques outils que +j'utilise personnellement, le but n'étant pas de faire un guide complet mais +plutôt une présentation assez détaillé pour les utiliser d'outils utiles. + +* Editeurs + +** Vim + +Vim est un éditeur de texte très puissant qui peut faire beaucoup de chose dont +du C. + +*** Fonctionnement + +taper vim dans un bash. Attention, pour coder en C il est nécessaire de modifier +quelques options dans le .vimrc, notamment + * syntax on ,pour avoir de la couleurs en codant + * set shiftwidth=4 ,pour une indentation de 4 caractères(voir les + standards du robot) + +*** Quelques commandes + +Pour vim et pour coder, quelques commandes + * :q quitter + * :x sauvegarder et quitter + * :w enregistré + * :e ouvrir + * == pour indenter une ligne + * =G indente du curseur à la fin du fichier + * :make exécute le makefile et affiche les erreurs éventuelles + * :cc aller à l'erreur actuelle + * :cn aller à l'erreur suivante + * :copen ouvre la liste des erreurs + * :cclose la ferme + +Y'en a plein d'autre mais si vous utilisez vim, elles viendront vite. + +* Compilateurs + +** Pour le C + +Pour coder en C, gcc, le GNU C Compiler. C'est un compilateur très puissant +avec un beaucoup d'option. + +** Pour le C++ + +Pour coder en C il faut juste remplacer gcc par g++. + +** Comment ça marche +Il suffit de taper gcc(ou g++) et le nom du fichier source(on ne met pas +les headers.) Si il n'y a qu'un seul fichier source, ça marche, et il y aura +comme résultat un fichier a.out, bon a part pour faire un Hello World, ça sert +à rien, pour des projets plus conséquent, le Makefile est tout indiqué. + +Si la compilation foire, le compilateur fera en sorte d'afficher les erreurs +avec le nom des fichiers et les lignes ou se trouve à 3 lignes près l'erreur. +Il se peut aussi qu'il annonce des warnings, c'est pas bon!! Les warnings +portent bien leurs noms, et généralement, laisser des warnings dans un programme +est suicidaire, donc, à éviter. + +** quelques options + +Dans la ligne de commandes gcc, il y a quelques options et librairies indispensables: + * -o permet de nommer le fichier exécutable, sinon il s'appelle a.out + * -W et -Wall pour voir tout les warnings qui pourrait passer + * -g permet d'ajouter les info de debuggage + * -Olevel Permet d'optimiser le programme plus level est grand plus c'est optimiser + (level 3 max) + * -Os permet d'optimiser le code pour obtenir un exécutable plus petit + * -lm permet d'inclure la librairie mathématique + +* make + +La commande make est une commande très puissante qui fait ce qu'on lui +dit de faire. Elle est intelligente pour certaine action mais pour des +choses un peu poussé, elle regarde dans un Makefile ce quel doit faire. +C'est avec elle que sont compiler la plupart des programmes. + +** Comment ça marche + +taper make et si il y a un makefile qui va bien ça s'exécute. +make tente de faire de la divination, pour un programme composé d'un +code source, il suffit de taper make nomdufichiersansextension. +Sinon, l'écriture d'un makefile est obligatoire. + +** Le makefile + +Le makefile s'appelle Makefile(n'oublier pas la majuscule, c'est mieux). +Dans le fichier ont trouve des variables et des règles. Les variables +sont défini et utilisé comme dans les scripts bash, mais certaines +variables sont standard et nous servirons plus tard. +Pour faire simple, un makefile pour compiler un programme en C ressemble +à ça. +^<< + +barbecue:main.o merguez.o thermostat.o + gcc -o barbecue main.o merguez.o thermostat.o + +^>> + +barbecue est le nom de la cible, main.o merguez.o thermostat.o les +"dépendances", la ligne du dessous qui commence obligatoirement par une +tabulation est la ou les actions à exécuter. +make étant très intelligent, il va essayer de voir si il peut résoudre +les dépendances, ici, il va compiler les sources pour produire les .o requis. +Cela dit pour un projet plus important, le Makefile peut contenir +plusieurs cible et plusieurs actions, pour éviter de réécrire les choses +plusieurs fois, il y a les variables. +Les variables fonctionnent comme pour les scripts bash à peu près. +Pour reprendre l'exemple au dessus on pourrait marquer +^<< + +OBJECTS=main.o merguez.o thermostat.o + +barbecue:${OBJECTS} + gcc -o $@ $^ + +^>> + +Les fichiers object sont dans la variable OBJECTS qui est utilisé dans la +ligne de commande gcc, $@ est une variable spéciale qui correspond au +nom de la cible et $^ en est une autre indiquant les dépendances. + +Avec ça, make peut compiler un projet entier, comme il est très +intelligent, il regardera ce qu'il a besoin de faire, c'est-à-dire qu'il +ne recompilera ce qui est nécessaire, faite le test, compiler quelque +chose avec make et refaite le. + +^<< + +nicolas@hermes:~/testmake$ ls +casertarien.c +nicolas@hermes:~/testmake$ make casertarien +cc casertarien.c -o casertarien +nicolas@hermes:~/testmake$ make casertarien +make: « casertarien » est à jour. + +^>> + +L'exemple précédent montre également une chose, c'est ce qu'exécute make +lorsqu'on ne lui dit rien. On voit qu'il utilise cc comme compilateur et +qu'il n'utilise rien. Vous allez me dire, m'en fiche je fais un +Makefile, certes, mais les dépendances en .o, il les faits tout seul +donc, il faut lui dire quoi faire, et pour cela, il existe les variables +spéciales. + +** Quelques variables utiles + +Pour dire à make comment faire ses trucs intelligents, certaines +variables sont bien utiles, en voici quelques une: + * CC permet de définir le compilateur C(exemple: CC=gcc) + * CLIBS permet de définir les librairie C à utiliser (exemple:CLIBS=-lm) + * CFLAGS qui permet de définir les flags(exemple CFLAGS=-g -W -Wall) + + +Pour le C++ il y a les équivalents + * CXX pour le compilo C++ + * CXXLIBS pour les librairies C++ + * CXXFLAGS pour les flags C++ +Mais il en existe bien d'autre. + + +En définitive, notre Makefile pour un programme en C pourrait ressembler +à ça: + +^<< + +CC=gcc +CLIBS=-lm +CFLAGS=-g -W -Wall -pipe + +barbecue:main.o merguez.o thermostat.o + ${CC} ${CLIBS} ${CFLAGS} -o $@ $^ + +^>> + +Et on aura à l'écran: + +^<< +nicolas@hermes:~/testmake/barbecue$ make +gcc -g -W -Wall -pipe -c -o main.o main.c +gcc -g -W -Wall -pipe -c -o thermostat.o thermostat.c +gcc -g -W -Wall -pipe -c -o merguez.o merguez.c +gcc -lm -g -W -Wall -pipe -o barbecue main.o thermostat.o merguez.o +^>> +Voila un beau Makefile qui comme le dirais Ni, permet de briller en +société. + +* Le débugueur + +Pour debugguer le jolie code qui marche pas comme prévu, il y a le +débuggueur GDB(pour GNU Debbuger, ouais ils ont vachement +d'imagination). Pour l'utiliser, il est utile de sortir le -g lors de +la compilation du programme foireux. +GDB permet plusieurs chose comme examiner les cadavre (les fichiers core +par exemple) ou de s'attacher à un processus. Mais je vais juste +expliquer le debuggage d'un programme lancée par gdb. +Pour lancer gdb, il faut taper gdb , et ensuite, le +programme est prêt à être espionné. Il suffit de taper les commandes qui +vont bien pour voir le fonctionnement du programme. + +** Quelques commandes + +Voici quelques fonctions sympa + * b ou breakpoint permet de mettre un point d'arrêt, c'est un +endroit où le débuggueur va s'arrêter. On peut lui donner le nom d'une +fonction ou d'un numéro de ligne. + * r ou run lance le programme à debugguer + * n ou next permet de passer à l'instruction suivante au même niveau +dans la pile(reste dans l'instruction) + * s ou step permet de passer à l'instruction suivante à un niveau plus +profond de la pile le cas échéant(typiquement les instructions d'une fonction appelé) + * c ou continue exécute le programme jusqu'au prochain point d'arrêt + * l \[numéro de ligne] ou list \[NDL] permet de lister dix lignes du code source. + * p ou print \[variable] permet d'obtenir la valeur d'une variable. la +variable est à rentrer sous la forme d'une instruction, donc si il + est possible d'appelé une variable temp, il est possible de marquer +thermostat->temp ou *temp ou encore temp\[0]. + * d ou display marche comme print sauf que l'état de la variable est +indiqué à chaque instruction + * up qui permet de remonter d'un niveau dans la pile + * down qui permet de descendre d'un niveau de la pile + * info \[truc], donne des infos sur beaucoup de chose. En tapant + * address \[fonction] les adresses des fonctions + * stack, on a les info sur la pile + * breakpoints qui indique les points d'arrêt définis + * q ou quit qui permet de quitter + +* Programmes contre les fuites de mémoire + +** Eletric fence + +Electric fence est une librairie qui permet d'envoyer un SIGSEGV (erreur de +segmentation) dès que l'on lit ou que l'on écrit dans l'espace. + +*** Comment ça marche + +Electric fence est une librairie qui a l'avantage de ne pas toucher au code, +par contre il faut rajouter la librairie lefence sur la ligne du compilateur. +Un désavantage également est qu'une allocation de mémoire prend beaucoup plus +de place en mémoire et de temps avec que sans electric fence. Donc en cas de +grosse allocation ou d'allocation répété, ça risque de trancher chérie. + +Electric Fence est à utiliser avec gdb pour connaître la position du segfault +et de l'instruction incriminé, car le terminal n'est pas très loquace et +renverra juste un message "erreur de segmentation". + +Personnellement, je n'utilise plus Electric fence que j'ai remplacé par +valgrind. + +** Valgrind + +Valgrind est un programme très utiles pour tout ce qui touche à la mémoire. Il +a également d'autre fonctions comme le profiling du cache que je ne +détaillerais pas. + +*** Comment ça marche + +Il suffit d'exécuter le programme en rajoutant valgrind et les options qui vont +bien avant le nom du programme. +Par exemple +^<< +nicolas@hermes:~\valgrind --tool=memcheck --leak-check=yes -v barbecue +^>> + +La j'utilise l'outil memcheck pour vérifier la mémoire(mais c'est l'option +par défaut), j'aurais pu mettre cachegrind pour profiler le cache. +leak-check permet d'afficher les fuites de mémoire et v c'est verbose. + +Il n'est pas obligatoire mais hautement conseillé de compiler le programme +avec les infos de debbugage (-g) pour avoir toutes les infos sur la +localisation d'un problème. + +Valgrind note les erreurs mais ne forcera pas l'envoie d'un segfault +contrairement à electric fence, par conséquent, ce n'est pas parce que y'a pas +segfault qu'il n'y a pas d'erreur grave. + +*** Qu'elle erreurs Valgrind indique + +Pratiquement toutes les erreurs liées à la mémoire, c'est à dire: + * les tests sur des variables qui ne sont pas initialisés exemple +^<< +#include +int main() +{ + int p, t; + if (p == 5) /*Ho une erreur*/ + t = p+1; + return 0; +} +^>> + * Les lecture/écriture dans l'espace + En gros, les tentatives de lecture/écriture sur des espaces de la + mémoires qui ne sont pas allouée pour ça. exemple +^<< +#include +int main() +{ + int *p, i, a; + p = malloc(10*sizeof(int)); + p[11] = 1; /* Ecriture dans l'espace */ + a = p[11]; /* Lecture dans l'espace */ + free(p); + return 0; +} +^>> + * Les libérations invalides + Vous essayez de libérer un blocs qui n'est pas alloué. Exemple: +^<< +#include +int main() +{ + int *p, i; + p = malloc(10*sizeof(int)); + for(i = 0;i < 10;i++) + p[i] = i; + free(p); + free(p); /* Oui mais non, p est déjà libéré */ + return 0; +} +^>> + * Les mauvaises utilisations de fonctions + Typiquement, les allocations par malloc qui sont libérées par delete. + Exemple: +^<< +#include +int main() +{ + int *p, i; + p = ( int* ) malloc(10*sizeof(int)); + for(i = 0;i < 10;i++) + p[i] = i; + delete(p); /* C'est pas la bonne fonction */ + return 0; +} +^>> + * Les mauvais paramètres sur des fonctions utilisant la mémoire + * Les pertes de mémoires dans le cosmos + Typiquement, vous avez perdu le pointeur qui avait l'adresse du bloc + alloué. Cela donne lieu à une fuite de mémoire. + +* Conclusion + +Voilà quelques outils qui sont très utiles pour développer, si vous en voyez +d'autre ou si j'ai écris une bêtise, n'hésitez pas à me le dire à +nicolas@popple.dyndns.org. -- cgit v1.2.3