# Débogage avancé/Travail pratique/Débordement de pile
## But de ce TP

Depuis la création et l'implantation du langage Algol dans les années 1958-1960, la plupart des langages de programmations permettent d'exécuter des fonction récursives. L'idée de base est d'avoir une zone de mémoire dédiée à enregistrer les informations pour cela: la pile.
Un petit peu de cette pile est consommé par chaque appel récursif pour y stocker les variables locales, les arguments de la fonction, l'adresse de retour, tous liés à l'appel. Cet espace n'est rendu qu'à la terminaison de la fonction. Il n'est donc pas possible d'empiler à l'infini des appels récursifs en C. Certains langages fonctionnels comme OCaml, LISP (et ses descendants: Scheme, Clojure, etc.) ou Haskell, sont capables d'enlever une récursion terminale pour rendre le programme itératif et ainsi, éliminer le problème. Le langage Go, augmente la pile jusqu'à plusieurs Gio ce qui repousse le problème, mais ne l'élimine pas.

## Le code à déboguer

Créer un fichier bug_stackoverflow.c contenant le code suivant.

## Les consignes
### Détecter le bug

Le programme bug_stackoverflow.c utilise une liste circulaire pour appeler à l'infini une fonction récursive. Une fonction récursive utilise une pile pour ses variables locales et ses paramètres. La pile est juste un bloc de mémoire contigüe de quelques Mio par défaut. La commande ulimit -a vous donne la liste de vos limites.
* Compiler et lancer le programme. C'est la gestion de la pagination et de la mémoire virtuelle du processeur (une détection matérielle) et du système d'exploitation (traitement logiciel de l'erreur détectée) qui désigne l'utilisation illégale de mémoire au-delà de la pile (SEGFAULT). Mais un SEGFAULT ressemble à tous les autres accès illégaux que vous pouvez faire avec un pointeur.
* Lancez le programme avec Valgrind. Il détecte également le problème. Mais surtout, Valgrind vous indique que c'est un débordement de pile et pas autre chose !

### Tracer l'état du programme sans le changer en permanence

Pour déboguer un code (ici, comprendre que la liste est circulaire), une première méthode est d'ajouter des printf pour obtenir des traces. Cela demande de savoir à l'avance ce que l'on veut observer, puis d'éditer le code, puis de recompiler, puis de réexécuter, puis de recommencer le tout si la trace ne suffit pas. C'est long !
Votre débogueur est parfaitement capable d'ajouter dynamiquement ces traces sans avoir à changer le code et recompiler le programme.
* Lancer gdb avec le programme en argument dans un terminal. Démarrer le programme. Afficher le code de la fonction fautive. Demander l'affichage de h et de h->next à chaque passage à la ligne avant le return. Redémarrez le programme en confirmant le redémarrage depuis le début. Voilà, vous avez votre trace ! Générez la trace en soi est long car gdb fait un arrêt à chaque passage à la ligne indiquée et votre terminal n'est pas aussi rapide que vous le pensez, mais vous n'hésitez pas à faire Control-C pour interrompre l'exécution.
Vous devriez avoir tapé les commandes suivantes (certains affichages de Valgrind sont omis):
Pour la détection du bug:
Pour la génération de la trace:
* Débogage avancé/Travail pratique/Pile d'appels