• Aucun résultat trouvé

Pour aider à la mise au point du modèle du système, diverses activités d’analyse peuvent être menées durant les phases de conception amont dont la simulation interactive, le débogage multivers et la détection de deadlocks. Ces activités permettent en général de détecter des erreurs de conception et de mettre en évidence certaines incohérences lors de l’exécution du modèle.

5.3.1 Simulation interactive

La simulation interactive permet d’explorer différentes traces d’exécution et de visualiser l’évolution des données d’exécution. Pour y parvenir, il est nécessaire de pouvoir piloter l’exé-cution du modèle en demandant dans chaque configuration la liste des pas d’exél’exé-cution dis-ponibles. Cette liste est ensuite exposée à l’utilisateur qui choisit le pas d’exécution devant être exécuté. Avec la fonctionnalité de retour en arrière (ou en anglais back-in-time), il est également possible de replacer l’interpréteur dans une configuration donnée et de reprendre

5.3. Simulation, débogage, et détection de deadlocks

l’exécution à partir de ce point. Ce mécanisme permet de facilement revenir en arrière sans avoir à redémarrer le moteur d’exécution.

En ce qui concerne la visualisation, il est nécessaire de construire une projection de la configuration et des pas d’exécution disponibles sur l’interface graphique. Dans ce but, une nouvelle interface P a été définie en Lean. Elle se base sur deux nouveaux types :Vc la vue d’une configuration etVa la vue d’une action.

Définition 5.1. L’interface P (Projection) permet d’obtenir une projection des configurations et des actions dans les termes du langage de modélisation. Elle est définie par :

structure P (C A : Type) :=

(projectC : C → Vc) (projectA : A → Va)

Listing 5.1 – Interface P.

Dans cette interface P, projectC permet de projeter une configuration C sur une vue Vc et projectA permet de projeter une action A sur une vue Va avec Vc et Va des vues de l’in-terface graphique de l’outil d’analyse. Étant donné que l’approche EMI vise la conception d’un interpréteur embarqué, la construction de ces vues doit être faite hors de l’interpréteur afin de ne pas accroître l’empreinte mémoire ou d’impacter les performances d’exécution. Dans notre approche, cette tâche est réalisée par un serveur de langages qui servira d’intermédiaire entre l’outil d’analyse et l’interpréteur de modèles.

5.3.2 Débogage multivers

Le débogage multivers a été introduit par [Tor+19] comme la possibilité de définir des points d’arrêts qui peuvent mettre en pause l’exécution du système dans différents chemins d’exécu-tion, appelés univers. Cette fonctionnalité est intéressante pour les interpréteurs EMI afin de permettre le débogage de modèles ayant des exécutions concurrentes.

Pour mener cette activité, des points d’arrêts conditionnels doivent être définis. Les condi-tions de ces points d’arrêt sont définies comme des prédicats portant sur l’exécution du sys-tème. Un langage, que nous appellerons langage d’observation, est alors nécessaire pour pouvoir spécifier ces prédicats aussi appelés propositions atomiques. Une fois exprimés, ces prédicats sont ensuite évalués dans chaque nouvelle configuration explorée et le résultat de leur évaluation est indiqué à l’utilisateur. L’évaluation de ces expressions nécessite non seule-ment l’accès aux données d’exécution du modèle mais aussi la connaissance de la sémantique du langage (p. ex. pour appeler une fonction). Pour effectuer cette tâche, une fonction d’éva-luation est donc également nécessaire pour déléguer l’évad’éva-luation d’une proposition atomique

à l’interpréteur EMI. Cette technique permet ainsi de réutiliser la même sémantique opération-nelle que pour l’exécution de modèles.

Pour définir cette fonction d’évaluation, l’interface de contrôle d’exécution doit être enrichie avec une nouvelle interface appelée APE. Pour cette définition,L est le type des étiquettes (en anglais labels) aussi appelées propositions atomiques ou atomes.

Définition 5.2. L’interface APE (Atomic Proposition Evaluator ) qui permet d’évaluer une propo-sition atomique (L) sur un pas d’exécution (C → A → C) est définie par :

structure APE (C A L : Type) :=

(eval : L → C → A → C → bool)

Listing 5.2 – Interface APE

Avec ce mécanisme, le débogage multivers peut facilement être supporté en utilisant un algorithme d’atteignabilité afin d’explorer l’espace d’état jusqu’à ce que l’un des prédicats de-vienne vrai (ou faux). Tous les chemins issus de la configuration courante sont donc explorés simultanément. Le premier qui atteint une configuration déclenchant l’un des points d’arrêt conditionnels est exposé à l’utilisateur afin qu’il visualise ce qu’il cherche à déboguer. Si les points d’arrêts ne sont jamais déclenchés, il faut attendre l’exploration complète de l’espace d’état pour le notifier à l’utilisateur. En considérantp la condition d’un point d’arrêt conditionnel, l’algorithme de débogage multivers est équivalent à vérifier par model-checking la propriété LTL"[] !p" indiquant que globalement p est faux. Dès que p devient vrai, un contre-exemple est trouvé et l’état dans lequel se trouve l’exécution du modèle correspond à l’état recherché.

D’un point de vue plus théorique, ces travaux de thèse proposent une formalisation du dé-bogage multivers interactif via les Listings 5.3 et 5.4. Cette définition formelle s’appuie sur une configuration de débogage (DebugConfig) et des actions de débogage (DebugAction) comme le montre le Listing 5.3. La configuration de débogage correspond aux données d’exécution stockées par le débogueur. Elle contient la configuration courante (current), l’ensemble des configurations déjà explorées (trace), et l’ensemble des successeurs (options) c.-à-d. l’en-semble des configurations pouvant être atteintes à partir de la configuration courante avec un seul pas d’exécution. Grâce à ces informations, l’utilisateur peut réaliser différentes actions de débogage permettant d’exécuter un pas à partir de la configuration courante (step), de sé-lectionner une configuration parmi l’ensemble des successeurs (select), de retourner dans une configuration déjà explorée (jump) ou de lancer un algorithme de débogage multivers jus-qu’à un point d’arrêt (run_to_breakpoint). C’est la raison pour laquelle on parle de débogage multivers interactif car c’est l’utilisateur qui joue le rôle du contrôleur d’exécution mais il peut déléguer ce rôle à l’algorithme de débogage multivers pour atteindre des points d’arrêt.

5.3. Simulation, débogage, et détection de deadlocks

structure DebugConfig (C : Type) :=

(current : option C) (trace : set C) (options : set C)

inductive DebugAction {C A : Type} | step : A → DebugAction

| select : C → DebugAction | jump : C → DebugAction

| run_to_breakpoint : DebugAction

Listing 5.3 – Définition des types utilisés en débogage multivers.

À partir de ces définitions formelles, le Listing 5.4 définit un opérateur appelé interactive_ multivers_debugging permettant de transformer une STR en une STR pour le débogage mul-tivers interactif. Cet opérateur prend en entrée la STR concernée (str), la fonction permettant de retrouver la trace du contre-exemple (find_counter example) et la liste des points d’arrêt considérés (breakpoints).

La STR résultante contient un unique état de débogage initial dans lequel l’état courant n’est pas défini (current := none), la trace est vide (trace := ∅) et l’ensemble des confi-gurations initiales de la STR est placé dans le champoptions (options := str.initial). À partir de cet état initial, les seules actions possibles correspondent à la sélection de l’une des configurations initiales de la STR (cas oùdc.current = none). Si une configuration courante est déjà sélectionnée (cas oùdc.current = (some c)), diverses actions de débogage sont possibles. La Figure 5.1 illustre ces différentes actions sur un automate très simple ayant sa configuration initiale en noir. À partir de la configuration courante (en gris foncé), il est possible de faire un pas (oa := {step1, step2}), de retourner sur l’une des configurations apparte-nant à la trace en faisant unjump (ja := {jump1, jump2}) ou de lancer l’algorithme de débo-gage multivers (run_to_breakpoint). En résumé, l’ensemble des actions ne correspond plus seulement aux pas exécutables (step) mais à l’ensemble des actions pouvant être réalisées par l’utilisateur (step, select, jump et run_to_breakpoint). De même, le champ execute de la nouvelle STR permet non seulement d’exécuter des pas mais aussi d’effectuer différentes actions de débogage tout en mettant à jour la configuration courante de débogage et la trace. Le Listing 5.4 présente la combinatoire des différents cas possibles selon l’action de débogage devant être exécutée et si la configuration courante de débogage est définie ou non. On peut notamment remarquer que l’exécution de l’algorithme de débogage multivers doit reconstruire la trace du contre-exemple si un point d’arrêt est atteint.

FIGURE5.1 – Présentation des actions de débogage disponibles.

def interactive_multiverse_debugging (str : STR C A)

(find_counterexample : set C → STR C A → set C → list C) (breakpoints : set C)

: STR (DebugConfig C) (@DebugAction C A) := { initial := { { DebugConfig . current := none,

trace := ∅, options := str.initial } }, actions := λ dc, match dc.current with

| (some c) := let oa := { x : @DebugAction C A | ∀ a ∈ str.actions c, x = DebugAction.step a }, ja := { x : @DebugAction C A | ∀ c ∈ dc.trace, x = DebugAction.jump c } in oa ∪ ja ∪ { DebugAction.run_to_breakpoint }

| none := { sa | ∀ c ∈ dc.options, sa = DebugAction.select c }

end,

execute := λ dc da, match dc.current, da with

| (some c), (DebugAction.step a) := {{ DebugConfig . current := none, trace := dc.trace, options := str.execute c a}}

| (none) , (DebugAction.step a) := ∅

| _ , (DebugAction.select c) := {{ DebugConfig . current := c, trace := {c} ∪ dc.trace, options := ∅ }}

| _ , (DebugAction.jump c) := {{ DebugConfig . current := c, trace := {c} ∪ dc.trace, options := ∅ }}

| (some c), (DebugAction.run_to_breakpoint) :=

match (find_counterexample { c } str breakpoints) with