Gestion des exceptions

Le système d’exploitation utilise la gestion structurée des exceptions pour signaler certains types d’erreurs. Une routine appelée par un pilote peut déclencher une exception que le pilote doit gérer.

Le système intercepte les types généraux d’exceptions suivants :

  1. Erreurs ou interruptions définies par le matériel, telles que ,

    • Violations d’accès (voir ci-dessous)
    • Désalignements de type de données (par exemple, une entité 16 bits alignée sur une limite d’octets impairs)
    • Instructions non valides et privilégiées
    • Séquences de verrous non valides (tentative d’exécution d’une séquence d’instructions non valides dans une section verrouillée du code)
    • L’entier divise par zéro et dépasse
    • Divise à virgule flottante par zéro, dépassements, sous-flux et opérandes réservés
    • Points d’arrêt et exécution en étape unique (pour prendre en charge les débogueurs)
  2. Exceptions définies par logiciel système, telles que ,

    • Violations de la page de protection (tentative de chargement ou de stockage de données à partir de ou vers un emplacement dans une page de protection)
    • Erreurs de lecture de page (tentative de lecture d’une page en mémoire et rencontre une erreur d’E/S simultanée)

Une violation d’accès est une tentative d’exécution d’une opération sur une page qui n’est pas autorisée dans les paramètres de protection de page actuels. Les violations d’accès se produisent dans les situations suivantes :

  • Opération de lecture ou d’écriture non valide, telle que l’écriture dans une page en lecture seule.

  • Pour accéder à la mémoire au-delà de la limite de l’espace d’adressage du programme actuel (appelée violation de longueur).

  • Pour accéder à une page actuellement résidente, mais dédiée à l’utilisation d’un composant système. Par exemple, le code en mode utilisateur n’est pas autorisé à accéder à une page que le noyau utilise.

Si une opération peut provoquer une exception, le pilote doit placer l’opération dans un bloc try/except . Les accès aux emplacements en mode utilisateur sont des causes classiques d’exceptions. Par exemple, la routine ProbeForWrite vérifie que le pilote peut réellement écrire dans une mémoire tampon en mode utilisateur. Si ce n’est pas le cas, la routine déclenche une exception STATUS_ACCESS_VIOLATION. Dans l’exemple de code suivant, le pilote appelle ProbeForWrite dans un try/except afin qu’il puisse gérer l’exception résultante, le cas échéant.

try {
    ...
    ProbeForWrite(Buffer, BufferSize, BufferAlignment);
 
    /* Note that any access (not just the probe, which must come first,
     * by the way) to Buffer must also be within a try-except.
     */
    ...
} except (EXCEPTION_EXECUTE_HANDLER) {
    /* Error handling code */
    ...
}

Les pilotes doivent gérer toutes les exceptions levées. Une exception qui n’est pas gérée entraîne un bogue du système case activée. Le pilote qui provoque la levée de l’exception doit la gérer : un pilote de niveau inférieur ne peut pas s’appuyer sur un pilote de niveau supérieur pour gérer l’exception.

Les pilotes peuvent déclencher directement une exception à l’aide des routines ExRaiseAccessViolation, ExRaiseDatatypeMisalignment ou ExRaiseStatus . Le pilote doit gérer toutes les exceptions que ces routines déclenchent.

Voici une liste partielle de routines qui, au moins dans certaines situations, peuvent déclencher une exception :

Les accès à la mémoire mémoire aux mémoires tampons en mode utilisateur peuvent également entraîner des violations d’accès. Pour plus d’informations, consultez Erreurs dans le référencement d’adresses User-Space.

Notez que la gestion structurée des exceptions est distincte des exceptions C++. Le noyau ne prend pas en charge les exceptions C++.

Pour plus d’informations sur la gestion structurée des exceptions, consultez la Microsoft Windows SDK et la documentation Visual Studio.