Traitement d'Exceptions : l'effet Démo en action

Le 10 avril 2003, au cours d'une démonstration de l'application ATTDAC sur le site de Grenoble une erreur s'est bien évidemment produite.

L'application est en service depuis début février 2003 et ce bug ne s'était jamais manifesté auparavant:

  • L'exception a été traitée, notée dans le journal, et présentée à l'utilisateur.
  • Il n'y a eu besoin de redémarrer ni l'application ni Windows.
  • Notre client nous a envoyé une copie du fichier automatiquement enregistré.

A partir de ce fichier, j'ai pu trouver assez facilement les causes de l'anomalie depuis mon bureau de Valence, et j'ai établi le rapport d'anomalie suivant:


Il s'agit d'un problème de collision très peu probable, mais qui peut se produire statistiquement à la fin de n'importe quelle mesure. Les symptomes seront toujours les mêmes, absence apparente d'une information dans un fichier RIF qui la contient pourtant.

Pour copier le fichier RIF à partir du catalogue workdir, j'utilise une primitive "copyfile()". Or cette primitive n'est pas "atomique", ce qui veut dire que la séquence qui conduit au bug est la suivante:

  • le thread d'acquisition appelle copyfile(), qui crée le fichier RIF
  • avant que les données aient été complètement copiées le scheduler Windows donne l'UC au thread de présentation des résultats
  • le thread de présentation constate la présence du fichier RIF, et tente de lire des données non encore écrites => Exception

J'ai effectué une correction dans ma version "prototype" en utilisant une copie vers un nom temporaire, suivi d'un rename.


Le Stack Frame de l'image ci-dessous indique que l'exception KeyError: section [specific] not found a été déclenchée par la méthode getValue( ) qui avait détecté l'erreur:

  • très exactement en ligne 243 du fichier alcos/config.py
  • appelée par la méthode __init__ en ligne 92 du fichier bktm/rthdpan.py
  • appelée par la méthode update en ligne 293 du fichier bktm/results.py
  • appelée par ...
jnl_keyerror.gif