Compare commits
3 commits
9744949b4f
...
1bfb8b9eb9
Author | SHA1 | Date | |
---|---|---|---|
Théophile Bastian | 1bfb8b9eb9 | ||
Théophile Bastian | 2b831dc3f2 | ||
Théophile Bastian | 32a807aa0f |
|
@ -4,8 +4,8 @@ author: "Théophile Bastian \\texttt{<theophile.bastian@inria.fr>}"
|
|||
date: "\\vspace{-1em}"
|
||||
lang: fr
|
||||
geometry:
|
||||
- top=2cm
|
||||
- bottom=2cm
|
||||
- top=1.5cm
|
||||
- bottom=1.5cm
|
||||
- left=2cm
|
||||
- right=2cm
|
||||
pagestyle: empty
|
||||
|
|
25
poly/poly.md
25
poly/poly.md
|
@ -2,9 +2,12 @@
|
|||
|
||||
Une *segfault* -- *segmentation fault*, ou *erreur de segmentation* -- apparaît
|
||||
quand un programme essaye d'accéder à une zone mémoire qui ne lui est pas
|
||||
allouée. C'est une erreur fréquente dès lors qu'on manipule des pointeurs, et
|
||||
elle est plus difficile à corriger qu'un bug classique -- en tout cas quand on
|
||||
n'a pas les bons réflexes !
|
||||
allouée\footnote{À noter que si une segfault est toujours due à un accès à de
|
||||
la mémoire non allouée, l'inverse n'est pas vrai : parfois, un tel accès ne
|
||||
résulte pas en une segfault, et peut par exemple corrompre une autre variable
|
||||
du programme.}. C'est une erreur fréquente dès lors qu'on manipule des
|
||||
pointeurs, et elle est plus difficile à corriger qu'un bug classique -- en tout
|
||||
cas quand on n'a pas les bons réflexes !
|
||||
|
||||
Elle arrive par exemple dans les cas suivants :
|
||||
|
||||
|
@ -117,11 +120,9 @@ nous indique, de bas en haut, que :
|
|||
* on crash (segfault)
|
||||
|
||||
La première ligne nous indique la position du bug, les lignes suivantes nous
|
||||
indiquent d'où on vient dans le programme.
|
||||
|
||||
C'est certes peu d'informations (la ligne de l'erreur seulement -- pas la
|
||||
variable concernée, etc), mais c'est déjà mieux que juste `Segmentation fault
|
||||
(core dumped)`, et souvent suffisant.
|
||||
indiquent d'où on vient dans le programme. C'est certes peu d'informations (la
|
||||
ligne de l'erreur seulement -- pas la variable concernée, etc), mais c'est déjà
|
||||
mieux que juste `Segmentation fault (core dumped)`, et souvent suffisant.
|
||||
|
||||
# Si c'est plus compliqué : gdb
|
||||
|
||||
|
@ -151,8 +152,8 @@ Program received signal SIGSEGV, Segmentation fault.
|
|||
`gdb` nous dit qu'on a une *segfault* dans `afficher_liste`, ligne 20 de
|
||||
`exemple.c` -- rien de nouveau. Il nous donne les valeurs des arguments de
|
||||
cette fonction (`taille=3`, et une adresse pour `tete`). Mais surtout, *on
|
||||
reste en mode interactif* ! On peut lui demander la même chose qu'à `valgrind`,
|
||||
savoir d'où on vient :
|
||||
reste en mode interactif* ! On peut lui demander ce que `valgrind` affichait spontanément,
|
||||
la *backtrace* (savoir d'où on vient) :
|
||||
|
||||
```GDB
|
||||
(gdb) backtrace
|
||||
|
@ -166,6 +167,10 @@ On peut lui demander d'afficher des valeurs *au moment du crash* :
|
|||
2
|
||||
(gdb) print cur
|
||||
(liste_t *) 0x0
|
||||
(gdb) print &(liste->suivant) # On peut écrire des expressions C compliquées
|
||||
(struct liste **) 0x5555555592a0
|
||||
(gdb) print liste->suivant->valeur + 42 - taille # aussi compliquées qu'on veut
|
||||
41
|
||||
```
|
||||
|
||||
...ou la même chose, mais dans `main`, au moment de l'appel de fonction :
|
||||
|
|
3
poly/src/.gitignore
vendored
Normal file
3
poly/src/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
vgcore.*
|
||||
a.out
|
||||
test
|
BIN
poly/src/a.out
BIN
poly/src/a.out
Binary file not shown.
|
@ -7,23 +7,26 @@ struct liste {
|
|||
};
|
||||
typedef struct liste liste_t;
|
||||
|
||||
// Alloue une nouvelle cellule de
|
||||
// valeur `val`
|
||||
liste_t* alloc_cell(int val) {
|
||||
liste_t* cell = malloc(sizeof(liste_t));
|
||||
liste_t* cell =
|
||||
malloc(sizeof(liste_t));
|
||||
cell->valeur = val;
|
||||
cell->suivant = NULL;
|
||||
return cell;
|
||||
}
|
||||
|
||||
void afficher_liste(liste_t* tete, int taille) {
|
||||
liste_t* cur = tete;
|
||||
// Affiche les `taille` 1ères valeurs de `liste`
|
||||
void afficher_liste(liste_t* liste, int taille) {
|
||||
liste_t* cur = liste;
|
||||
for(int pos=0; pos < taille; ++pos) {
|
||||
printf("%d\n", cur->valeur);
|
||||
cur = cur->suivant;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int n = atoi(argv[1]);
|
||||
int n = atoi(argv[1]); // premier argument
|
||||
liste_t* tete = alloc_cell(1);
|
||||
tete->suivant = alloc_cell(2);
|
||||
afficher_liste(tete, n);
|
||||
|
|
BIN
poly/src/test
BIN
poly/src/test
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue