# Débogage avancé/Travail pratique/Observation à la loupe
## But de ce TP

Un des bugs classiques en C et C++ est de lire ou d'écrire en dehors d'une zone préalablement allouée. Suivant les cas les comportements à l'exécution sont un peu différents. Cela va permettre d'illustrer différentes techniques sur des bugs très similaires.

## Les trois codes à déboguer
### Lire un peu avant la zone allouée

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

### Écrire un peu après la zone allouée

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

### Écrire loin au-delà de la zone allouée

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

## Les consignes
### Lire un peu avant la zone allouée

Le code bug_overreadheap_tiny.c lit une valeur juste un peu devant l'allocation. Comme c'est la première allocation, elle est en bordure de page et cela provoque instantanément un SEGFAULT. Il est donc relativement aisé de trouver la source du problème avec gdb en demandant simplement les valeurs des variables.
* Compiler le fichier bug_overreadheap_tiny.c. Un compilateur récent devrait détecter le bug.
* Lancer le programme bug_overreadheap_tiny. Vous devriez obtenir le SEGFAULT attendu
* Lancer le programme avec Valgrind qui devrait vous indiquer la ligne du code avec l'erreur.
* Lancer le programme dans gdb. Afficher le contenu des 20 premières cases du tableau en décimal.
* Demander l'affichage de p[i-2]
* Recompiler le programme avec ASan. Lancer le programme. ASan détecte bien le SEGFAULT mais ne vous indique rien sur sa cause.
Vous devriez avoir tapé les commandes suivantes (Certains affichages sont omis):

### Écrire un peu après la zone allouée

Le code bug_overwriteheap_tiny.c écrit une valeur juste un peu après l'allocation (un entier de 4 octets, 0 octet après, donc juste après). Lors d'une exécution normale, il ne se passe rien ! Il se termine parfaitement normalement. Mais le bug est bien là. Valgrind est capable de le détecter.
* Compiler le fichier bug_overwriteheap_tiny.c. Il est fort possible que votre compilateur ne remonte aucun problème.
* Lancer le programme. Il ne devrait y avoir aucun problème non plus, car la détection matérielle ne fonctionne qu'à la granularité d'une page (typiquement 4Kio).
* Lancer le programme avec Valgrind qui devrait vous indiquer la ligne du code avec l'erreur.
* Recompiler le programme avec ASan. Lancer le programme. L'erreur devrait aussi être détectée à l'exécution.
Vous devriez avoir tapé les commandes suivantes (Certains affichages sont omis):

### Écrire loin au-delà de la zone allouée

Dans le code bug_overwriteheap_large.c l'allocation est 4 fois trop petite. Beaucoup d'écritures débordent. Néanmoins, la détection n'a lieu qu'au moment du free. Valgrind sait détecter le problème. Mais si nous soupçonnons un débordement en écriture, nous pouvons demander à gdb de surveiller explicitement des modifications juste après notre allocation.
Cette technique est particulièrement utile lorsque quelque chose a modifié une de vos structures de données: vous ne savez pas quoi ou quand, mais vous savez où.
* Compiler le fichier bug_overwriteheap_large.c. Le compilateur devrait détecter le problème.
* Lancer le programme. La détection du problème a lieu au moment du free.
* Lancer le programme avec Valgrind qui devrait vous indiquer les lignes du code avec l'erreur.
* Charger le programme dans GDB. Mettre un breakpoint au niveau du malloc. Après l'exécution du malloc, mettre un watchpoint sur la mémoire juste après le malloc (attention à l'arithmétique de pointeurs !). Continuer.
* Recompiler le programme avec ASan. Lancer le programme. L'erreur devrait aussi être détectée à l'exécution.
Vous devriez avoir tapé les commandes suivantes (Certains affichages sont omis):
| Débogage avancé/Travail pratique/Débogage à la volée | Débogage avancé/Travail pratique/Allocation dans la pile |