web-dev-qa-db-fra.com

Que dois-je savoir sur les exceptions structurées (SEH) en C ++?

Quels points importants sur les exceptions structurées chaque développeur C++ doit-il connaître?

43
Andrew T

Ils sont l'équivalent Win32 des signaux Unix et vous permettent de détecter des exceptions de processeur telles qu'une violation d'accès, une instruction illégale, une division par zéro.

Avec les bonnes options du compilateur (/ EHa pour Visual C++), les exceptions C++ utilisent le même mécanisme que le déroulement de pile fonctionne correctement pour les exceptions C++ (utilisateur) et SEH (OS).

Contrairement aux exceptions C++, SEH ne sont pas typées mais partagent toutes la même structure de données qui a un code d'exception (la cause) et des informations supplémentaires sur le code défaillant et ce que les registres du CPU contenaient au moment de la défaillance. Voir GetExceptionCode et GetExceptionInformation pour plus de détails à ce sujet.

En outre, SEH a une gestion "à la première chance", qui vous permet de consigner ou de gérer autrement l'exception avant le déroulement détruit toutes les variables locales.

41
Ben Voigt

J'ai récemment eu un problème causé indirectement par SEH, en particulier à cause d'une caractéristique de SEH dont je pense que chaque développeur devrait être conscient:

Lorsque SEH est utilisé, les destructeurs ne sont pas appelés, donc si vous avez du code de nettoyage dans votre destructeur, il ne sera pas nettoyé.

Notre problème a été provoqué par une section critique qui a été enveloppée par un objet avec Lock dans le constructeur et Unlock dans le destructeur.

Nous avons eu une situation de blocage et nous ne pouvions pas comprendre pourquoi, et après environ une semaine de fouille dans le code et les vidages et le débogage, nous avons finalement compris que c'était parce qu'il y avait une exception qui était gérée par COM et qui faisait que la section Critique restait verrouillée. . Nous avons changé un indicateur de compilation dans VS dans les propriétés du projet qui lui indique d'exécuter des destructeurs même pour SEH et cela a résolu le problème.

Ainsi, même si vous n'utilisez pas SEH dans votre code, vous utilisez peut-être une bibliothèque qui le fait (comme COM) et qui peut provoquer un comportement inattendu.

32
Tidhar

Ils doivent savoir qu'ils ne font pas partie du C++ standard - ils sont une invention de Microsoft et peuvent être utilisés dans des langages autres que C++.

24
anon

n cours intensif sur les profondeurs de la gestion des exceptions structurées Win32 ™

Cet article est la référence pour se familiariser avec SEH. 13 ans plus tard, c'est toujours le meilleur qui soit.

Il y a un sujet dédié sur MSDN pour SEH vs différences de gestion des exceptions C++ .

Un développeur C++ doit savoir si SEH est en discussion:

Écriture de C/C++ SEH gestionnaires d'exceptions :

__try 
{
   // guarded code
}
__except ( expression )
{
   // exception handler code
}

Ce n'est pas la gestion des exceptions C++, c'est les extensions spécifiques à MS pour accrocher directement dans SEH. Cela fonctionne très différemment de vos exceptions C++ courantes. Vous avez besoin d'une bonne compréhension de SEH pour les utiliser.

Écriture de C/C++ SEH gestionnaires de terminaison :

__try {
   // guarded code
}
__finally ( expression ) {
   // termination code
}

Comme avec le gestionnaire SEH, ne confondez pas cela avec la sémantique d'exception C++. Vous avez besoin d'une bonne compréhension de SEH.

_set_se_trasnlator : c'est la fonction qui traduit les exceptions SEH en exceptions de type C++ lorsque des exceptions asynchrones sont utilisées / EHa .

Et enfin, une opinion personnelle: un développeur C++ devrait-il connaître SEH? Après votre première recrue . Ecxr vous comprendrez que lorsque le Push arrive à pousser les exceptions C++ ne sont qu'une illusion fournie pour votre commodité. La seule chose qui se passe est SEH.

20
Remus Rusanu

Un point important est de savoir quand utiliser SEH et quand utiliser les exceptions C++ standard. Tout d'abord, choisissez un seul système - les systèmes de mélange ont tendance à être problématiques, nécessitant une compréhension approfondie des deux pour bien fonctionner. Deuxièmement, à un niveau élevé, SEH n'est pas limité à C++, tandis que les exceptions C++ standard ne sont pas limitées à Windows. Si cela ne dicte pas votre décision, choisissez des exceptions standard à moins qu'elles ne soient inadéquates (voir les autres réponses pour plus de détails sur ce que SEH peut faire).

Une citation de documentation de Microsoft (datée du 13/08/2018) confirme cette conclusion.

La gestion structurée des exceptions (SEH) est une extension Microsoft de C pour gérer gracieusement certaines situations de code exceptionnelles, telles que des erreurs matérielles. Bien que Windows et Microsoft C++ prennent en charge SEH, nous vous recommandons d'utiliser la gestion des exceptions C++ standard ISO car cela rend votre code plus portable et flexible. Néanmoins, pour conserver le code existant ou pour des types de programmes particuliers, vous devrez peut-être encore utiliser SEH.

Pourquoi l'auteur d'une extension recommande-t-il de ne pas l'utiliser dans la plupart des cas? Vraisemblablement parce que l'extension a été écrite pour C et que le contexte actuel est C++. Les langages sont similaires, donc le portage de SEH en C++ comme avantage secondaire était probablement assez facile, même si seuls "des types de programmes particuliers" en bénéficieraient vraiment. (Ou peut-être pour une autre raison; peut-être que le portage a été commencé avant que C++ ne soit standardisé. L'historique est compliqué.)

1
JaMiT