Works only with GCC. Needs command line tool 'addr2line' to be callable from within MAIA.
77 {
78
79 const int maxNoTraces = 128;
80 void* trace[maxNoTraces];
81 int noTraces = ::backtrace(trace, maxNoTraces);
82
83
84 char** messages = backtrace_symbols(trace, noTraces);
85
86
87 std::stringstream s;
88 const MInt maxLineLength = 1024;
89 MChar line[maxLineLength];
90
91
92 const MInt maxCmdSize = 1024;
94 const MInt noFrames = noTraces - noFramesOmitted;
95 const MInt width = noFrames ? floor(log10(noFrames)) + 1 : 1;
96 s << "\nBacktrace (line numbers are usually too large, typically by 1-3 "
97 "lines):\n";
98 for(
MInt i = noFramesOmitted; i < noTraces; i++) {
99
101 mangled = mangled.substr(mangled.find("(") + 1);
102 mangled = mangled.substr(0, mangled.find("+"));
103 int status;
104 char* demangledChar = abi::__cxa_demangle(mangled.c_str(), 0, 0, &status);
105
106
107 const MString demangled = (status == 0) ? demangledChar : messages[i];
109
110
111 char cmd[maxCmdSize];
112 std::sprintf(cmd, "addr2line %p -s -e %s", trace[i], fileName.c_str());
114 FILE* pipe = popen(cmd, "r");
115 if(!pipe) {
116 fileline = "n/a";
117 } else {
118 char buffer[128];
119 while(!feof(pipe)) {
120 if(fgets(buffer, 128, pipe) != nullptr) {
121 fileline += buffer;
122 }
123 }
124 }
125 pclose(pipe);
126
127
128
129 fileline = fileline.substr(0, fileline.length() - 1);
130 fileline = fileline.substr(0, fileline.find(" "));
131
132
133 std::sprintf(line, "#%-*d 0x%016lx in %s at %s\n", width, frameId++, reinterpret_cast<uintptr_t>(trace[i]),
134 demangled.c_str(), fileline.c_str());
135 line[maxLineLength - 1] = '\0';
136 s << line;
137 }
138 std::cout << s.str() << std::endl;
139}
std::basic_string< char > MString