void print_backtrace(size_t max) { VMException::Backtrace s = get_trace(2, max); demangle(s); for(size_t i = 0; i < s.size(); i++) { std::cout << s[i] << std::endl; } }
static void demangle(VMException::Backtrace& s) { for (size_t i = 0; i < s.size(); i++) { squeeze_space(s[i]); const char* str = s[i].c_str(); const char* pos = strstr(str, " _Z"); /* Found a mangle. */ if(pos) { size_t sz = 1024; char *cpp_name = 0; char* name = strdup(pos + 1); char* end = strstr(name, " + "); *end = 0; int status; cpp_name = abi::__cxa_demangle(name, cpp_name, &sz, &status); if(!status) { std::string full_cpp = std::string(str, pos - str) + " " + cpp_name + " " + (++end); s[i] = full_cpp; } if(cpp_name) free(cpp_name); free(name); } } }
static void demangle(VMException::Backtrace& s) { for (size_t i = 0; i < s.size(); i++) { squeeze_space(s[i]); const char* str = s[i].c_str(); const char* pos = strstr(str, " _Z"); /* Found a mangle. */ if(pos) { size_t sz = 0; char *cpp_name = 0; char* name = strdup(pos + 1); char* end = strstr(name, " + "); *end = 0; int status; cpp_name = abi::__cxa_demangle(name, cpp_name, &sz, &status); // It's possible for __cxa_demangle to return 0x0, which probably // shouldn't happen with status == 0, but it was observed in OS X // Mavericks Preview 2 so be paranoid. if(cpp_name) { if(!status) { std::string full_cpp = std::string(str, pos - str) + " " + cpp_name + " " + (++end); s[i] = full_cpp; } free(cpp_name); } free(name); } } }
static VMException::Backtrace get_trace(size_t skip, size_t max_depth=100) { #ifdef USE_EXECINFO size_t stack_depth; char **stack_strings; void **stack_addrs = (void **) calloc(max_depth, sizeof(void*)); stack_depth = backtrace(stack_addrs, max_depth); stack_strings = backtrace_symbols(stack_addrs, stack_depth); VMException::Backtrace s; for (size_t i = skip; i < stack_depth; i++) { s.push_back(std::string(stack_strings[i])); } free(stack_strings); // malloc()ed by backtrace_symbols free(stack_addrs); #else VMException::Backtrace s; s.push_back(std::string("C++ backtrace not available")); #endif return s; }