]> git.tdb.fi Git - libs/core.git/blob - source/debug/backtrace.cpp
Add move semantics to Variant
[libs/core.git] / source / debug / backtrace.cpp
1 // Must include something to test for glibc
2 #include <cstdlib>
3 #if !defined(_WIN32) && defined(__GLIBC__)
4 #include <dlfcn.h>
5 #include <execinfo.h>
6 #endif
7 #include "backtrace.h"
8 #include "demangle.h"
9
10 using namespace std;
11
12 namespace Msp {
13 namespace Debug {
14
15 Backtrace Backtrace::create()
16 {
17 #if !defined(_WIN32) && defined(__GLIBC__)
18         void *addresses[50];
19         int count = ::backtrace(addresses, 50);
20
21         Backtrace bt;
22         Dl_info dli;
23         for(int i=0; i<count; ++i)
24         {
25                 StackFrame frame;
26                 frame.address = addresses[i];
27                 if(dladdr(addresses[i], &dli))
28                 {
29                         frame.file = dli.dli_fname;
30                         if(dli.dli_sname)
31                                 frame.symbol = demangle(dli.dli_sname);
32                 }
33                 else
34                         frame.file = "<unknown>";
35                 bt.frames.push_back(frame);
36         }
37
38         return bt;
39 #else
40         return Backtrace();
41 #endif
42 }
43
44 ostream &operator<<(ostream &out, const Backtrace &bt)
45 {
46         for(const Backtrace::StackFrame &f: bt.get_frames())
47                 out << f << '\n';
48
49         return out;
50 }
51
52 ostream &operator<<(ostream &out, const Backtrace::StackFrame &sf)
53 {
54         out << sf.address;
55         if(!sf.symbol.empty())
56                 out << " in " << sf.symbol;
57         out << " from " << sf.file;
58
59         return out;
60 }
61
62 } // namespace Debug
63 } // namespace Msp