Je veux avoir un moyen de signaler la trace de la pile à l'utilisateur si une exception est levée. Quelle est la meilleure façon de procéder? Faut-il d'énormes quantités de code supplémentaire?
Pour répondre aux questions:
J'aimerais que ce soit portable si possible. Je souhaite que des informations apparaissent, afin que l'utilisateur puisse copier la trace de la pile et m'envoyer un e-mail en cas d'erreur.
Linux
notgcc
.libstdc++
(utilisé par GCC et potentiellement Clang) comme expliqué dans cette réponse .La réponse d'Andrew Grant n'aide pas à obtenir une trace de pile de la fonction de lancement , du moins pas avec GCC, car une instruction throw n'enregistre pas la trace de pile actuelle seule, et le gestionnaire de capture n'aura pas accès à la trace de pile à ce point plus.
La seule façon - en utilisant GCC - de résoudre ce problème est de vous assurer de générer une trace de pile au point de l'instruction throw et de l'enregistrer avec l'objet d'exception.
Cette méthode nécessite, bien sûr, que chaque code qui lève une exception utilise cette classe d'exception particulière.
Mise à jour du 11 juillet 2017 : pour un code utile, jetez un œil à la réponse de cahit beyaz, qui pointe vers http://stacktrace.sourceforge.net - je ne l'ai pas encore utilisé mais cela semble prometteur.
la source
throw stack_runtime_error
. Ai-je raison de déduire que cette bibliothèque ne fonctionne que pour les exceptions dérivées de cette classe, et non pour lesstd::exception
exceptions de bibliothèques tierces?Si vous utilisez Boost 1.65 ou supérieur, vous pouvez utiliser boost :: stacktrace :
la source
Unix: backtrace
Mac: trace
Windows: CaptureBackTrace
la source
Je voudrais ajouter une option de bibliothèque standard (c'est-à-dire multiplateforme) comment générer des backtraces d'exception, qui est devenue disponible avec C ++ 11 :
Utiliser
std::nested_exception
etstd::throw_with_nested
Cela ne vous permettra pas de vous détendre, mais à mon avis, la meilleure chose à faire. Il est décrit sur StackOverflow ici et ici , comment vous pouvez obtenir une trace arrière sur vos exceptions dans votre code sans avoir besoin d'un débogueur ou d'une journalisation encombrante, en écrivant simplement un gestionnaire d'exceptions approprié qui renverra les exceptions imbriquées.
Puisque vous pouvez le faire avec n'importe quelle classe d'exception dérivée, vous pouvez ajouter beaucoup d'informations à une telle trace! Vous pouvez également jeter un oeil à mon MWE sur GitHub , où une trace ressemblerait à quelque chose comme ceci:
la source
AFAIK libunwind est assez portable et jusqu'à présent je n'ai rien trouvé de plus facile à utiliser.
la source
Je recommande le projet http://stacktrace.sourceforge.net/ . Il prend en charge Windows, Mac OS et aussi Linux
la source
throw stack_runtime_error
. Ai-je raison de déduire que cette bibliothèque ne fonctionne que pour les exceptions dérivées de cette classe, et non pour lesstd::exception
exceptions de bibliothèques tierces?Si vous utilisez C ++ et que vous ne voulez pas / ne pouvez pas utiliser Boost, vous pouvez imprimer une trace arrière avec des noms démangés en utilisant le code suivant [lien vers le site d'origine] .
Notez que cette solution est spécifique à Linux. Il utilise les fonctions libc de GNU backtrace () / backtrace_symbols () (from execinfo.h) pour obtenir les backtraces, puis utilise __cxa_demangle () (from cxxabi.h) pour démêler les noms des symboles de backtrace.
HTH!
la source
sur linux avec g ++ consultez cette lib
https://sourceforge.net/projects/libcsdbg
il fait tout le travail pour vous
la source
Sous Windows, consultez BugTrap . Ce n'est plus au lien d'origine, mais il est toujours disponible sur CodeProject.
la source
J'ai un problème similaire, et bien que j'aime la portabilité, je n'ai besoin que du support gcc. Dans gcc, execinfo.h et les appels de trace sont disponibles. Pour démêler les noms de fonction, M. Bingmann a un joli morceau de code. Pour vider une trace arrière sur une exception, je crée une exception qui imprime la trace arrière dans le constructeur. Si je m'attendais à ce que cela fonctionne avec une exception levée dans une bibliothèque, cela pourrait nécessiter une reconstruction / liaison afin que l'exception de retour en arrière soit utilisée.
La compilation et l'exécution de ceci avec gcc 4.8.4 donne une trace avec des noms de fonction C ++ bien démêlés:
la source
Étant donné que la pile est déjà déroulée lors de l'entrée dans le bloc catch, la solution dans mon cas était de ne pas intercepter certaines exceptions qui conduisent ensuite à un SIGABRT. Dans le gestionnaire de signaux pour SIGABRT, puis fork () et execl () soit gdb (dans les versions de débogage) ou Google breakpads stackwalk (dans les versions de version). J'essaie également d'utiliser uniquement les fonctions de sécurité du gestionnaire de signaux.
GDB:
minidump_stackwalk:
Edit: Pour le faire fonctionner pour le breakpad, j'ai également dû ajouter ceci:
Source: Comment obtenir une trace de pile pour C ++ en utilisant gcc avec des informations sur le numéro de ligne? et est-il possible d'attacher gdb à un processus en panne (aka débogage "juste à temps")
la source
Poppy peut rassembler non seulement la trace de la pile, mais aussi les valeurs des paramètres, les variables locales, etc. - tout ce qui mène au crash.
la source
Le code suivant arrête l'exécution juste après la levée d'une exception. Vous devez définir un windows_exception_handler avec un gestionnaire de terminaison. J'ai testé cela en MinGW 32bits.
Vérifiez le code suivant pour la fonction windows_exception_handler: http://www.codedisqus.com/0ziVPgVPUk/exception-handling-and-stacktrace-under-windows-mingwgcc.html
la source
Cpp-tool ex_diag - poids léger, multiplateforme, utilisation minimale des ressources, simple et flexible à la trace.
la source