From 514de7edc40fe4e0486e1b483f79182473f1dd19 Mon Sep 17 00:00:00 2001 From: Eugene Shalygin Date: Sat, 17 Dec 2016 17:29:43 +0100 Subject: [PATCH 1/2] Follow project coding style. Issue #2192. --- src/app/stacktrace.h | 102 +++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 52 deletions(-) diff --git a/src/app/stacktrace.h b/src/app/stacktrace.h index 48dfa9b3b..f731240ca 100644 --- a/src/app/stacktrace.h +++ b/src/app/stacktrace.h @@ -15,76 +15,74 @@ static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames fprintf(out, "stack trace:\n"); // storage array for stack trace address data - void* addrlist[max_frames+1]; + void *addrlist[max_frames + 1]; // retrieve current stack addresses - int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*)); + int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void *)); if (addrlen == 0) { - fprintf(out, " \n"); - return; + fprintf(out, " \n"); + return; } // resolve addresses into strings containing "filename(function+address)", // this array must be free()-ed - char** symbollist = backtrace_symbols(addrlist, addrlen); + 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); + char *funcname = (char *)malloc(funcnamesize); // iterate over the returned symbol lines. skip the first, it is the // address of this function. - for (int i = 2; i < addrlen; i++) - { - char *begin_name = 0, *begin_offset = 0, *end_offset = 0; + for (int i = 2; 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] - //fprintf(out, "%s TT\n", symbollist[i]); - 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; - } - } + // find parentheses and +address offset surrounding the mangled name: + // ./module(function+0x15c) [0x8048a6d] + // fprintf(out, "%s TT\n", symbollist[i]); + 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; + } + } - if (begin_name && begin_offset && end_offset - && begin_name < begin_offset) - { - *begin_name++ = '\0'; - *begin_offset++ = '\0'; - *end_offset = '\0'; + 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(): + // 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 %s\n", - symbollist[i], funcname, begin_offset, ++end_offset); - } - else { - // demangling failed. Output function name as a C function with - // no arguments. - fprintf(out, " %s : %s()+%s %s\n", - symbollist[i], begin_name, begin_offset, ++end_offset); - } - } - else - { - // couldn't parse the line? print the whole line. - fprintf(out, " %s\n", symbollist[i]); - } + 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 %s\n", + symbollist[i], funcname, begin_offset, ++end_offset); + } + else { + // demangling failed. Output function name as a C function with + // no arguments. + fprintf(out, " %s : %s()+%s %s\n", + symbollist[i], begin_name, begin_offset, ++end_offset); + } + } + else { + // couldn't parse the line? print the whole line. + fprintf(out, " %s\n", symbollist[i]); + } } free(funcname); From 05dbea390b3772e2ff16474fff2c1c0e100d2537 Mon Sep 17 00:00:00 2001 From: Eugene Shalygin Date: Sat, 17 Dec 2016 17:35:40 +0100 Subject: [PATCH 2/2] Print warning to the user if stacktrace contains no function names Count matched function names, and if there are no, point out to the user that the stacktrace is useless. If not all stactrace elements contain function names, suggest user that installing debug packages may improve the stacktrace usefulness. --- src/app/stacktrace.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/app/stacktrace.h b/src/app/stacktrace.h index f731240ca..03639ba8a 100644 --- a/src/app/stacktrace.h +++ b/src/app/stacktrace.h @@ -33,6 +33,7 @@ static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames size_t funcnamesize = 256; char *funcname = (char *)malloc(funcnamesize); + int functionNamesFound = 0; // iterate over the returned symbol lines. skip the first, it is the // address of this function. for (int i = 2; i < addrlen; i++) { @@ -78,6 +79,7 @@ static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames fprintf(out, " %s : %s()+%s %s\n", symbollist[i], begin_name, begin_offset, ++end_offset); } + ++functionNamesFound; } else { // couldn't parse the line? print the whole line. @@ -85,6 +87,14 @@ static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames } } + if (!functionNamesFound) { + fprintf(out, "There were no function names found in the stack trace\n." + "Seems like debug symbols are not installed, and the stack trace is useless.\n"); + } + if (functionNamesFound < addrlen - 2) { + fprintf(out, "Consider installing debug symbols for packages containing files with empty" + " function names (i.e. empty braces \"()\") to make your stack trace more useful\n"); + } free(funcname); free(symbollist); }