Ce didacticiel est destiné aux nouveaux utilisateurs de la Simple Virtual Machine.
Dans ce didacticiel, vous allez manipuler le débugueur depuis le code de manière plus étendue.
Le temps de lecture de ce didacticiel est estimé à 15 minutes si l'utilisation basique du débugueur et les instructions extensions ont été abordées.
Pour commencer, créez le canevas de l'application dans le fichier exécutable points_arret_etendus.svm en utilisant ce code :
#!/usr/bin/env svm
DESCRIPTION
Advanced debug example
END
LOG
DEBUG "Advanced debug" STYLE "default"
PLUGIN "svmcom.so"
PLUGIN "svmstr.so"
PROCESS "application"
CODE "main" INLINE
:interruption CASCADE MEMORY failure
:call function P
:shutdown
:label function
:memory INT/i, STR/s
0 -> &i
11 -> &s
:shift &i
:str.replace @&s 1 CONST str.pattern "[0-9]" => "x"
:com.message @&i " " @&s
:return
:label failure
:com.message "Error"
END
END
Lancez l'application :
./points_arret_etendus.svm
Error
Le résultat indique qu'une interruption mémoire a été levée lors de l'exécution de l'application.
Quand l'application est un peu conséquente, avoir un point d'arrêt sur une interruption peut se révéler efficace pour diagnostiquer dans le débugueur la cause de l'erreur.
Modifiez le code pour ajouter un point d'arrêt sur interruption :
#!/usr/bin/env svm
DESCRIPTION
Advanced debug example
END
LOG
DEBUG "Advanced debug" STYLE "default"
PLUGIN "svmcom.so"
PLUGIN "svmstr.so"
PROCESS "application"
CODE "main" INLINE
:debug ADD MEMORY
:interruption CASCADE MEMORY failure
:call function P
:shutdown
:label function
:memory INT/i, STR/s
0 -> &i
11 -> &s
:shift &i
:str.replace @&s 1 CONST str.pattern "[0-9]" => "x"
:com.message @&i " " @&s
:return
:label failure
:com.message "Error"
END
END
Puis lancez l'application en mode débugueur. L'application est directement sur un point d'arrêt là où l'interruption a été levée :
En bas de la fenêtre du processeur, vous pouvez noter que l'interruption mémoire est en attente de traitement.
:debug ADD interruption
permet d'ajouter un point d'arrêt sur une interruption.:debug REMOVE interruption
permet de retirer un point d'arrêt sur une interruption.Tout comme pour les interruptions, il peut être très pratique de pouvoir arrêter l'application sur une opération mémoire.
Corrigez la source de l'interruption et modifiez le code :
#!/usr/bin/env svm
DESCRIPTION
Advanced debug example
END
LOG
DEBUG "Advanced debug" STYLE "default"
PLUGIN "svmcom.so"
PLUGIN "svmstr.so"
PROCESS "application"
CODE "main" INLINE
:debug ADD READ &0
:interruption CASCADE MEMORY failure
:call function P
:shutdown
:label function
:memory INT/i, STR/s
0 -> &i
"11" -> &s
:shift &i
:str.replace @&s 1 CONST str.pattern "[0-9]" => "x"
:com.message @&i " " @&s
:return
:label failure
:com.message "Error"
END
END
Lancez de nouveau l'application en mode débugueur. Lorsque le second point d'arrêt est atteint, vous devez obtenir :
L'application a été arrêtée dans le débugueur lors des deux lectures à l'adresse &0. Notez que l'adresse passée à l'instruction :debug ADD READ
peut être calculée comme n'importe quelle adresse.
De plus, le débugueur montre dans la liste des points d'arrêt le type et la valeur pour chacune des lectures.
Modifiez à nouveau le code :
#!/usr/bin/env svm
DESCRIPTION
Advanced debug example
END
LOG
DEBUG "Advanced debug" STYLE "default"
PLUGIN "svmcom.so"
PLUGIN "svmstr.so"
PROCESS "application"
CODE "main" INLINE
:interruption CASCADE MEMORY failure
:call function P
:shutdown
:label function
:memory INT/i, STR/s
:debug ADD WRITE &s
0 -> &i
"11" -> &s
:shift &i
:str.replace @&s 1 CONST str.pattern "[0-9]" => "x"
:com.message @&i " " @&s
:return
:label failure
:com.message "Error"
END
END
Puis lancez une nouvelle fois l'application avec le débugueur :
Cette fois, l'application est arrêtée sur l'écriture en mémoire à l'adresse &1. Le point d'arrêt indique l'ancien type, l'ancienne valeur et les nouveaux type et valeur.
Modifiez encore le code :
#!/usr/bin/env svm
DESCRIPTION
Advanced debug example
END
LOG
DEBUG "Advanced debug" STYLE "default"
PLUGIN "svmcom.so"
PLUGIN "svmstr.so"
PROCESS "application"
CODE "main" INLINE
:interruption CASCADE MEMORY failure
:call function P
:shutdown
:label function
:memory INT/i, STR/s
:debug ADD ACCESS &s
0 -> &i
"11" -> &s
:shift &i
:str.replace @&s 1 CONST str.pattern "[0-9]" => "x"
:com.message @&i " " @&s
:return
:label failure
:com.message "Error"
END
END
Lancez dans le débugueur pour obtenir :
L'instruction :str.replace
n'arrête pas l'application sur une lecture ou une écriture en mémoire, mais sur un accès à la mémoire.
Un accès en mémoire est une opération qui modifie une valeur directement stockée en mémoire sans écriture explicite. Seuls les nouveaux type et valeur sont indiqués dans le point d'arrêt.
Une seule exception existe : l'instruction :shift
réalise un accès mémoire, mais simule une lecture et une écriture sur les points d'arrêt pour des raisons pratiques.
Modifiez une dernière fois le code :
#!/usr/bin/env svm
DESCRIPTION
Advanced debug example
END
LOG
DEBUG "Advanced debug" STYLE "default"
PLUGIN "svmcom.so"
PLUGIN "svmstr.so"
PROCESS "application"
CODE "main" INLINE
:interruption CASCADE MEMORY failure
:call function P
:shutdown
:label function
:memory INT/i, STR/s
:debug ADD FREE &s
0 -> &i
"11" -> &s
:shift &i
:str.replace @&s 1 CONST str.pattern "[0-9]" => "x"
:com.message @&i " " @&s
:return
:label failure
:com.message "Error"
END
END
Et lancez l'application avec le débugueur :
Dans ce cas, l'application s'arrête sur l'instruction qui libère la mémoire à l'adresse &1. Le type et la valeur avant suppression sont indiqués dans le point d'arrêt.
:debug ADD READ adresse_memoire
permet de placer un point d'arrêt sur une lecture mémoire.:debug ADD WRITE adresse_memoire
permet de placer un point d'arrêt sur une écriture mémoire.:debug ADD ACCESS adresse_memoire
permet de placer un point d'arrêt sur un accès mémoire. Un accès mémoire est une modification directe d'une valeur en mémoire sans écriture explicite.:debug ADD FREE adresse_memoire
permet de placer un point d'arrêt sur une libération mémoire.ADD
peut être remplacé par le mot-clef REMOVE
pour retirer le point d'arrêt dans les quatre instructions précédentes.Une dernière catégorie de points d'arrêt peut être rencontrée. Créer de tels points d'arrêt est accessible uniquement à des utilisateurs avancés, mais peuvent être rencontrés par des utilisateurs débutants. Ainsi, nous nous contenterons ici de montrer dans le débugueur à quoi ils ressemblent.
Les extensions peuvent contenir des points d'arrêt au beau milieu de leur exécution pour expliciter comment elle se déroule et son impact sur la machine virtuelle. L'exécution de l'application s'arrête sur un tel point d'arrêt :
Les extensions peuvent aussi vouloir afficher des informations complémentaires dans le débugueur sans toutefois arrêter l'application.
Ce sont des notifications :
Les extensions peuvent également demander des informations complémentaires permettant de faciliter les investigations, ou destinées à tester le code dans des conditions particulières.
Pour cela, une extension peut soumettre un formulaire directement dans la liste des points d'arrêt :
Tant que le formulaire n'est pas validé, l'application reste arrêtée (relancer le processeur n'a aucun effet). Une fois les valeurs remplies et validées en cliquant sur le bouton "Submit", le formulaire se transforme en la liste des valeurs entrées :
Vous venez de voir comment utiliser les points d'arrêt étendus du débugueur.
Ces nouveaux points d'arrêt permettent de cibler efficacement les investigations en se focalisant sur les événements importants de l'application indépendamment de leur localisation dans le code.
Les extensions peuvent également interagir avec le débugueur pour apporter des compléments d'information utiles sur leur fonctionnement.