31 const char* fmt, ...) {
38 p += vsnprintf(buffer + p,
sizeof(buffer) - p - 1, fmt, args);
43 void** addrlist =
reinterpret_cast<void**
>(
44 alloca(
sizeof(
void*) * max_frames));
47 int addrlen = backtrace(addrlist, max_frames);
49 for (
int i = 1; i < addrlen; ++i) {
50 if (addrlist[i] ==
nullptr)
53 p += snprintf(buffer + p,
sizeof(buffer) - p - 1,
" %p", addrlist[i]);
57 fprintf(out,
"%s\n", buffer);
61 fprintf(out,
"(backtrace not supported on this platform)\n");
74 fprintf(out,
"backtrace:\n");
79 void** addrlist =
reinterpret_cast<void**
>(
80 alloca(
sizeof(
void*) * max_frames));
83 int addrlen = backtrace(addrlist, max_frames);
86 fprintf(out,
" <empty, possibly corrupt>\n");
92 char** symbollist = backtrace_symbols(addrlist, addrlen);
95 size_t funcnamesize = 256;
96 char* funcname =
reinterpret_cast<char*
>(alloca(funcnamesize));
100 for (
int i = 1; i < addrlen; i++)
102 char* begin_name = 0, * begin_offset = 0, * end_offset = 0;
106 for (
char* p = symbollist[i]; *p; ++p)
112 else if (*p ==
')' && begin_offset) {
118 if (begin_name && begin_offset && end_offset
119 && begin_name < begin_offset)
121 *begin_name++ =
'\0';
122 *begin_offset++ =
'\0';
130 char* ret = abi::__cxa_demangle(begin_name,
131 funcname, &funcnamesize, &status);
134 fprintf(out,
" %s : %s+%s\n",
135 symbollist[i], funcname, begin_offset);
140 fprintf(out,
" %s : %s()+%s\n",
141 symbollist[i], begin_name, begin_offset);
147 fprintf(out,
" %s\n", symbollist[i]);
155 fprintf(out,
" (not supported on this platform)\n");
163 static void segv_backtrace_handler(
int sig) {
169 size = backtrace(addr, 16);
171 fprintf(stderr,
"Caught SIGSEGV (segmentation fault). Backtrace:\n");
172 backtrace_symbols_fd(addr + 1, size - 1, STDERR_FILENO);
180 signal(SIGSEGV, segv_backtrace_handler);
182 printf(
"enable_segv_backtrace(): not supported on this platform.\n");
void print_cxx_backtrace(FILE *out, unsigned int max_frames)
Print a demangled stack backtrace of the caller function to FILE* out.
void print_raw_backtrace(FILE *out, unsigned int max_frames, const char *fmt,...)
Print a plain hex stack backtrace of the called function to FILE* out, prefixed with the given printf...
void enable_segv_backtrace()
Install SIGSEGV signal handler and output backtrace on segmentation fault.