Comment mettre fin à un programme quand il se bloque? (ce qui devrait échouer un test d'unité au lieu de rester coincé à jamais)
Nos tests unitaires de déclencher les processus enfants, et parfois, ces enfants des processus de collision. Lorsque cela se produit, un rapport d'Erreurs Windows boîte de dialogue pop-up, et le processus reste actif jusqu'à ce que ce soit manuellement rejeté. Bien sûr, cela empêche les tests unitaires de jamais s'arrêter.
Comment cela peut-il être évité?
Voici un exemple de boîte de dialogue dans Win7 avec les habituels réglages:
Si je désactive le AeDebug
clé de registre, le débogage JIT option disparaît:
Si je désactive la vérification de la solution (la seule chose qui me semble avoir le contrôle via le panneau de contrôle), ça ressemble à ça, mais apparaît encore et toujours s'arrête le programme de la mort jusqu'à ce que l'utilisateur appuie sur quelque chose. WerAddExcludedApplication est documenté aussi avoir cet effet.
- Comment faites-vous appel à WerAddExcludedApplication?
- J'ai peur depuis, j'ai supprimé ma déclaration extern, et il n'y en a pas un sur pinvoke.net. Donc je ne peux pas dire exactement comment je l'ai appelé la dernière fois. Il semble être un leurre; il semble que de désactiver l'envoi du rapport, peu, pas du tout crash boîte de dialogue.
Vous devez vous connecter pour publier un commentaire.
Un résumé des réponses par jdehaan et Eric Brown, ainsi que cette question (voir aussi cette question):
N. B. Ces solutions peuvent affecter d'autres rapports d'erreurs ainsi, par exemple, l'échec de charger une DLL ou d'ouvrir un fichier.
Option 1: Désactiver globalement
Fonctionne globalement sur l'ensemble du compte d'utilisateur ou de la machine, qui peut être à la fois un avantage et un inconvénient.
Ensemble
[HKLM|HKCU]\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI
à 1.Plus d'infos: WER paramètres.
Option 2: Désactiver pour l'application
Nécessite une modification de l'plantage du programme, décrit dans la documentation des meilleures pratiques, impropres à une fonction de la bibliothèque.
Appel SetErrorMode:
SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
(ou avecSEM_FAILCRITICALERRORS
). Plus d'infos: La désactivation de l'plantage du programme de dialogue (explique l'étrange arrangement des appels).Option 2a: pour Désactiver une fonction:
Nécessite une modification de l'plantage du programme, nécessite Windows 7/2008 R2 (applications de bureau uniquement) ou supérieur, décrit dans la documenation de préférence à
SetErrorMode
, adapté pour un thread-safe fonction de la bibliothèque.Appel et réinitialiser SetThreadErrorMode:
Plus d'infos: pas beaucoup de disponibles?
Option 3: Spécifier un gestionnaire
Nécessite une modification de l'plantage du programme.
Utilisation
SetUnhandledExceptionFilter
pour définir votre propre et structurée gestionnaire d'exceptions qui se ferme simplement, avec probablement des rapports et, éventuellement, à une tentative de nettoyage.Option 4: Attraper une exception
Nécessite une modification de l'plantage du programme. Pour .NET applications seulement.
Envelopper tout le code d'un bloc try/catch. Spécifiez le
HandleProcessCorruptedStateExceptionsattribute
et peut-être aussi leSecurityCriticalAttribute
sur la méthode d'attraper les exceptions. Plus d'infos: La manipulation de l'état corrompu exceptionsNote: cela pourrait ne pas attraper des collisions causées par la Géré Assistants De Débogage; le cas échéant, elles doivent également être désactivé dans l'application.
Option 5: Arrêter le processus de présentation de rapports
Fonctionne globalement sur l'ensemble du compte d'utilisateur, mais uniquement pour contrôler la durée.
Tuer le rapport d'Erreurs Windows processus chaque fois qu'il montre:
Ce n'est pas encore complètement à l'épreuve des balles, parce que une console application peut se bloquer par un autre message d'erreur, apparemment affiché par une fonction interne appelé
NtRaiseHardError
:SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
fonctionne le mieux. @romkyns vous avez fait ma journée 🙂reg add HKLM\SYSTEM\CurrentControlSet\Control\Windows /v ErrorMode /t REG_DWORD /f /d 2
. Ils ne sont pas affectés par la DontShowUI paramètre de registre.La seule solution est d'attraper toutes les exceptions à un niveau très élevé (pour chaque thread) et de mettre fin à l'application correctement (ou effectuer une autre action).
C'est la seule façon de prévenir l'exception de s'échapper de votre application et de l'activation de WER.
Plus:
Si l'exception est quelque chose que vous n'avez pas sauf à arriver, vous pouvez utiliser un
AssertNoThrow
(NUnit) ou équivalent dans une autre Unité de Test de cadre pour encadrer le code de tir le processus enfant. De cette façon, vous obtenez également dans votre Unité de rapport d'essai. C'est à mon avis le plus propre possible solution je pense.Addition2:
Comme les commentaires ci-dessous montrent, que je me suis trompé: vous ne pouvez pas toujours prendre la asynchrones exceptions, cela dépend de ce que l'environnement le permet. Dans .NET quelques exceptions sont empêchés d'être pris, ce qui fait mon idée est inutile dans ce cas...
Pour .NET: Il y a de compliqué solutions impliquant l'utilisation de domaines d'application, conduisant à un déchargement d'un domaine d'application au lieu d'un crash de l'application dans son ensemble. Trop mauvais...
http://www.bluebytesoftware.com/blog/PermaLink,guid,223970c3-e1cc-4b09-9d61-99e8c5fae470.aspx
http://www.develop.com/media/pdfs/developments_archive/AppDomains.pdf
EDIT:
J'ai finalement obtenu. Avec .NET 4.0, Vous pouvez ajouter le
HandleProcessCorruptedStateExceptions
attribut à partir du Système.Moment de l'exécution.ExceptionServices de la méthode contenant le bloc try/catch. Cela a vraiment fonctionné! Peut-être pas recommandé, mais fonctionne./EHa
drapeau de la MSVC++ compilateur voir, par exemple, msdn.microsoft.com/en-us/library/1deeycx5.aspx). Le devenir technique, la question n'est pas de langue plus agnostique. Dans .NET, vous pouvez attraper ces exceptions, sans tordre autour de.StackOverflowException
peut capturés à l'aide deHandleProcessCorruptedStateExceptions
. Malheureusement, ce n'est pas vrai, il ne sera pas pris (essayer). Certains autres du CST sont pris bien.Essayez de définir
à 1. (Vous pouvez également définir la même clé dans la clé HKLM, mais vous avez besoin d'admin privs de le faire.)
Ce qui devrait éviter WER de montrer de l'INTERFACE utilisateur.