Ich möchte eine Möglichkeit haben, den Stack-Trace dem Benutzer zu melden, wenn eine Ausnahme ausgelöst wird. Was ist der beste Weg, dies zu tun? Benötigt es große Mengen an zusätzlichem Code?
Fragen beantworten:
Ich möchte, dass es wenn möglich tragbar ist. Ich möchte, dass Informationen angezeigt werden, damit der Benutzer den Stack-Trace kopieren und per E-Mail an mich senden kann, wenn ein Fehler auftritt.
Linux
nicht istgcc
.libstdc++
(von GCC und möglicherweise Clang verwendet) überschreiben, wie in dieser Antwort erläutert .Die Antwort von Andrew Grant hilft nicht , eine Stapelverfolgung der Wurffunktion zu erhalten , zumindest nicht mit GCC, da eine throw-Anweisung die aktuelle Stapelverfolgung nicht alleine speichert und der catch-Handler keinen Zugriff auf die Stapelverfolgung bei hat dieser Punkt nicht mehr.
Die einzige Möglichkeit, dies mithilfe von GCC zu lösen, besteht darin, am Punkt der Wurfanweisung eine Stapelverfolgung zu generieren und diese mit dem Ausnahmeobjekt zu speichern.
Diese Methode erfordert natürlich, dass jeder Code, der eine Ausnahme auslöst, diese bestimmte Ausnahmeklasse verwendet.
Update 11. Juli 2017 : Einen hilfreichen Code finden Sie in der Antwort von cahit beyaz, die auf http://stacktrace.sourceforge.net verweist. Ich habe ihn noch nicht verwendet, aber er sieht vielversprechend aus.
quelle
throw stack_runtime_error
. Kann ich zu Recht feststellen, dass diesestd::exception
Bibliothek nur für Ausnahmen funktioniert, die von dieser Klasse abgeleitet sind, und nicht für oder Ausnahmen von Bibliotheken von Drittanbietern?Wenn Sie Boost 1.65 oder höher verwenden, können Sie boost :: stacktrace verwenden :
quelle
Unix: Backtrace
Mac: Rückverfolgung
Windows: CaptureBackTrace
quelle
Ich möchte eine Standardbibliotheksoption (dh plattformübergreifend) zum Generieren von Ausnahme-Backtraces hinzufügen , die mit C ++ 11 verfügbar geworden ist :
Verwenden Sie
std::nested_exception
undstd::throw_with_nested
Dies gibt Ihnen keinen Stapel zum Entspannen, aber meiner Meinung nach das nächstbeste. In StackOverflow wird hier und hier beschrieben , wie Sie eine Rückverfolgung Ihrer Ausnahmen in Ihrem Code erhalten können, ohne dass ein Debugger oder eine umständliche Protokollierung erforderlich ist, indem Sie einfach einen geeigneten Ausnahmebehandler schreiben, der verschachtelte Ausnahmen erneut auslöst.
Da Sie dies mit jeder abgeleiteten Ausnahmeklasse tun können, können Sie einer solchen Rückverfolgung viele Informationen hinzufügen! Sie können sich auch mein MWE auf GitHub ansehen, wo ein Backtrace ungefähr so aussehen würde:
quelle
AFAIK libunwind ist ziemlich portabel und ich habe bisher nichts einfacher zu bedienen gefunden.
quelle
Ich empfehle das Projekt http://stacktrace.sourceforge.net/ . Es unterstützt Windows, Mac OS und auch Linux
quelle
throw stack_runtime_error
. Kann ich zu Recht feststellen, dass diesestd::exception
Bibliothek nur für Ausnahmen funktioniert, die von dieser Klasse abgeleitet sind, und nicht für oder Ausnahmen von Bibliotheken von Drittanbietern?Wenn Sie C ++ verwenden und Boost nicht verwenden möchten / können, können Sie Backtrace mit entwirrten Namen mit dem folgenden Code drucken [Link zur ursprünglichen Site] .
Beachten Sie, dass diese Lösung spezifisch für Linux ist. Es verwendet die libc-Funktionen von GNU backtrace () / backtrace_symbols () (von execinfo.h), um die Backtraces abzurufen, und verwendet dann __cxa_demangle () (von cxxabi.h), um die Namen der Backtrace-Symbole zu entwirren.
HTH!
quelle
Unter Linux mit G ++ schau dir diese Bibliothek an
https://sourceforge.net/projects/libcsdbg
es erledigt die ganze Arbeit für Sie
quelle
Schauen Sie sich unter Windows BugTrap an . Es befindet sich nicht mehr unter dem ursprünglichen Link, ist aber weiterhin auf CodeProject verfügbar.
quelle
Ich habe ein ähnliches Problem und obwohl ich Portabilität mag, brauche ich nur gcc-Unterstützung. In gcc sind execinfo.h und die Backtrace- Aufrufe verfügbar. Um die Funktionsnamen zu entwirren, hat Herr Bingmann einen schönen Code. Um eine Rückverfolgung für eine Ausnahme zu sichern, erstelle ich eine Ausnahme, die die Rückverfolgung im Konstruktor druckt. Wenn ich damit gerechnet habe, dass dies mit einer in einer Bibliothek ausgelösten Ausnahme funktioniert, muss möglicherweise neu erstellt / verknüpft werden, damit die Backtracing-Ausnahme verwendet wird.
Das Kompilieren und Ausführen mit gcc 4.8.4 ergibt eine Rückverfolgung mit gut entwirrten C ++ - Funktionsnamen:
quelle
Da der Stapel bereits beim Betreten des Catch-Blocks abgewickelt wird, bestand die Lösung in meinem Fall darin , bestimmte Ausnahmen nicht zu fangen, die dann zu einem SIGABRT führen. Im Signalhandler für SIGABRT habe ich dann fork () und execl () entweder gdb (in Debug-Builds) oder Google Breakpads Stackwalk (in Release-Builds). Außerdem versuche ich, nur Signalhandler-sichere Funktionen zu verwenden.
GDB:
minidump_stackwalk:
Bearbeiten: Damit es für das Breakpad funktioniert, musste ich auch Folgendes hinzufügen:
Quelle: Wie erhalte ich einen Stack-Trace für C ++ mit gcc mit Zeilennummerninformationen? und Ist es möglich, GDB an einen abgestürzten Prozess anzuhängen (auch bekannt als "Just-in-Time" -Debugging)?
quelle
Poppy kann nicht nur den Stack-Trace erfassen, sondern auch Parameterwerte, lokale Variablen usw. - alles, was zum Absturz führt.
quelle
Der folgende Code stoppt die Ausführung direkt nach dem Auslösen einer Ausnahme. Sie müssen einen windows_exception_handler zusammen mit einem Terminierungshandler festlegen. Ich habe dies in MinGW 32bit getestet.
Überprüfen Sie den folgenden Code für die Funktion windows_exception_handler: http://www.codedisqus.com/0ziVPgVPUk/exception-handling-and-stacktrace-under-windows-mingwgcc.html
quelle
Cpp-Tool ex_diag - einfach, plattformübergreifend, minimal ressourcenschonend, einfach und flexibel bei der Ablaufverfolgung.
quelle