4 Déverminage d'un programme
Un dévermineur (ou metteur au point ou débogueur) permet d'exécuter un
programme en mode pas à pas et de visualiser l'ensemble de la mémoire
du processus correspondant au programme en cours d'exécution. La
plupart des processeurs possède un mode pas à pas dans lequel ils
appellent automatiquement une routine après l'exécution de chaque
instruction machine. Les dévermineurs utilisent ce mode pour exécuter
un programme :
-
instruction par instruction (stepi, nexti) ;
- ligne de code source par ligne de code source (step,
next) ;
- point d'arrêt par point d'arrêt (continue,
cont).
C'est ce dernier mode que l'on utilise le plus fréquemment :
-
on place un point d'arrêt (break) dans le code source
à l'endroit où l'on suspecte que se trouve l'erreur ;
- on démarre l'exécution du programme (run) jusqu'à ce
point d'arrêt ;
- puis on exécute pas à pas en examinant le comportement du
programme.
On peut également examiner le contenu des variables (print et
display) ou même la valeur d'une expression quelconque du
langage C.
La pile des appels de fonction est aussi visible (backtrace),
ainsi que les cadres d'appel de chaque fonction (frame et
info frame).
Le dévermineur que vous allez utiliser est gdb (Gnu DeBugger)
et plusieurs interfaces graphiques à gdb sont disponibles,
dont xxgdb et ddd, ce dernier étant le moins
austère.
Exercice 15
-
Lancez le dévermineur et chargez votre programme.
- Placez un point d'arrêt avant l'appel à la fonction
factorielle().
- Exécutez alors le programme en mode pas à pas
(step pour entrer dans la fonction, next
saute les appels de fonction).
- Affichez les valeurs des variables res et
i (display) : leurs valeurs sont quelconques
car elles n'ont encore pas été initialisées. Les variables
locales sont en effet allouées automatiquement dans la pile,
qui à cet instant de l'exécution peut contenir n'importe quoi.
- En continuant à exécuter en mode pas à pas, vous verrez
les variables res et i évoluer au cours des
itérations de la boucle.
Exercice 16
Relancez l'exécution du programme (run) avec le même
point d'arrêt. Modifier la valeur de n dans la fonction
main() avec l'instruction set (via le bouton
set
) ou par :
(gdb) set n=12
et terminez son exécution (cont). Le programme a bien
calculé la factorielle de 12, et non pas de 10. Recommencez avec
n=13, et vérifiez que le résultat n'est pas égal à 13
fois le précédent. Les entiers de type int ne font bien
que 32 bits sur cette machine.