34 #include <madness/madness_config.h>
35 #ifdef MADNESS_HAS_LIBUNWIND
36 #define UNW_LOCAL_ONLY
37 #include <libunwind.h>
39 #if __has_include(<execinfo.h>)
40 #define HAVE_BACKTRACE
45 #if __has_include(<cxxabi.h>)
47 #define HAVE_CXA_DEMANGLE
53 #ifdef MADNESS_HAS_LIBUNWIND
57 unw_word_t ip, sp, offp;
61 unw_init_local(&cursor, &uc);
62 while (unw_step(&cursor) > 0) {
63 unw_get_reg(&cursor, UNW_REG_IP, &ip);
64 unw_get_reg(&cursor, UNW_REG_SP, &sp);
66 unw_get_proc_name(&cursor, name, 32768, &offp);
67 std::ostringstream oss;
68 oss << prefix_ <<
"frame " << frame <<
": "
69 <<
"ip = 0x" << (long)ip <<
" sp = 0x" << (
long)sp
70 <<
" symbol = " << __demangle(name);
71 frames_.push_back(oss.str());
75 #elif defined(HAVE_BACKTRACE) // !MADNESS_HAS_LIBUNWIND
76 void *stack_addrs[1024];
77 const int naddrs = backtrace(stack_addrs, 1024);
78 char **frame_symbols = backtrace_symbols(stack_addrs, naddrs);
80 for (
int i = 1; i < naddrs; ++i) {
84 std::string mangled_function_name = frame_symbols[i];
85 #if defined(__APPLE__)
88 std::istringstream iss(std::string(frame_symbols[i]),
89 std::istringstream::in);
90 std::string frame, file, address;
91 iss >> frame >> file >> address >> mangled_function_name;
93 #elif defined(__linux__)
97 const auto last_right_bracket = mangled_function_name.rfind(
']');
98 const auto last_left_bracket =
99 mangled_function_name.rfind(
'[', last_right_bracket);
100 const auto last_right_parens =
101 mangled_function_name.rfind(
')', last_left_bracket);
102 const auto offset = mangled_function_name.rfind(
"+0x", last_right_parens);
103 const auto last_left_parens =
104 mangled_function_name.rfind(
'(', last_right_parens);
105 if (last_left_parens + 1 < mangled_function_name.size()) {
106 mangled_function_name = mangled_function_name.substr(
107 last_left_parens + 1, offset - last_left_parens - 1);
112 std::ostringstream oss;
113 oss << prefix_ <<
"frame " << i <<
": return address = " << stack_addrs[i]
115 <<
" symbol = " << __demangle(mangled_function_name);
116 frames_.push_back(oss.str());
119 #else // !MADNESS_HAS_LIBUNWIND && !HAVE_BACKTRACE
120 #if defined(SIMPLE_STACK)
122 void **topstack = (
void **)0xffffffffL;
123 void **botstack = (
void **)0x70000000L;
126 void **toptext = (
void **)0xffffffffL;
127 void **bottext = (
void **)0x00010000L;
128 #endif // SIMPLE_STACK
130 #if (defined(linux) && defined(i386))
131 topstack = (
void **)0xc0000000;
132 botstack = (
void **)0xb0000000;
134 #if (defined(__OSF1__) && defined(i860))
135 topstack = (
void **)0x80000000;
136 botstack = (
void **)0x70000000;
139 #if defined(SIMPLE_STACK)
144 void **stack = (
void **)⊥
146 void **frame_pointer = (
void **)stack[3];
147 while (frame_pointer >= botstack && frame_pointer < topstack &&
148 frame_pointer[1] >= bottext && frame_pointer[1] < toptext) {
149 std::ostringstream oss;
150 oss << prefix_ <<
"frame: " << (
void *)frame_pointer;
151 oss <<
" retaddr: " << frame_pointer[1];
152 frames_.push_back(oss.str());
154 frame_pointer = (
void **)*frame_pointer;
156 #endif // SIMPLE_STACK
157 #endif // HAVE_BACKTRACE
161 : frames_(other.frames_), prefix_(other.prefix_) {}
164 std::ostringstream oss;
165 std::copy(frames_.begin() + nframes_to_skip, frames_.end(),
166 std::ostream_iterator<std::string>(oss,
"\n"));
170 std::string Backtrace::__demangle(
const std::string &symbol) {
172 #ifdef HAVE_CXA_DEMANGLE
175 char *dsymbol_char = abi::__cxa_demangle(symbol.c_str(), 0, 0, &status);
177 dsymbol = dsymbol_char;