X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fdebug%2Fexceptiontrace.cpp;fp=source%2Fdebug%2Fexceptiontrace.cpp;h=30df4b6f353718c687774878c04e0f4252b4e9b6;hp=0000000000000000000000000000000000000000;hb=c7b4b9d6e07b3e32e5b03f41f0640a8273eed848;hpb=d2795b92b02253a36cb7406fbaeabdef6d7caa19 diff --git a/source/debug/exceptiontrace.cpp b/source/debug/exceptiontrace.cpp new file mode 100644 index 0000000..30df4b6 --- /dev/null +++ b/source/debug/exceptiontrace.cpp @@ -0,0 +1,71 @@ +#include +#if !defined(_WIN32) && defined(__GLIBC__) +#include +#endif +#include "backtrace.h" +#include "exceptiontrace.h" + +using namespace std; + +namespace { + +#if defined(WITH_EXCEPTION_TRACE) && !defined(_WIN32) && defined(__GLIBC__) +typedef void CxaThrowType(void *, type_info *, void (*)(void *)); +CxaThrowType *orig_cxa_throw; + +struct HookThrow +{ + HookThrow(); +}; + +HookThrow::HookThrow() +{ + void *handle = dlopen(0, RTLD_LAZY); + orig_cxa_throw = reinterpret_cast(dlvsym(handle, "__cxa_throw", "CXXABI_1.3")); + dlclose(handle); +} + +HookThrow hook; +#endif + +bool trace_enabled = false; + +Msp::Debug::Backtrace &get_thread_backtrace() +{ +#if __cplusplus>=201103L + static thread_local Msp::Debug::Backtrace backtrace; +#elif defined(__GNUC__) + static __thread Msp::Debug::Backtrace backtrace; +#else + static Msp::Debug::Backtrace backtrace; +#endif + return backtrace; +} + +} + +namespace Msp { +namespace Debug { + +void enable_exception_trace(bool e) +{ + trace_enabled = e; +} + +const Backtrace &get_exception_trace() +{ + return get_thread_backtrace(); +} + +} // namespace Debug +} // namespace Msp + +#if defined(WITH_EXCEPTION_TRACE) && !defined(_WIN32) && defined(__GLIBC__) +extern "C" void __cxa_throw(void *exc, std::type_info *type, void (*dest) (void *)) +{ + if(trace_enabled) + get_thread_backtrace() = Msp::Debug::Backtrace::create(); + orig_cxa_throw(exc, type, dest); + std::terminate(); +} +#endif