From c44350269a60c941203431170df0262f421ff52a Mon Sep 17 00:00:00 2001 From: Patrick Wuttke Date: Sun, 26 Nov 2023 11:49:23 +0100 Subject: [PATCH] Added code to capture stacktrace whenever an exception is thrown. --- source/mijin/debug/stacktrace.cpp | 42 ++++++++++++++++++++++++++++++- source/mijin/debug/stacktrace.hpp | 1 + 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/source/mijin/debug/stacktrace.cpp b/source/mijin/debug/stacktrace.cpp index 3936caf..dfca406 100644 --- a/source/mijin/debug/stacktrace.cpp +++ b/source/mijin/debug/stacktrace.cpp @@ -1,10 +1,10 @@ #include "./stacktrace.hpp" -#include #include #include #include +#include "../detect.hpp" namespace mijin { @@ -32,6 +32,8 @@ struct BacktraceData // internal variables // +thread_local Optional gCurrentExceptionStackTrace; + // // internal functions // @@ -85,4 +87,42 @@ Result captureStacktrace(unsigned skipFrames) noexcept return Stacktrace(std::move(btData.stackframes)); } +const Optional& getExceptionStacktrace() noexcept +{ + return gCurrentExceptionStackTrace; +} } // namespace mijin + +#if MIJIN_STDLIB == MIJIN_STDLIB_GLIBC +#include + +namespace +{ +using cxa_throw_type = void (*)(void*, std::type_info*, void(*)(void*)); +using cxa_rethrow_type = void (*)(); + +cxa_throw_type orig_cxa_throw = nullptr; // Address of the original __cxa_throw +// cxa_rethrow_type orig_cxa_rethrow = nullptr; // Address of the original __cxa_rethrow + +extern "C" void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*)) +{ + if (!orig_cxa_throw) { + orig_cxa_throw = reinterpret_cast(dlsym(RTLD_NEXT, "__cxa_throw")); + } + if (mijin::Result stacktrace = mijin::captureStacktrace(); stacktrace.isSuccess()) + { + mijin::gCurrentExceptionStackTrace = std::move(*stacktrace); + } + else + { + mijin::gCurrentExceptionStackTrace.reset(); + } + if (orig_cxa_throw) { + orig_cxa_throw(thrown_exception, tinfo, dest); + } + else { + std::abort(); + } +} +} +#endif diff --git a/source/mijin/debug/stacktrace.hpp b/source/mijin/debug/stacktrace.hpp index d039337..569734f 100644 --- a/source/mijin/debug/stacktrace.hpp +++ b/source/mijin/debug/stacktrace.hpp @@ -58,6 +58,7 @@ public: // [[nodiscard]] Result captureStacktrace(unsigned skipFrames = 0) noexcept; +[[nodiscard]] const Optional& getExceptionStacktrace() noexcept; template TStream& operator<<(TStream& stream, const Stackframe& stackframe)