Il n'existe pas de lint qui soit réellement utilisable, tout simplement
parce que la grande majorité des développeurs sont satisfaits des messages
d'avertissement de gcc. Il est probable que l'option la plus utile est
l'option -Wall
--- qui a pour effet d'afficher tous les
avertissements possibles.
Il existe une version du domaine public du programme lint que vous pouvez trouver à l'adresse suivante : ftp://larch.lcs.mit.edu/pub/Larch/lclint. Je ne sais pas ce qu'elle vaut.
Vous devez compiler et effectuer l'édition de liens avec l'option
-g
, et sans l'option -fomit-frame-pointer
.
En fait, vous ne devez compiler que les modules que
vous avez besoin de déboguer.
Si vous possédez un système a.out, les bibliothèques dynamiques sont
compilées avec l'option -fomit-frame-pointer
,
que gcc ne peut pas gérer. Lorsque vous compilez avec l'option
-g
, alors par défaut vous effectuez une édition de liens statique, ce
qui permet de résoudre le problème.
Si l'éditeur de liens échoue avec un message disant qu'il n'arrive
pas à trouver la bibliothèque libg.a, c'est que vous ne possédez pas
la bibliothèque /usr/lib/libg.a
, qui est la bibliothèque C standard
permettant le débogage. Cette bibliothèque est fournie dans
le paquetage des binaires de la libc., ou (dans les nouvelles versions)
vous aurez besoin de récupérer le source et de le compiler vous-même.
Vous n'avez pas réellement besoin de cela en fait, vous pouvez faire
un lien logique vers /usr/lib/libc.a
Bon nombre de produits GNU sont fournis pour compiler avec l'option
-g
, ce qui génère des exécutables d'une taille très importante (et
souvent l'édition de liens s'effectue d'une manière statique).
Ce n'est pas une idée lumineuse...
Si le programme possède le script configure
généré par
autoconf, vous pouvez modifier les options de débogage en
effectuant un
./configure CFLAGS=
ou ./configure CFLAGS=-O2
. Sinon,
vous pouvez aller modifier le Makefile. Bien sûr, si vous utilisez le format
ELF, l'édition de liens sera effectuée de manière dynamique même avec l'option
-g
. Dans ce cas, vous pouvez effectuer un strip sur l'exécutable.
Beaucoup de gens utilisent gdb, que vous pouvez récupérer sur le site prep.ai.mit.edu, sous une forme binaire sur tsx-11 ou sur sunsite. xxgdb est une surcouche X de gdb (c.a.d. que vous avez besoin de gdb pour utiliser xxgdb). Les sources peuvent être récupérés sur ftp://ftp.x.org/contrib/xxgdb-1.08.tar.gz
Il existe également le débogueur UPS qui a été porté par Rick Sladkey. Il fonctionne sous X également, mais à la différence d'xxgdb, ce n'est qu'une surcouche X pour un débogueur en mode en texte. Il possède certaines caractéristiques très intéressantes et si vous utilisez beaucoup ce genre d'outils, vous l'essayerez sûrement. Les patches ainsi que des versions précompilées pour Linux peuvent être trouvées sur ftp://sunsite.unc.edu/pub/Linux/devel/debuggers/, et les sources peuvent être récupérés sur ftp://ftp.x.org/contrib/ups-2.45.2.tar.Z.
Un autre outil que vous pouvez trouver utile pour déboguer est « strace » , qui affiche les appels systèmes que le processus lance. Il possède d'autres caractéristiques telles que donner les chemins d'accès où ont été compilés les binaires, donner les temps passés dans chacun des appels systèmes, et il vous permet également de connaître les résultats des appels. La dernière version de strace (actuellement la version 3.0.8) peut être trouvée sur ftp://ftp.std.com/pub/jrs/.
Les démons lancent typiquement un fork()
dès leur lancement et
terminent donc le père. Cela fait une session de déboguage très courte.
La manière la plus simple de résoudre ce problème est de poser
un point d'arrêt sur fork
, et
lorsque le programme s'arrête, forcer le retour à 0.
(gdb) list
1 #include <stdio.h>
2
3 main()
4 {
5 if(fork()==0) printf("child\n");
6 else printf("parent\n");
7 }
(gdb) break fork
Breakpoint 1 at 0x80003b8
(gdb) run
Starting program: /home/dan/src/hello/./fork
Breakpoint 1 at 0x400177c4
Breakpoint 1, 0x400177c4 in fork ()
(gdb) return 0
Make selected stack frame return now? (y or n) y
#0 0x80004a8 in main ()
at fork.c:5
5 if(fork()==0) printf("child\n");
(gdb) next
Single stepping until exit from function fork,
which has no line number information.
child
7 }
Lorsque Linux se lance, il n'est généralement pas configuré pour produire des fichiers core. Si vous les voulez vous devez utiliser votre shell pour ça en faisant sous csh (ou tcsh) :
% limit core unlimited
avec sh, bash, zsh, pdksh, utilisez
$ ulimit -c unlimited
Si vous voulez pousser le vice à nommer votre fichier core (par exemple
si vous utilisez un débogueur bogué... ce qui est un comble)
vous pouvez simplement modifier
le noyau. Editez les fichiers fs/binfmt_aout.c
et
fs/binfmt_elf.c
(dans les nouveaux noyaux, vous devrez
chercher ailleurs) :
memcpy(corefile,"core.",5);
#if 0
memcpy(corefile+5,current->comm,sizeof(current->comm));
#else
corefile[4] = '\0';
#endif
et changez les 0
par des 1
.
Il est possible d'examiner un peu le programme pour
savoir quels sont les appels de fonctions qui sont effectués le
plus souvent ou bien qui prennent du temps. C'est une bonne manière
d'optimiser le code en déterminant là où l'on passe le plus de temps.
Vous devez compiler tous les objets avec l'option -p
,
et pour mettre en forme la sortie écran, vous aurez besoin du
programme gprof
(situé dans les binutils
).
Consultez les pages de manuel gprof
pour plus de détails.