Débogage avancé/Outils d'aide au débogage et fondamentaux

Début de la boite de navigation du chapitre
Outils d'aide au débogage et fondamentaux
Icône de la faculté
Chapitre no 1
Leçon : Débogage avancé
Chap. suiv. :Débogage avancé/La mémoire
fin de la boite de navigation du chapitre
En raison de limitations techniques, la typographie souhaitable du titre, « Débogage avancé : Outils d'aide au débogage et fondamentaux
Débogage avancé/Outils d'aide au débogage et fondamentaux
 », n'a pu être restituée correctement ci-dessus.

La diversité des outils

modifier

La programmation et le débogage impliquent des successions d'actions réparties en plusieurs phases: l'écriture du programme; la compilation; l'exécution du programme. Des différentes techniques interviennent suivant les phases: l'analyse statique du code lors de la phase d'écriture ou de compilation; les tests unitaires; le débogage interactif; la vérification sémantique dynamique des accès mémoires.

Les tests unitaires

modifier

Écrire les tests unitaires pendant la rédaction des programmes fait partie des bonnes pratiques. Dans des langages récents comme Rust et Go, ils sont complètement intégrés dans les chaînes de fabrication d'un programme. De manière notable, directement, dans les commentaires du code, sous une forme complémentaire à la programmation lettrée de Knuth (literate programming).

Le compilateur

modifier

Le compilateur (ou l'interpréteur) peut parfois détecter des aspects du code qui lui semble incohérents dans un cadre général, même si le code est valide du point de vue purement syntaxique.

Il est très important dans la phase de débogage de favoriser cette remontée d'information. Mais comme ces détections augmentent le temps de compilation, il faut les activer explicitement.

Les avertissements

modifier

Il y a plusieurs niveaux dans la détection. Le mieux est d'en demander le plus possible.

$ gcc -g -Wall -Wextra ...

Néanmoins, pour un code déjà ancien et de taille importante, il est parfois difficile de refactoriser le code pour les éliminer. Mais plutôt que de ne demander aucun avertissement, il vaut mieux supprimer uniquement ceux dont vous avez vérifié l'inocuité.

$ gcc -g -Wall -Wextra -Wno-unused-result ...

L'analyseur statique

modifier

L'analyseur statique du compilateur fera une analyse beaucoup plus fine de la totalité du code, et donc beaucoup plus coûteuse en temps. L'activation est différente, et complémentaire, des avertissements.

Pour gcc, c'est relativement simple

$ gcc -g -Wall -Wextra -fanalyzer ...

Pour clang, l'analyse statique et sa visualisation sont plus intrusives dans le processus de compilation.

$ scan-build clang ...
[... affiche le répertoire avec les résultats ...]
$ scan-view <répertoire avec les résultats>

La page web de l'analyseur statique de clang est https://clang-analyzer.llvm.org/ .

AddressSanitizer

modifier

AddressSanitizer est une bibliothèque de détection d'erreurs mémoire à l'exécution du programme. Elle est relativement rapide et détecte de nombreuses erreurs. Par contre, il faut demander explicitement au compilateur de l'utiliser.

$ gcc ... -fsanitize=address ...

Cette instrumentation est incompatible ou rend difficile, l'utilisation de valgrind sur l'exécutable.

Le débogueur

modifier

GDB

Valgrind

modifier

Memcheck

modifier

Ce qui n'est pas (encore) dans les TP

modifier
  • les protections des cadres des piles (stack smashing) (-fstack-protector, -lssp)
  • le débogage des threads (fil) (valgrind -tool=helgrind, valgrind --tool=drd)