Existe-t-il un équivalent c ++ de Java
try {
...
}
catch (Throwable t) {
...
}
J'essaie de déboguer du code Java / jni qui appelle des fonctions Windows natives et la machine virtuelle continue de planter. Le code natif apparaît bien dans les tests unitaires et ne semble planter que lorsqu'il est appelé via jni. Un mécanisme générique de capture d'exceptions s'avérerait extrêmement utile.
Réponses:
va intercepter toutes les exceptions C ++, mais il doit être considéré comme une mauvaise conception. Vous pouvez utiliser le nouveau mécanisme current_exception de c ++ 11, mais si vous n'avez pas la possibilité d'utiliser c ++ 11 (systèmes de code hérités nécessitant une réécriture), vous n'avez aucun pointeur d'exception nommé à utiliser pour obtenir un message ou un nom. . Vous souhaiterez peut-être ajouter des clauses catch distinctes pour les diverses exceptions que vous pouvez intercepter, et intercepter uniquement tout en bas pour enregistrer une exception inattendue. Par exemple:
la source
Quelqu'un devrait ajouter que l'on ne peut pas intercepter les "plantages" dans le code C ++. Ceux-ci ne lèvent pas d'exceptions, mais font tout ce qu'ils veulent. Lorsque vous voyez un programme se bloquer en raison, par exemple, d'une déréférence de pointeur nul, il fait un comportement non défini. Il n'y en a pas
std::null_pointer_exception
. Essayer d'attraper des exceptions n'y aidera pas.Juste pour le cas où quelqu'un lit ce fil et pense qu'il peut obtenir la cause des plantages du programme. Un débogueur comme gdb devrait être utilisé à la place.
la source
try { .. } catch(...) { ... }
capture en utilisant signal / sigaction, je ne l'appellerais pas "capture" :) Si dans un gestionnaire de signal, il est relativement difficile pour le programmeur de savoir où dans le code le crash s'est produit (je parle à propos de la détection par programme), par rapport à try / catch.Voici comment vous pouvez effectuer une rétro-ingénierie du type d'exception de l'intérieur
catch(...)
si vous en avez besoin (peut être utile lors de la capture d'un inconnu dans une bibliothèque tierce) avec GCC:et si vous pouvez vous permettre d'utiliser Boost, vous pouvez rendre votre section de capture encore plus simple (à l'extérieur) et potentiellement multiplateforme
la source
Notez que l'
...
intérieur ducatch
est une vraie ellipse, c'est-à-dire. trois points.Cependant, comme les exceptions C ++ ne sont pas nécessairement des sous-classes d'une
Exception
classe de base , il n'existe aucun moyen de voir réellement la variable d'exception levée lors de l'utilisation de cette construction.la source
catch
spécificateur de l'espace réservé de code existant dans un commentaire (// ...
) qui n'est évidemment pas la syntaxe C ++.il n'est pas possible (en C ++) d'intercepter toutes les exceptions de manière portable. En effet, certaines exceptions ne sont pas des exceptions dans un contexte C ++. Cela inclut des choses comme la division par zéro erreur et autres. Il est possible de pirater et d'obtenir ainsi la possibilité de lever des exceptions lorsque ces erreurs se produisent, mais ce n'est pas facile à faire et certainement pas facile à corriger de manière portable.
Si vous voulez intercepter toutes les exceptions STL, vous pouvez le faire
Ce qui vous permettra d'utiliser
e.what()
, qui renverra unconst char*
, qui peut vous en dire plus sur l'exception elle-même. C'est la construction qui ressemble le plus à la construction Java, vous avez demandé le plus.Cela ne vous aidera pas si quelqu'un est assez stupide pour lancer une exception qui n'hérite pas
std::exception
.la source
En bref, utilisez
catch(...)
. Cependant, notez que celacatch(...)
est destiné à être utilisé conjointement avecthrow;
essentiellement:C'est la bonne façon de l'utiliser
catch(...)
.la source
Foo
le destructeur? Je pensais que c'était tout l'intérêt de RAII. Cependant, si vous avez besoin d'un pointeur sur unFoo
plutôt que de simplement le créerFoo
sur la pile, vous devrez envelopper le pointeur dans quelque chose d'autre qui est déclaré sur la pile.il est possible de le faire en écrivant:
Mais il y a un risque très peu visible ici: vous ne pouvez pas trouver le type d'erreur exact qui a été jeté dans le
try
bloc, alors utilisez ce genre decatch
lorsque vous êtes sûr que quel que soit le type d'exception, le programme doit persister de la manière définie dans lecatch
bloc.la source
Vous pouvez utiliser
mais c'est très dangereux. Dans son livre Debugging Windows , John Robbins raconte une histoire de guerre à propos d'un bug vraiment méchant qui était masqué par une commande catch (...). Il vaut mieux attraper des exceptions spécifiques. Attrapez tout ce que vous pensez que votre bloc try peut raisonnablement lever, mais laissez le code lever une exception plus haut si quelque chose de vraiment inattendu se produit.
la source
Permettez-moi de mentionner ceci ici: le Java
peut ne PAS attraper toutes les exceptions! J'ai déjà vu ce genre de choses se produire auparavant, et cela provoque de l'insante; L'exception dérive de Throwable. Donc, littéralement, pour tout attraper, vous ne voulez PAS attraper d'exceptions; vous voulez attraper Throwable.
Je sais que cela semble compliqué, mais lorsque vous avez passé plusieurs jours à essayer de comprendre d'où provenait "l'exception non capturée" dans le code qui était entouré d'un bloc try ... catch (Exception e) " tu.
la source
catch(Exception)
peut que toutes les exceptions ne soient pas détectées en Java, vous le mélangez avec C # ... Java =catch(Thowable)
, C # =catch(Exception)
. Ne les confondez pas.CoderMalfunctionError
(qui est en fait une vraieError
sous-classe Java ... bien que cela ne signifie pas à quoi elle ressemble.)Eh bien, si vous souhaitez intercepter toutes les exceptions pour créer un minidump par exemple ...
Quelqu'un a fait le travail sur Windows.
Voir http://www.codeproject.com/Articles/207464/Exception-Handling-in-Visual-Cplusplus Dans l'article, il explique comment il a découvert comment intercepter toutes sortes d'exceptions et il fournit du code qui fonctionne.
Voici la liste que vous pouvez attraper:
Et l'utilisation: CCrashHandler ch; ch.SetProcessExceptionHandlers (); // faire cela pour un thread ch.SetThreadExceptionHandlers (); // pour chaque lancer
Par défaut, cela crée un minidump dans le répertoire courant (crashdump.dmp)
la source
Douteux. Vous savez déjà que votre code est cassé, car il plante. Manger des exceptions peut masquer cela, mais cela entraînera probablement des bogues encore plus méchants et plus subtils.
Ce que vous voulez vraiment, c'est un débogueur ...
la source
Pouvez-vous exécuter votre application Java utilisant JNI à partir d'une fenêtre de console (lancez-la à partir d'une ligne de commande java) pour voir s'il existe un rapport de ce qui a pu être détecté avant que la JVM ne plante. Lors de l'exécution directe en tant qu'application de fenêtre Java, il se peut que des messages n'apparaissent pas si vous exécutez à partir d'une fenêtre de console à la place.
Deuxièmement, pouvez-vous bloquer votre implémentation de DLL JNI pour montrer que les méthodes de votre DLL sont entrées à partir de JNI, que vous revenez correctement, etc.?
Juste au cas où le problème proviendrait d'une utilisation incorrecte de l'une des méthodes d'interface JNI du code C ++, avez-vous vérifié que quelques exemples JNI simples se compilent et fonctionnent avec votre configuration? Je pense en particulier à utiliser les méthodes de l'interface JNI pour convertir les paramètres au format C ++ natif et transformer les résultats des fonctions en types Java. Il est utile de les bloquer pour vous assurer que les conversions de données fonctionnent et que vous ne vous trompez pas dans les appels de type COM dans l'interface JNI.
Il y a d'autres choses à vérifier, mais il est difficile d'en suggérer sans en savoir plus sur vos méthodes Java natives et ce que leur implémentation JNI essaie de faire. Il n'est pas clair que la capture d'une exception au niveau du code C ++ est liée à votre problème. (Vous pouvez utiliser l'interface JNI pour renvoyer l'exception comme Java, mais il n'est pas clair d'après ce que vous fournissez que cela va aider.)
la source
Pour le vrai problème lié à l'impossibilité de déboguer correctement un programme qui utilise JNI (ou le bogue n'apparaît pas lors de son exécution sous un débogueur):
Dans ce cas, il est souvent utile d'ajouter des wrappers Java autour de vos appels JNI (c'est-à-dire que toutes les méthodes natives sont privées et que vos méthodes publiques de la classe les appellent) qui effectuent une vérification de base de la justesse (vérifiez que tous les "objets" sont libérés et les "objets" ne sont pas utilisés après la libération) ou la synchronisation (il suffit de synchroniser toutes les méthodes d'une DLL vers une seule instance d'objet). Laissez les méthodes du wrapper java enregistrer l'erreur et lever une exception.
Cela aidera souvent à trouver la vraie erreur (qui est étonnamment la plupart du temps dans le code Java qui n'obéit pas à la sémantique des fonctions appelées provoquant des doubles libérations désagréables ou similaires) plus facilement que d'essayer de déboguer un programme Java massivement parallèle dans un débogueur natif ...
Si vous connaissez la cause, conservez le code dans vos méthodes d'encapsuleur qui l'évite. Mieux vaut que vos méthodes wrapper lèvent des exceptions que votre code JNI plante la VM ...
la source
Eh bien, cela dépend vraiment de l'environnement du compilateur. gcc ne les attrape pas. Visual Studio et le dernier Borland que j'ai utilisé l'ont fait.
La conclusion à propos des plantages est donc que cela dépend de la qualité de votre environnement de développement.
La spécification C ++ indique que catch (...) doit intercepter toutes les exceptions, mais ce n'est pas le cas dans tous les cas.
Du moins d'après ce que j'ai essayé.
la source
Être conscient
n'attrape que les exceptions au niveau de la langue, d'autres exceptions / erreurs de bas niveau comme
Access Violation
etSegmentation Fault
ne seront pas interceptées.la source