]> git.tdb.fi Git - libs/core.git/blob - source/debug/exceptiontrace.cpp
8ffc9c81b988667cffa12d770c1a6e97e5244ba6
[libs/core.git] / source / debug / exceptiontrace.cpp
1 #include <string>
2 #if !defined(_WIN32) && defined(__GLIBC__)
3 #include <dlfcn.h>
4 #endif
5 #include "backtrace.h"
6 #include "exceptiontrace.h"
7
8 using namespace std;
9
10 namespace {
11
12 #if defined(WITH_EXCEPTION_TRACE) && !defined(_WIN32) && defined(__GLIBC__)
13 typedef void CxaThrowType(void *, type_info *, void (*)(void *));
14 CxaThrowType *orig_cxa_throw;
15
16 struct HookThrow
17 {
18         HookThrow();
19 };
20
21 HookThrow::HookThrow()
22 {
23         void *handle = dlopen(0, RTLD_LAZY);
24         orig_cxa_throw = reinterpret_cast<CxaThrowType *>(dlvsym(handle, "__cxa_throw", "CXXABI_1.3"));
25         dlclose(handle);
26 }
27
28 HookThrow hook;
29 #endif
30
31 bool trace_enabled = false;
32
33 Msp::Debug::Backtrace &get_thread_backtrace()
34 {
35         static thread_local Msp::Debug::Backtrace backtrace;
36         return backtrace;
37 }
38
39 }
40
41 namespace Msp {
42 namespace Debug {
43
44 void enable_exception_trace(bool e)
45 {
46         trace_enabled = e;
47 }
48
49 const Backtrace &get_exception_trace()
50 {
51         return get_thread_backtrace();
52 }
53
54 } // namespace Debug
55 } // namespace Msp
56
57 #if defined(WITH_EXCEPTION_TRACE) && !defined(_WIN32) && defined(__GLIBC__)
58 extern "C" void __cxa_throw(void *exc, type_info *type, void (*dest) (void *))
59 {
60         if(trace_enabled)
61                 get_thread_backtrace() = Msp::Debug::Backtrace::create();
62         orig_cxa_throw(exc, type, dest);
63         terminate();
64 }
65 #endif