diff --git a/libretroshare/src/util/stacktrace.h b/libretroshare/src/util/stacktrace.h index 49a5e5c0a..b535e34f9 100644 --- a/libretroshare/src/util/stacktrace.h +++ b/libretroshare/src/util/stacktrace.h @@ -1,10 +1,32 @@ -// stacktrace.h (c) 2008, Timo Bingmann from http://idlebox.net/ -// published under the WTFPL v2.0 +/* + * stacktrace.h + * + * Copyright (C) 2016 Gioacchino Mazzurco + * Copyright (C) 2008 Timo Bingmann http://idlebox.net/ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + */ #ifndef _STACKTRACE_H_ #define _STACKTRACE_H_ #include + +#ifndef WINDOWS_SYS + #include #include #include @@ -12,82 +34,89 @@ /** Print a demangled stack backtrace of the caller function to FILE* out. */ static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames = 63) { - fprintf(out, "stack trace:\n"); + fprintf(out, "stack trace:\n"); - // storage array for stack trace address data - void* addrlist[max_frames+1]; + // storage array for stack trace address data + void* addrlist[max_frames+1]; - // retrieve current stack addresses - int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*)); + // retrieve current stack addresses + int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*)); - if (addrlen == 0) { - fprintf(out, " \n"); - return; - } - - // resolve addresses into strings containing "filename(function+address)", - // this array must be free()-ed - char** symbollist = backtrace_symbols(addrlist, addrlen); - - // allocate string which will be filled with the demangled function name - size_t funcnamesize = 256; - char* funcname = (char*)malloc(funcnamesize); - - // iterate over the returned symbol lines. skip the first, it is the - // address of this function. - for (int i = 1; i < addrlen; i++) - { - char *begin_name = 0, *begin_offset = 0, *end_offset = 0; - - // find parentheses and +address offset surrounding the mangled name: - // ./module(function+0x15c) [0x8048a6d] - for (char *p = symbollist[i]; *p; ++p) + if (addrlen == 0) { - if (*p == '(') - begin_name = p; - else if (*p == '+') - begin_offset = p; - else if (*p == ')' && begin_offset) { - end_offset = p; - break; - } + fprintf(out, " \n"); + return; } - if (begin_name && begin_offset && end_offset - && begin_name < begin_offset) + // resolve addresses into strings containing "filename(function+address)", + // this array must be free()-ed + char** symbollist = backtrace_symbols(addrlist, addrlen); + + // allocate string which will be filled with the demangled function name + size_t funcnamesize = 256; + char* funcname = (char*)malloc(funcnamesize); + + // iterate over the returned symbol lines. skip the first, it is the + // address of this function. + for (int i = 1; i < addrlen; i++) { - *begin_name++ = '\0'; - *begin_offset++ = '\0'; - *end_offset = '\0'; + char *begin_name = 0, *begin_offset = 0, *end_offset = 0; - // mangled name is now in [begin_name, begin_offset) and caller - // offset in [begin_offset, end_offset). now apply - // __cxa_demangle(): + // find parentheses and +address offset surrounding the mangled name: + // ./module(function+0x15c) [0x8048a6d] + for (char *p = symbollist[i]; *p; ++p) + { + if (*p == '(') begin_name = p; + else if (*p == '+') begin_offset = p; + else if (*p == ')' && begin_offset) + { + end_offset = p; + break; + } + } - int status; - char* ret = abi::__cxa_demangle(begin_name, - funcname, &funcnamesize, &status); - if (status == 0) { - funcname = ret; // use possibly realloc()-ed string - fprintf(out, " %s : %s+%s\n", - symbollist[i], funcname, begin_offset); - } - else { - // demangling failed. Output function name as a C function with - // no arguments. - fprintf(out, " %s : %s()+%s\n", - symbollist[i], begin_name, begin_offset); - } + if (begin_name && begin_offset && end_offset && begin_name < begin_offset) + { + *begin_name++ = '\0'; + *begin_offset++ = '\0'; + *end_offset = '\0'; + + // mangled name is now in [begin_name, begin_offset) and caller + // offset in [begin_offset, end_offset). now apply + // __cxa_demangle(): + + int status; + char* ret = abi::__cxa_demangle(begin_name, funcname, &funcnamesize, &status); + if (status == 0) + { + funcname = ret; // use possibly realloc()-ed string + fprintf(out, " %s : %s+%s\n", symbollist[i], funcname, begin_offset); + } + else + { + // demangling failed. Output function name as a C function with + // no arguments. + fprintf(out, " %s : %s()+%s\n", symbollist[i], begin_name, begin_offset); + } + } + else + { + // couldn't parse the line? print the whole line. + fprintf(out, " %s\n", symbollist[i]); + } } - else - { - // couldn't parse the line? print the whole line. - fprintf(out, " %s\n", symbollist[i]); - } - } - free(funcname); - free(symbollist); + free(funcname); + free(symbollist); } +#else // WINDOWS_SYS +static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames = 63) +{ + (void) max_frames; + + fprintf(out, "TODO: 2016/01/01 print_stacktrace not implemented yet for WINDOWS_SYS\n"); +} +#endif // WINDOWS_SYS + #endif // _STACKTRACE_H_