Line data Source code
1 : #include "dtcInterfaceLib/otsStyleCoutMacros.h"
2 :
3 : //==============================================================================
4 : // stackTrace
5 : // static function
6 : // https://gist.github.com/fmela/591333/c64f4eb86037bb237862a8283df70cdfc25f01d3
7 : #include <cxxabi.h> //for abi::__cxa_demangle
8 : #include <execinfo.h> //for back trace of stack
9 :
10 : // #include "TUnixSystem.h"
11 0 : std::string otsStyleStackTrace()
12 : {
13 0 : __SS__ << "ots::stackTrace:\n";
14 :
15 : void* array[10];
16 : size_t size;
17 :
18 : // get void*'s for all entries on the stack
19 0 : size = backtrace(array, 10);
20 : // backtrace_symbols_fd(array, size, STDERR_FILENO);
21 :
22 : // https://stackoverflow.com/questions/77005/how-to-automatically-generate-a-stacktrace-when-my-program-crashes
23 0 : char** messages = backtrace_symbols(array, size);
24 :
25 : // skip first stack frame (points here)
26 : // char syscom[256];
27 0 : for (unsigned int i = 1; i < size && messages != NULL; ++i)
28 : {
29 : // mangled name needs to be converted to get nice name and line number
30 : // line number not working... FIXME
31 :
32 : // sprintf(syscom,"addr2line %p -e %s",
33 : // array[i],
34 : // messages[i]); //last parameter is the name of this app
35 : // ss << StringMacros::exec(syscom) << __E__;
36 : // system(syscom);
37 :
38 : // continue;
39 :
40 0 : char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;
41 :
42 : // find parentheses and +address offset surrounding mangled name
43 0 : for (char* p = messages[i]; *p; ++p)
44 : {
45 0 : if (*p == '(')
46 : {
47 0 : mangled_name = p;
48 : }
49 0 : else if (*p == '+')
50 : {
51 0 : offset_begin = p;
52 : }
53 0 : else if (*p == ')')
54 : {
55 0 : offset_end = p;
56 0 : break;
57 : }
58 : }
59 :
60 : // if the line could be processed, attempt to demangle the symbol
61 0 : if (mangled_name && offset_begin && offset_end && mangled_name < offset_begin)
62 : {
63 0 : *mangled_name++ = '\0';
64 0 : *offset_begin++ = '\0';
65 0 : *offset_end++ = '\0';
66 :
67 : int status;
68 0 : char* real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
69 :
70 : // if demangling is successful, output the demangled function name
71 0 : if (status == 0)
72 : {
73 0 : ss << "[" << i << "] " << messages[i] << " : " << real_name << "+" << offset_begin << offset_end << std::endl;
74 : }
75 : // otherwise, output the mangled function name
76 : else
77 : {
78 0 : ss << "[" << i << "] " << messages[i] << " : " << mangled_name << "+" << offset_begin << offset_end << std::endl;
79 : }
80 0 : free(real_name);
81 0 : }
82 : // otherwise, print the whole line
83 : else
84 : {
85 0 : ss << "[" << i << "] " << messages[i] << std::endl;
86 : }
87 : }
88 0 : ss << std::endl;
89 :
90 0 : free(messages);
91 :
92 : // call ROOT's stack trace to get line numbers of ALL threads
93 : // gSystem->StackTrace();
94 :
95 0 : return ss.str();
96 0 : } // end stackTrace
|