Aller au contenu principal

Produire une trace d'exécution

Si un as un morceau de code, on peut souhaiter savoir dans quel ordre les instructions sont exécutées.

Pour cela, on peut utiliser un outil de traçage.

Principe

On veut accomplir 2 éléments principaux:

  1. indiquer quelles lignes de code s'exécutent dans quel ordre
  2. indiquer les effets de chaque ligne de code

Exemple simple

Si on a le code suivant:

val a = 3 + 4
val b = a * 2
println("salut " + b)

Trace

On aura la trace suivante:

ligne exécutéeeffet
val a = 3 + 4a: 7
val b = a * 2a: 7, b: 14
println("salut " + b)a: 7, b: 14, affiche "salut 14"

Dans le cas d'une séquence d'instructions, on peut voir que les instructions sont exécutées dans l'ordre de lecture du code. Simple!

Le code markdown de ce tableau est disponible ici.

Exemple avec boucle

Si on a le code suivant:

for (i in 1..3){
if (i % 2 == 0) {
println("c'est pair " + i)
}
else {
println("ah ben ah ben, c'est impair " + i)
}
}

Trace

On aura la trace suivante:

ligne exécutéeeffet
for (i in 1..3)i parcourt l'interval 1, 2, 3
if (i % 2 == 0)i: 1
i%2 vaut 1
println("ah ben ah ben, c'est impair " + i)i: 1
affiche "ah ben ah ben, c'est impair 1"
if (i % 2 == 0)i: 2
i%2 vaut 0
println("c'est pair " + i)i: 2
affiche "c'est pair 2"
if (i % 2 == 0)i: 3
i%2 vaut 1
println("ah ben ah ben, c'est impair " + i)i: 3
affiche "ah ben ah ben, c'est impair 3"

On voit que:

  • on n'indique que les lignes qui s'exécutent en vrai
  • certaines lignes s'exécutent plusieurs fois, c'est le principe de la boucle!
  • on appelle ce cheminement le flot de contrôle

Exemple avec une fonction

Si on a le code suivant:

fun ma_fonction(a : Int, b: Int) : Int {
val c = a + b
return c
}

fun main() {
var mavariable = 3
var tavariable = 5
var z = ma_fonction(mavariable, tavariable)
var y = ma_fonction(4, 9)
print("z vaut " + z + " et y vaut " + y)
}

Trace

S'il y a des fonctions dans le code, on doit ajouter la pile d'appels pour indiquer quelles fonctions ont été commencées mais pas finies.

ligne exécutéeeffetpile d'appels
var mavariable = 3mavariable: 3main
var tavariable = 5mavariable: 3
tavariable: 5
main
var z = ma_fonction(mavariable, tavariable)mavariable: 3
tavariable: 5
appelle ma_fonction avec a→3 et b→5
main
val c = a + ba: 3
b: 5
c: 8
ma_fonction
main
return ca: 3
b: 5
c: 8, retourne 8, z = 8
ma_fonction
main
var y = ma_fonction(4, 9)mavariable: 3
tavariable: 5
z: 8
appelle ma_fonction avec a→4 et b→9
main
val c = a + ba: 4
b: 9
c: 13
ma_fonction
main
return ca: 4
b: 9
c: 13
retourne 13, y = 13
ma_fonction
main
println("z vaut " + z + " et y vaut " + y)mavariable: 3
tavariable: 5
z: 8
y = 13
affiche "z vaut 8 et y vaut 13"
main

Dans ce cas, on doit ajouter la pile d'appels pour indiquer quelles fonctions ont été commencées mais pas finies.

Valider ta trace

Afin de valider ta trace, tu vas utiliser le débogueur de ton IDE préféré.

  1. place un point d'arrêt sur la première ligne qui s'exécute
  2. lance l'exécution en mode débogage
  3. saute d'une ligne en une ligne pour voir si ta trace est correcte

Si tu te rends à la fin de l'exécution et que toutes tes valeurs étaient bonnes, tu as bien compris ce que fait le code.