C++ exceptions non gérées
Ne C++ offre un moyen de "montrer" quelque chose de visuel si une exception non gérée se produit?
Ce que je veux faire est de faire quelque chose comme assert(unhandled exception.msg())
si il arrive effectivement (comme dans l'exemple suivant):
void foo() {
throw std::exception("Message!");
}
int main() {
foo();
}
J'attends de ce genre de code ne pas résilier immédiatement (parce que l'exception était non gérée), plutôt montrer personnalisé affirmation message (Message!
en fait).
Est-ce possible?
Pourquoi ne pas simplement mettre un bloc try/catch dans
Mondial constructeur ou un destructeur pouvez également jeter en dehors des principales. Pour le destructeur cas, le déroulement ne pourriez pas le faire à la main.
En effet, j'étais plus préoccupé par son exemple particulier.
main
?Mondial constructeur ou un destructeur pouvez également jeter en dehors des principales. Pour le destructeur cas, le déroulement ne pourriez pas le faire à la main.
En effet, j'étais plus préoccupé par son exemple particulier.
OriginalL'auteur Yippie-Ki-Yay | 2010-09-22
Vous devez vous connecter pour publier un commentaire.
Il n'y a aucune manière spécifiée par la norme pour afficher le message de l'exception non interceptée. Toutefois, sur plusieurs plates-formes, il est possible de toute façon. Sur Windows, vous pouvez utiliser SetUnhandledExceptionFilter et tirez le C++ à l'exception de l'information. Avec g++ (les versions appropriées de toute façon), le gestionnaire peut résilier l'accès de l'exception non interceptée avec un code comme:
et en effet g++par défaut de résilier le gestionnaire fait quelque chose de semblable à cela. Vous pouvez configurer le gestionnaire de résilier avec set_terminate.
EN bref, il n'y a pas de C++ générique façon, mais il y a des manières en fonction de votre plate-forme.
unexpected
, et qui permettrait un diagnostic pour trafic illégal de jeter-sur-détendez-vous.En outre, il peut attraper les exceptions levées de mondial des constructeurs et destructeurs, qui un bloc catch dans
main
ne le peuvent pas.J'ai vu au moins une configuration où cette astuce ne fonctionne pas vraiment, je ne prétends pas être assez bien informés au sujet de la norme (et les autres choses que nous faisions avec la gestion des exceptions) à dire d'une façon ou l'autre, mais je sais que ça marche sur Linux avec un modernish gcc.
J'ai aussi trouvé qu'il y avait des situations que vous pourriez obtenir dans résilier w/o il y a une exception, j'ai donc utilisé
abi::__cxa_current_exception_type
pour savoir si il y avait un avant d'essayer de la renvoyer, et, évidemment, c'est un non-portable gccism.Non, je ne m'attends pas qu'il soit portable, dans la pratique, dans la période en cours. Eh bien, si vous aussi vous avez défini un inattendu gestionnaire, puis le renvoyer juste traduit le
terminate
dans ununexpected
. Vous pouvez ajouter un peu de logique pour continuer le long de l'gestionnaire de la chaîne (c'est à direunexpected
appelle la remplacéterminate
gestionnaire) et le reste du programme n'est pas plus sage, non?OriginalL'auteur Logan Capaldo
Microsoft Visual C++ permet de raccorder non gérée exceptions C++comme ceci. C'est standard STL comportement.
Vous définissez un gestionnaire via un appel à
set_terminate
. Il est recommandé que votre gestionnaire ne sont pas très à beaucoup de travail, et ensuite de mettre fin au programme, mais je ne vois pas pourquoi vous ne pourriez pas le signe de quelque chose via une assertion - si vous n'avez pas accès à de l'exception qui a causé le problème.printf
(ou mieux, justewrite(2)
àSTDERR_FILENO
), bien que, et d'appeler la terminate_handler il a remplacé. Aussi, voir Logan réponse et discussion sur les raisons de cette exception devrait toujours être accessible à ce point.est votre déclaration applicable dans toutes les circonstances - en d'autres termes, il serait possible d'affirmer, mais n'est pas recommandé? Merci.
Il est toujours possible de faire valoir, mais que toutes les fonctions de gestionnaire sont recommandés à la queue-appeler le gestionnaire précédemment installé.
merci
OriginalL'auteur Steve Townsend
Si vous utilisez Windows, une bonne bibliothèque pour la manipulation des exceptions non gérées et les accidents de la CrashRpt. Si vous voulez le faire manuellement vous pouvez également utilisation suivantes que j'ai écrit dans cette réponse.
OriginalL'auteur Brian R. Bondy
Je pense que vous pourriez bénéficier d'un fourre-tout énoncé comme suit:
std::exception
exemple, C++ vous permet de lancer n'importe quel type de valeur, comme unint
ou quoi que ce soit. Vous pouvez contourner ce problème en ayant également uncatch (std::exception &e)
avant lacatch (...)
, ou n'importe quel type que vous pourriez souhaiter pour l'attraper.Un bon point en effet.
Sur Windows vous devez être un peu prudent avec les (...) prendre structuré exception générée en interne (ex. violations d'accès). Il peut être dangereux de continuer l'exécution dans des conditions comme celles-ci.
Ce n'est probablement pas possible de poursuivre l'exécution de cette méthode, indépendamment de ce que l'exception s'est produite. Cette intercepte l'exception seulement après que la pile a été entièrement déroulée, tout le chemin jusqu'à
main()
. À ce stade, vous pouvez ainsiexec(argv[0])
.OriginalL'auteur Christopher Hunt
Si je suis en train de lire votre question correctement, vous vous demandez si vous pouvez surcharge
throw
(changer son comportement par défaut), donc ça fait quelque chose de défini par l'utilisateur. Non, vous ne pouvez pas.Edit: puisque vous êtes insistante :), voici une mauvaise idée™:
Encore une fois, c'est une très mauvaise idée, et c'est évidemment dépend de la plateforme, mais il fonctionne.
throw
en fait. Je veux changer le comportement par défaut lorsqu'une exception non gérée situation se produit.Donc, fondamentalement, lorsque vous
throw
une exception non gérée 😛OriginalL'auteur David Titarenco
Oui, c'est possible. Ici, vous allez:
OriginalL'auteur karlphillip
La norme c++ est le résilier gestionnaire - comme d'autres l'ont dit
Si vous êtes après mieux traceablility à jette alors c'est ce que nous faisons
Nous avons une macro à Lancer qui enregistre le nom de fichier et le numéro de ligne et le message, puis le jette. Il prend un printf style varargs message.
Je reçois un message de journal
depuis son me lancer (pas le moteur d'exécution) je ne suis pas catastrophique (pas de mémoire, pas de pile , tas de morts) mode, de sorte que le gestionnaire de travaux. Si non, alors la je suis mort de toute façon. J'utilise cette technique dans une très grande entreprise commerciale des produits (100s kloc) - sans problème. Je peux régler le niveau d'enregistrement à supprimer les frais généraux
OriginalL'auteur pm100
Si vous êtes vraiment intéressé à ce qui s'est passé à cause de votre échec du programme, vous pourriez bénéficier d'examiner le processus de l'image dans un post-mortem débogueur. La technique précise varie un peu d'un système à un, mais le train est d'abord de permettre de base de dumping, et de compiler votre programme avec les symboles de débogage. Une fois que le programme se bloque, le système d'exploitation copie de son mémoire sur le disque, et vous pouvez ensuite examiner l'état du programme au moment où il s'est écrasé.
OriginalL'auteur SingleNegationElimination