Débogage avancé/Outils d'aide au débogage et fondamentaux
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)