From 00fae12d8611ff9af7210355d95aceca741f1a14 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Mon, 29 Oct 2018 14:45:46 +0100 Subject: [PATCH] simpleStacktrace compiles in debug mode only by conditioned compilation --- alib2common/src/debug/simpleStacktrace.cpp | 200 +++++++++++---------- 1 file changed, 103 insertions(+), 97 deletions(-) diff --git a/alib2common/src/debug/simpleStacktrace.cpp b/alib2common/src/debug/simpleStacktrace.cpp index 679eb39ecb..d0840a00c2 100644 --- a/alib2common/src/debug/simpleStacktrace.cpp +++ b/alib2common/src/debug/simpleStacktrace.cpp @@ -25,114 +25,120 @@ int callback(struct dl_phdr_info *info, size_t, void * data) { return 0; } -std::string simpleStacktrace(unsigned int max_frames) { - char linkname[512]; /* /proc/exe */ - char buf[512]; - pid_t pid; - int ret; - - /* Get our PID and build the name of the link in /proc */ - pid = getpid(); - snprintf(linkname, sizeof(linkname), "/proc/%i/exe", pid); - - /* Now read the symbolic link */ - ret = readlink(linkname, buf, 512); - if ( ret < 0 ) { - strcpy(buf, "[UNKNOWN]"); - } else { - buf[ret] = 0; - } - - std::stringstream ss; - ss << "stack trace for process " << buf << " (PID:" << pid << "):"<< std::endl; - - // storage array for stack trace address data - void** addrlist = (void**) malloc( (max_frames + 1 ) * sizeof(void*) ); - - // retrieve current stack addresses - int addrlen = backtrace(addrlist, max_frames); - - if (addrlen == 0) { - ss << " <empty, possibly corrupt>" << std::endl; - free(addrlist); - return std::move(ss).str(); - } - - // 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); - - ext::map<std::string, long> dlToBaseAddress; - - dl_iterate_phdr(callback, &dlToBaseAddress); - - // 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, *addr_offset = 0; - - // 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; - addr_offset = p + 3; - break; - } +#ifdef DEBUG + std::string simpleStacktrace(unsigned int max_frames) { + char linkname[512]; /* /proc/exe */ + char buf[512]; + pid_t pid; + int ret; + + /* Get our PID and build the name of the link in /proc */ + pid = getpid(); + snprintf(linkname, sizeof(linkname), "/proc/%i/exe", pid); + + /* Now read the symbolic link */ + ret = readlink(linkname, buf, 512); + if ( ret < 0 ) { + strcpy(buf, "[UNKNOWN]"); + } else { + buf[ret] = 0; } - if (begin_name && begin_offset && end_offset && begin_name < begin_offset) { - *begin_name++ = '\0'; - *begin_offset++ = '\0'; - *end_offset = '\0'; - addr_offset[strlen(addr_offset) - 1] = '\0'; - - unsigned long long x; - std::stringstream ss1; - ss1 << std::hex << addr_offset; - ss1 >> x; + std::stringstream ss; + ss << "stack trace for process " << buf << " (PID:" << pid << "):"<< std::endl; - unsigned long long y = x - dlToBaseAddress[symbollist[i]]; + // storage array for stack trace address data + void** addrlist = (void**) malloc( (max_frames + 1 ) * sizeof(void*) ); - std::stringstream ss2; - ss2 << std::hex << y; - std::string addr_offset_by_dl; - ss2 >> addr_offset_by_dl; + // retrieve current stack addresses + int addrlen = backtrace(addrlist, max_frames); -// ss << addrToLine(symbollist[i], NULL, NULL, addr_offset_by_dl.c_str()) << " [" << addr_offset << "]" << endl; + if (addrlen == 0) { + ss << " <empty, possibly corrupt>" << std::endl; + free(addrlist); + return std::move(ss).str(); + } - // mangled name is now in [begin_name, begin_offset) and caller - // offset in [begin_offset, end_offset). now apply - // __cxa_demangle(): + // 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); + + ext::map<std::string, long> dlToBaseAddress; + + dl_iterate_phdr(callback, &dlToBaseAddress); + + // 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, *addr_offset = 0; + + // 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; + addr_offset = p + 3; + break; + } + } - int status; - char* demangled = abi::__cxa_demangle(begin_name, funcname, &funcnamesize, &status); - if (status == 0) { - funcname = demangled; // use possibly realloc()-ed string - ss << " " << symbollist[i] << " : " << funcname << "+" << begin_offset << " " << begin_name << " [0x" << addr_offset_by_dl.c_str() << "; @ " << addr_offset << "]" << std::endl; + if (begin_name && begin_offset && end_offset && begin_name < begin_offset) { + *begin_name++ = '\0'; + *begin_offset++ = '\0'; + *end_offset = '\0'; + addr_offset[strlen(addr_offset) - 1] = '\0'; + + unsigned long long x; + std::stringstream ss1; + ss1 << std::hex << addr_offset; + ss1 >> x; + + unsigned long long y = x - dlToBaseAddress[symbollist[i]]; + + std::stringstream ss2; + ss2 << std::hex << y; + std::string addr_offset_by_dl; + ss2 >> addr_offset_by_dl; + + // ss << addrToLine(symbollist[i], NULL, NULL, addr_offset_by_dl.c_str()) << " [" << addr_offset << "]" << endl; + + // mangled name is now in [begin_name, begin_offset) and caller + // offset in [begin_offset, end_offset). now apply + // __cxa_demangle(): + + int status; + char* demangled = abi::__cxa_demangle(begin_name, funcname, &funcnamesize, &status); + if (status == 0) { + funcname = demangled; // use possibly realloc()-ed string + ss << " " << symbollist[i] << " : " << funcname << "+" << begin_offset << " " << begin_name << " [0x" << addr_offset_by_dl.c_str() << "; @ " << addr_offset << "]" << std::endl; + } else { + // demangling failed. Output function name as a C function with + // no arguments. + ss << " " << symbollist[i] << " : " << begin_name << "()+" << begin_offset << " " << " [0x" << addr_offset_by_dl.c_str() << "; @ " << addr_offset << "]" << std::endl; + } } else { - // demangling failed. Output function name as a C function with - // no arguments. - ss << " " << symbollist[i] << " : " << begin_name << "()+" << begin_offset << " " << " [0x" << addr_offset_by_dl.c_str() << "; @ " << addr_offset << "]" << std::endl; + // couldn't parse the line? print the whole line. + ss << " " << symbollist[i] << std::endl; } - } else { - // couldn't parse the line? print the whole line. - ss << " " << symbollist[i] << std::endl; } + free(funcname); + free(symbollist); + free(addrlist); + return std::move(ss).str(); } - free(funcname); - free(symbollist); - free(addrlist); - return std::move(ss).str(); -} +#else + std::string simpleStacktrace ( unsigned int ) { + return ""; + } +#endif } /* namespace ext */ -- GitLab