Sign in to follow this  
Calypso

 tutoriel Débuguer avec Valgrind

Recommended Posts

Niveau requis Débutant

Temps estimé : 30 minutes

Salut tout le monde !

 

Aujourd'hui je vous propose un petit tutoriel pour débuguer votre programme C / C++ avec Valgrind. Dans ce tutoriel, je vais vous parler des principales erreurs. Je donnerai des exemples simples de sorte à ce que soit compréhensible pour tout le monde.

 

Valgrind ?

 

Révélation

Valgrind est un outil très puissant pour détecter et corriger une grande partie des problèmes de gestion mémoire de vos applications écrites en C ou C++, et ainsi éviter des plantages aléatoires ou certains trous de sécurité. Ainsi, avoir un Valgrind clean permet d'avoir un programme stable qui limite beaucoup les Segmentations Fault.

 

Installer & Utiliser Valgrind

 

Révélation

 

Valgrind est un outil qui n'est fonctionnel que sur un système Linux / Unix. L'outil ne fonctionne donc pas sous Windows. Il suffit tout simplement d'installer le packet valgrind. Par exemple avec apt-get, il suffit de faire :

apt-get install valgrind

Une fois installé, on utilise valgrind de la façon suivante :

valgrind ./nom_du_binaire

Sur un programme clean qui n'affiche que "Salut Funky-Emulation", voici ce que donne Valgrind :

 

Révélation

102004Screenshot-2017-06-10-16-19-46.png

 

Ici, Valgrind m'affiche que je n'ai aucune erreur Valgrind. Je vous conseille de compiler vos fichiers sources avec le paramètre -g3, il vous permettra de savoir à quelle ligne est l'erreur.

 

 

Les Erreurs

 

Révélation

 

Invalid write of size

 

Révélation

 

Cette erreur parle d'elle même: Vous écrivez plus dans l'espace qui a été alloué. Voici un exemple simple :

 

Révélation

102853Screenshot-2017-06-10-16-28-31.png

 

Voici ce que Valgrind donne :

 

Révélation

103214Screenshot-2017-06-10-16-31-57.png

 

J'ai une erreur Invalid write of size 1, trouvez l'erreur.

 

Regardez, j'alloue un sizeof(char) * 3 à ma chaîne de caractère, donc je ne peux y mettre que 3 char .. Pourtant le ' \0 ' est compté comme un caractère. Il faut donc allouer un char en plus à la chaîne. Voici un schéma qui vous montre bien l'erreur:

 

Révélation

105833Sans-titre.jpg

 

 

Invalid read of size

 

Révélation

 

Pareil, l'erreur parle d'elle même. Dans ce cas là, vous n'écrivez pas en dehors de la mémoire mais vous lisez en dehors de celle-ci. Voici un programme qui génère cette erreur :

 

Révélation

104057Screenshot-2017-06-10-16-40-37.png

 

Et voila ce que Valgrind me donne :

 

Révélation

104159Screenshot-2017-06-10-16-40-15.png

 

L'erreur est simple : Ma chaine de caractère ne comporte pas de ' \0 '. La condition de fin de ma boucle est le caractère ' \0 ', or, il n'y en a pas, donc on lit plus loin que ce que l'on est censé pouvoir lire. Voici un schéma qui explique l'erreur :

 

Révélation

100329Sans-titre.jpg

 

Il suffit juste de mettre un ' \0 ' à la fin de la chaîne pour corriger cette erreur. Pensez à bien sécuriser vos boucle ! Il faut toujours qu'il y est une condition de fin, dans tous les cas possibles. Par exemple, quand on cherche la position du caractère ' : ' dans une chaîne, il vaut mieux sécuriser la boucle avec la condition sur le ' \0 '. Comme ceci :

 

Révélation

105035Screenshot-2017-06-10-16-50-21.png

 

Imaginons que ma chaîne ne comporte pas le caractère ' : ', il comporte alors forcément le caractère ' \0 ' et évite les sorties mémoire.

 

 

Conditional jump or move depends on uninitialised value(s)

 

Révélation

 

Cette erreur veut dire que l'une de vos variables n'est pas initialisée, que ça soit une variable de type int ou même de type char*. Voici un programme qui génère cette erreur :

 

Révélation

100021Screenshot-2017-06-10-17-00-05.png

 

Et voila ce que donnne Valgrind :

 

Révélation

100057Screenshot-2017-06-10-16-59-38.png

 

C'est simple, j'ai déclaré une chaîne de caractère sans lui allouer un espace mémoire. Du coup, lorsque ça passe sur la boucle, on parcourt une chaîne qui n'est pas initialisée. De même, quand on incrémente un compteur de type int, si celui-ci n'est pas initialisé, cela provoque une erreur.

 

 

 

Conclusion

 

Révélation

Valgrind est un outil très puissant, n'hésitez pas à l'utiliser ! La principale notion à retenir est de bien mettre des \0 à la fin de ses chaines de caractères et de bien sécuriser ses boucles.

 

Cordialement,

Hey hey

Share this post


Link to post
Share on other sites

Merci pour le tutoriel ! :)

 

Dommage que ça ne soit pas dispo sous Windows, je connais un certain client de jeu vidéo qui en aurait bien besoin ...

Share this post


Link to post
Share on other sites
Sign in to follow this